Make capbilities be connection specific versus for the whole endpoint. Bug #4334

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@5742 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.2-netsec
Jeremy McNamara 21 years ago
parent 9c83ec2f25
commit ec9ce8db9d

@ -83,6 +83,7 @@ answer_call_cb on_answer_call;
progress_cb on_progress; progress_cb on_progress;
rfc2833_cb on_set_rfc2833_payload; rfc2833_cb on_set_rfc2833_payload;
hangup_cb on_hangup; hangup_cb on_hangup;
setcapabilities_cb on_setcapabilities;
/* global debug flag */ /* global debug flag */
int h323debug; int h323debug;
@ -1014,9 +1015,7 @@ static struct ast_channel *oh323_request(const char *type, int format, void *dat
else else
memcpy(&pvt->options, &global_options, sizeof(pvt->options)); memcpy(&pvt->options, &global_options, sizeof(pvt->options));
/* pass on our capabilites to the H.323 stack */
ast_mutex_lock(&caplock); ast_mutex_lock(&caplock);
h323_set_capability(pvt->capability, pvt->dtmfmode);
/* Generate unique channel identifier */ /* Generate unique channel identifier */
snprintf(tmp1, sizeof(tmp1)-1, "%s-%u", host, ++unique); snprintf(tmp1, sizeof(tmp1)-1, "%s-%u", host, ++unique);
tmp1[sizeof(tmp1)-1] = '\0'; tmp1[sizeof(tmp1)-1] = '\0';
@ -1511,6 +1510,26 @@ void set_dtmf_payload(unsigned call_reference, const char *token, int payload)
ast_log(LOG_DEBUG, "DTMF payload on %s set to %d\n", token, payload); ast_log(LOG_DEBUG, "DTMF payload on %s set to %d\n", token, payload);
} }
static void set_local_capabilities(unsigned call_reference, const char *token)
{
struct oh323_pvt *pvt;
int capability, dtmfmode;
if (h323debug)
ast_log(LOG_DEBUG, "Setting capabilities for connection %s\n", token);
pvt = find_call_locked(call_reference, token);
if (!pvt)
return;
capability = pvt->capability;
dtmfmode = pvt->dtmfmode;
ast_mutex_unlock(&pvt->lock);
h323_set_capabilities(token, capability, dtmfmode);
if (h323debug)
ast_log(LOG_DEBUG, "Capabilities for connection %s is set\n", token);
}
static void *do_monitor(void *data) static void *do_monitor(void *data)
{ {
int res; int res;
@ -2160,14 +2179,6 @@ int reload_config(void)
alias = alias->next; alias = alias->next;
} }
/* Add our capabilities */
ast_mutex_lock(&caplock);
if (h323_set_capability(capability, dtmfmode)) {
ast_log(LOG_ERROR, "Capabilities failure, this is bad.\n");
ast_mutex_unlock(&caplock);
return -1;
}
ast_mutex_unlock(&caplock);
return 0; return 0;
} }
@ -2383,7 +2394,8 @@ int load_module()
answer_call, answer_call,
progress, progress,
set_dtmf_payload, set_dtmf_payload,
hangup_connection); hangup_connection,
set_local_capabilities);
/* start the h.323 listener */ /* start the h.323 listener */
if (h323_start_listener(h323_signalling_port, bindaddr)) { if (h323_start_listener(h323_signalling_port, bindaddr)) {
ast_log(LOG_ERROR, "Unable to create H323 listener.\n"); ast_log(LOG_ERROR, "Unable to create H323 listener.\n");

@ -282,7 +282,15 @@ H323Codec * AST_G729ACapability::CreateCodec(H323Codec::Direction direction) con
} }
/** MyH323EndPoint /** MyH323EndPoint
* The fullAddress parameter is used directly in the MakeCall method so */
MyH323EndPoint::MyH323EndPoint()
: H323EndPoint()
{
// Capabilities will be negotiated on per-connection basis
capabilities.RemoveAll();
}
/** The fullAddress parameter is used directly in the MakeCall method so
* the General form for the fullAddress argument is : * the General form for the fullAddress argument is :
* [alias@][transport$]host[:port] * [alias@][transport$]host[:port]
* default values: alias = the same value as host. * default values: alias = the same value as host.
@ -359,11 +367,6 @@ void MyH323EndPoint::SetGateway(void)
terminalType = e_GatewayOnly; terminalType = e_GatewayOnly;
} }
H323Capabilities MyH323EndPoint::GetCapabilities(void)
{
return capabilities;
}
BOOL MyH323EndPoint::ClearCall(const PString & token, H323Connection::CallEndReason reason) BOOL MyH323EndPoint::ClearCall(const PString & token, H323Connection::CallEndReason reason)
{ {
if (h323debug) { if (h323debug) {
@ -915,6 +918,12 @@ void MyH323Connection::OnSendCapabilitySet(H245_TerminalCapabilitySet & pdu)
} }
} }
void MyH323Connection::OnSetLocalCapabilities()
{
if (on_setcapabilities)
on_setcapabilities(GetCallReference(), (const char *)callToken);
}
BOOL MyH323Connection::OnReceivedCapabilitySet(const H323Capabilities & remoteCaps, BOOL MyH323Connection::OnReceivedCapabilitySet(const H323Capabilities & remoteCaps,
const H245_MultiplexCapability * muxCap, const H245_MultiplexCapability * muxCap,
H245_TerminalCapabilitySetReject & reject) H245_TerminalCapabilitySetReject & reject)
@ -963,6 +972,73 @@ BOOL MyH323Connection::OnStartLogicalChannel(H323Channel & channel)
return connectionState != ShuttingDownConnection; return connectionState != ShuttingDownConnection;
} }
void MyH323Connection::SetCapabilities(int cap, int dtmfMode)
{
int g711Frames = 20;
// int gsmFrames = 4;
PINDEX lastcap = -1; /* last common capability index */
#if 0
if (cap & AST_FORMAT_SPEEX) {
/* Not real sure if Asterisk acutally supports all
of the various different bit rates so add them
all and figure it out later*/
localCapabilities.SetCapability(0, 0, new SpeexNarrow2AudioCapability());
localCapabilities.SetCapability(0, 0, new SpeexNarrow3AudioCapability());
localCapabilities.SetCapability(0, 0, new SpeexNarrow4AudioCapability());
localCapabilities.SetCapability(0, 0, new SpeexNarrow5AudioCapability());
localCapabilities.SetCapability(0, 0, new SpeexNarrow6AudioCapability());
}
#endif
if (cap & AST_FORMAT_G729A) {
AST_G729ACapability *g729aCap;
AST_G729Capability *g729Cap;
lastcap = localCapabilities.SetCapability(0, 0, g729aCap = new AST_G729ACapability);
lastcap = localCapabilities.SetCapability(0, 0, g729Cap = new AST_G729Capability);
}
if (cap & AST_FORMAT_G723_1) {
H323_G7231Capability *g7231Cap;
lastcap = localCapabilities.SetCapability(0, 0, g7231Cap = new H323_G7231Capability);
}
#if 0
if (cap & AST_FORMAT_GSM) {
H323_GSM0610Capability *gsmCap;
lastcap = localCapabilities.SetCapability(0, 0, gsmCap = new H323_GSM0610Capability);
gsmCap->SetTxFramesInPacket(gsmFrames);
}
#endif
if (cap & AST_FORMAT_ULAW) {
H323_G711Capability *g711uCap;
lastcap = localCapabilities.SetCapability(0, 0, g711uCap = new H323_G711Capability(H323_G711Capability::muLaw));
g711uCap->SetTxFramesInPacket(g711Frames);
}
if (cap & AST_FORMAT_ALAW) {
H323_G711Capability *g711aCap;
lastcap = localCapabilities.SetCapability(0, 0, g711aCap = new H323_G711Capability(H323_G711Capability::ALaw));
g711aCap->SetTxFramesInPacket(g711Frames);
}
lastcap++;
lastcap = localCapabilities.SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::HookFlashH245));
lastcap++;
mode = dtmfMode;
if (dtmfMode == H323_DTMF_INBAND) {
localCapabilities.SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::SignalToneH245));
sendUserInputMode = SendUserInputAsTone;
} else {
localCapabilities.SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::SignalToneRFC2833));
sendUserInputMode = SendUserInputAsInlineRFC2833;
}
if (h323debug) {
cout << "Allowed Codecs:\n\t" << setprecision(2) << localCapabilities << endl;
}
}
/* MyH323_ExternalRTPChannel */ /* MyH323_ExternalRTPChannel */
MyH323_ExternalRTPChannel::MyH323_ExternalRTPChannel(MyH323Connection & connection, MyH323_ExternalRTPChannel::MyH323_ExternalRTPChannel(MyH323Connection & connection,
const H323Capability & capability, const H323Capability & capability,
@ -1106,7 +1182,8 @@ void h323_callback_register(setup_incoming_cb ifunc,
answer_call_cb acfunc, answer_call_cb acfunc,
progress_cb pgfunc, progress_cb pgfunc,
rfc2833_cb dtmffunc, rfc2833_cb dtmffunc,
hangup_cb hangupfunc) hangup_cb hangupfunc,
setcapabilities_cb capabilityfunc)
{ {
on_incoming_call = ifunc; on_incoming_call = ifunc;
on_outgoing_call = sfunc; on_outgoing_call = sfunc;
@ -1120,90 +1197,30 @@ void h323_callback_register(setup_incoming_cb ifunc,
on_progress = pgfunc; on_progress = pgfunc;
on_set_rfc2833_payload = dtmffunc; on_set_rfc2833_payload = dtmffunc;
on_hangup = hangupfunc; on_hangup = hangupfunc;
on_setcapabilities = capabilityfunc;
} }
/** /**
* Add capability to the capability table of the end point. * Add capability to the capability table of the end point.
*/ */
int h323_set_capability(int cap, int dtmfMode) int h323_set_capabilities(const char *token, int cap, int dtmfMode)
{ {
H323Capabilities oldcaps; MyH323Connection *conn;
PStringArray codecs;
int g711Frames = 20;
// int gsmFrames = 4;
PINDEX lastcap = -1; /* last common capability index */
if (!h323_end_point_exist()) { if (!h323_end_point_exist()) {
cout << " ERROR: [h323_set_capablity] No Endpoint, this is bad" << endl; cout << " ERROR: [h323_set_capablity] No Endpoint, this is bad" << endl;
return 1; return 1;
} }
/* clean up old capabilities list before changing */ PString myToken(token);
oldcaps = endPoint->GetCapabilities(); conn = (MyH323Connection *)endPoint->FindConnectionWithLock(myToken);
for (PINDEX i=0; i< oldcaps.GetSize(); i++) { if (!conn) {
codecs.AppendString(oldcaps[i].GetFormatName()); cout << " ERROR: [h323_set_capability] Unable to find connection " << token << endl;
} return 1;
endPoint->RemoveCapabilities(codecs);
#if 0
if (cap & AST_FORMAT_SPEEX) {
/* Not real sure if Asterisk acutally supports all
of the various different bit rates so add them
all and figure it out later*/
endPoint->SetCapability(0, 0, new SpeexNarrow2AudioCapability());
endPoint->SetCapability(0, 0, new SpeexNarrow3AudioCapability());
endPoint->SetCapability(0, 0, new SpeexNarrow4AudioCapability());
endPoint->SetCapability(0, 0, new SpeexNarrow5AudioCapability());
endPoint->SetCapability(0, 0, new SpeexNarrow6AudioCapability());
}
#endif
if (cap & AST_FORMAT_G729A) {
AST_G729ACapability *g729aCap;
AST_G729Capability *g729Cap;
lastcap = endPoint->SetCapability(0, 0, g729aCap = new AST_G729ACapability);
lastcap = endPoint->SetCapability(0, 0, g729Cap = new AST_G729Capability);
}
if (cap & AST_FORMAT_G723_1) {
H323_G7231Capability *g7231Cap;
lastcap = endPoint->SetCapability(0, 0, g7231Cap = new H323_G7231Capability);
}
#if 0
if (cap & AST_FORMAT_GSM) {
H323_GSM0610Capability *gsmCap;
lastcap = endPoint->SetCapability(0, 0, gsmCap = new H323_GSM0610Capability);
gsmCap->SetTxFramesInPacket(gsmFrames);
}
#endif
if (cap & AST_FORMAT_ULAW) {
H323_G711Capability *g711uCap;
lastcap = endPoint->SetCapability(0, 0, g711uCap = new H323_G711Capability(H323_G711Capability::muLaw));
g711uCap->SetTxFramesInPacket(g711Frames);
}
if (cap & AST_FORMAT_ALAW) {
H323_G711Capability *g711aCap;
lastcap = endPoint->SetCapability(0, 0, g711aCap = new H323_G711Capability(H323_G711Capability::ALaw));
g711aCap->SetTxFramesInPacket(g711Frames);
}
lastcap++;
lastcap = endPoint->SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::HookFlashH245));
lastcap++;
mode = dtmfMode;
if (dtmfMode == H323_DTMF_INBAND) {
endPoint->SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::SignalToneH245));
endPoint->SetSendUserInputMode(H323Connection::SendUserInputAsTone);
} else {
endPoint->SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::SignalToneRFC2833));
endPoint->SetSendUserInputMode(H323Connection::SendUserInputAsInlineRFC2833);
} }
conn->SetCapabilities(cap, dtmfMode);
conn->Unlock();
if (h323debug) {
cout << "Allowed Codecs:\n\t" << setprecision(2) << endPoint->GetCapabilities() << endl;
}
return 0; return 0;
} }

@ -128,6 +128,7 @@ class MyH323EndPoint : public H323EndPoint {
PCLASSINFO(MyH323EndPoint, H323EndPoint); PCLASSINFO(MyH323EndPoint, H323EndPoint);
public: public:
MyH323EndPoint();
int MakeCall(const PString &, PString &, unsigned int *, call_options_t *opts); int MakeCall(const PString &, PString &, unsigned int *, call_options_t *opts);
BOOL ClearCall(const PString &, H323Connection::CallEndReason reason); BOOL ClearCall(const PString &, H323Connection::CallEndReason reason);
BOOL ClearCall(const PString &); BOOL ClearCall(const PString &);
@ -137,7 +138,6 @@ class MyH323EndPoint : public H323EndPoint {
void OnConnectionCleared(H323Connection &, const PString &); void OnConnectionCleared(H323Connection &, const PString &);
H323Connection * CreateConnection(unsigned, void *); H323Connection * CreateConnection(unsigned, void *);
void SendUserTone(const PString &, char); void SendUserTone(const PString &, char);
H323Capabilities GetCapabilities(void);
BOOL OnConnectionForwarded(H323Connection &, const PString &, const H323SignalPDU &); BOOL OnConnectionForwarded(H323Connection &, const PString &, const H323SignalPDU &);
BOOL ForwardConnection(H323Connection &, const PString &, const H323SignalPDU &); BOOL ForwardConnection(H323Connection &, const PString &, const H323SignalPDU &);
void SetEndpointTypeInfo( H225_EndpointType & info ) const; void SetEndpointTypeInfo( H225_EndpointType & info ) const;
@ -173,6 +173,8 @@ class MyH323Connection : public H323Connection {
void OnUserInputString(const PString &value); void OnUserInputString(const PString &value);
BOOL OnReceivedProgress(const H323SignalPDU &); BOOL OnReceivedProgress(const H323SignalPDU &);
void OnSendCapabilitySet(H245_TerminalCapabilitySet &); void OnSendCapabilitySet(H245_TerminalCapabilitySet &);
void OnSetLocalCapabilities();
void SetCapabilities(int, int);
BOOL OnReceivedCapabilitySet(const H323Capabilities &, const H245_MultiplexCapability *, BOOL OnReceivedCapabilitySet(const H323Capabilities &, const H245_MultiplexCapability *,
H245_TerminalCapabilitySetReject &); H245_TerminalCapabilitySetReject &);
void SetCause(int _cause) { cause = _cause; }; void SetCause(int _cause) { cause = _cause; };

@ -169,6 +169,9 @@ extern rfc2833_cb on_set_rfc2833_payload;
typedef void (*hangup_cb)(unsigned, const char *, int); typedef void (*hangup_cb)(unsigned, const char *, int);
extern hangup_cb on_hangup; extern hangup_cb on_hangup;
typedef void (*setcapabilities_cb)(unsigned, const char *);
extern setcapabilities_cb on_setcapabilities;
/* debug flag */ /* debug flag */
extern int h323debug; extern int h323debug;
@ -202,8 +205,9 @@ extern "C" {
answer_call_cb, answer_call_cb,
progress_cb, progress_cb,
rfc2833_cb, rfc2833_cb,
hangup_cb); hangup_cb,
int h323_set_capability(int, int); setcapabilities_cb);
int h323_set_capabilities(const char *, int, int);
int h323_set_alias(struct oh323_alias *); int h323_set_alias(struct oh323_alias *);
int h323_set_gk(int, char *, char *); int h323_set_gk(int, char *, char *);
void h323_set_id(char *); void h323_set_id(char *);

Loading…
Cancel
Save