Marian Durkovic
2004-Mar-18 08:35 UTC
[Asterisk-Users] Several H323 bugfixes - working SIP <-> H.323 translator
Hi all, in an effort to create a SIP <-> H.323 translator we've found and fixed several problems in H.323 channel. These inlcude: for SIP->H.323 calls - no ringback tone - ringback not related to H.323 events - one-way audio with Cisco CallManager - incorrect Caller ID for H.323->SIP calls - not able to establish call with Cisco IOS 12.3(4)T - ringback not related to SIP events - no support for 183 Call Progress - incorrect Caller ID Please find the patches against aterisk 0.7.2 release below. M. -------------------------------------------------------------------------- ---- ---- ---- Marian Durkovic network manager ---- ---- ---- ---- Slovak Technical University Tel: +421 2 524 51 301 ---- ---- Computer Centre, Nam. Slobody 17 Fax: +421 2 524 94 351 ---- ---- 812 43 Bratislava, Slovak Republic E-mail/sip: md@bts.sk ---- ---- ---- -------------------------------------------------------------------------- -------------- next part -------------- --- chan_h323.h.072 Tue Jan 13 09:46:46 2004 +++ chan_h323.h Thu Mar 18 16:03:11 2004 @@ -84,6 +84,7 @@ function*/ typedef struct call_options { char *callerid; + char *callername; int noFastStart; int noH245Tunnelling; int noSilenceSuppression; @@ -101,6 +102,7 @@ const char *call_dest_alias; const char *call_source_e164; const char *call_dest_e164; + const char *call_source_name; const char *sourceIp; } call_details_t; @@ -134,6 +136,11 @@ typedef void (*start_logchan_cb)(unsigned int, const char *, int); start_logchan_cb on_start_logical_channel; +/* This is a callback prototype function, called when openh323 + OnAlerting is invoked */ +typedef void (*chan_ringing_cb)(unsigned); +chan_ringing_cb on_chan_ringing; + /* This is a callback protoype function, called when the openh323 OnConnectionEstablished is inovked */ typedef void (*con_established_cb)(unsigned); @@ -167,6 +174,7 @@ on_connection_cb, start_logchan_cb, clear_con_cb, + chan_ringing_cb, con_established_cb, send_digit_cb); @@ -189,6 +197,8 @@ /* H323 create and destroy sessions */ int h323_make_call(char *host, call_details_t *cd, call_options_t); int h323_clear_call(const char *); + int h323_send_alerting(const char *token); + int h323_send_progress(const char *token); int h323_answering_call(const char *token, int); int h323_soft_hangup(const char *data); -------------- next part -------------- --- chan_h323.c.072 Tue Jan 13 10:24:26 2004 +++ chan_h323.c Thu Mar 18 16:09:40 2004 @@ -388,7 +389,7 @@ int res; struct oh323_pvt *p = c->pvt->pvt; char called_addr[256]; - char *tmp; + char *tmp, *cid, *cidname, oldcid[256]; strtok_r(dest, "/", &(tmp)); @@ -419,15 +420,47 @@ /* Copy callerid, if there is any */ if (c->callerid) { - char *tmp = strchr(c->callerid, '"'); - if (!tmp) { - p->calloptions.callerid = malloc(80); // evil - // sprintf(p->calloptions.callerid, "\"%s\"", c->callerid); - sprintf(p->calloptions.callerid, "\"\" <%s>", c->callerid); - } else { - p->calloptions.callerid = strdup(c->callerid); - } - } + memset(oldcid, 0, sizeof(oldcid)); + memcpy(oldcid, c->callerid, strlen(c->callerid)); + oldcid[sizeof(oldcid)-1] = '\0'; + ast_callerid_parse(oldcid, &cidname, &cid); + if (p->calloptions.callerid) { + free(p->calloptions.callerid); + p->calloptions.callerid = NULL; + } + if (p->calloptions.callername) { + free(p->calloptions.callername); + p->calloptions.callername = NULL; + } + p->calloptions.callerid = (char*)malloc(256); + if (p->calloptions.callerid == NULL) { + ast_log(LOG_ERROR, "Not enough memory.\n"); + return(-1); + } + memset(p->calloptions.callerid, 0, 256); + if ((cid != NULL)&&(strlen(cid) > 0)) + strncpy(p->calloptions.callerid, cid, 255); + + p->calloptions.callername = (char*)malloc(256); + if (p->calloptions.callername == NULL) { + ast_log(LOG_ERROR, "Not enough memory.\n"); + return(-1); + } + memset(p->calloptions.callername, 0, 256); + if ((cidname != NULL)&&(strlen(cidname) > 0)) + strncpy(p->calloptions.callername, cidname, 255); + + } else { + if (p->calloptions.callerid) { + free(p->calloptions.callerid); + p->calloptions.callerid = NULL; + } + if (p->calloptions.callername) { + free(p->calloptions.callername); + p->calloptions.callername = NULL; + } + } + res = h323_make_call(called_addr, &(p->cd), p->calloptions); @@ -436,7 +469,6 @@ return -1; } - ast_setstate(c, AST_STATE_RINGING); return 0; } @@ -592,27 +624,33 @@ switch(condition) { case AST_CONTROL_RINGING: - if (c->_state == AST_STATE_RING) { - // transmit_response(p, "180 Ringing", &p->initreq); + if (c->_state == AST_STATE_RING || c->_state == AST_STATE_RINGING) { + h323_send_alerting(p->cd.call_token); break; } - return 0; + return -1; + case AST_CONTROL_PROGRESS: + if (c->_state != AST_STATE_UP) { + h323_send_progress(p->cd.call_token); + break; + } + return -1; case AST_CONTROL_BUSY: if (c->_state != AST_STATE_UP) { - // transmit_response(p, "600 Busy everywhere", &p->initreq); + h323_answering_call(p->cd.call_token, 1); p->alreadygone = 1; - ast_softhangup(c, AST_SOFTHANGUP_DEV); + ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV); break; } - return 0; + return -1; case AST_CONTROL_CONGESTION: if (c->_state != AST_STATE_UP) { - // transmit_response(p, "486 Busy here", &p->initreq); + h323_answering_call(p->cd.call_token, 1); p->alreadygone = 1; - ast_softhangup(c, AST_SOFTHANGUP_DEV); + ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV); break; } - return 0; + return -1; case -1: return -1; default: @@ -985,11 +1023,12 @@ p->cd.call_dest_alias = cd.call_dest_alias; p->cd.call_source_e164 = cd.call_source_e164; p->cd.call_dest_e164 = cd.call_dest_e164; + p->cd.call_source_name = cd.call_source_name; if (h323debug) { ast_verbose(VERBOSE_PREFIX_3 "Setting up Call\n"); ast_verbose(VERBOSE_PREFIX_3 " Call token: [%s]\n", p->cd.call_token); - ast_verbose(VERBOSE_PREFIX_3 " Calling party name: [%s]\n", p->cd.call_source_aliases); + ast_verbose(VERBOSE_PREFIX_3 " Calling party name: [%s]\n", p->cd.call_source_name); ast_verbose(VERBOSE_PREFIX_3 " Calling party number: [%s]\n", p->cd.call_source_e164); ast_verbose(VERBOSE_PREFIX_3 " Called party name: [%s]\n", p->cd.call_dest_alias); ast_verbose(VERBOSE_PREFIX_3 " Called party number: [%s]\n", p->cd.call_dest_e164); @@ -1013,7 +1052,7 @@ } - sprintf(p->callerid, "%s <%s>", p->cd.call_source_aliases, p->cd.call_source_e164); + sprintf(p->callerid, "%s <%s>", p->cd.call_source_name, p->cd.call_source_e164); } else { /* Either this call is not from the Gatekeeper @@ -1024,7 +1063,7 @@ if (!user) { - sprintf(p->callerid, "%s <%s>", p->cd.call_source_aliases, p->cd.call_source_e164); + sprintf(p->callerid, "%s <%s>", p->cd.call_source_name, p->cd.call_source_e164); if (strlen(p->cd.call_dest_e164)) { strncpy(p->exten, cd.call_dest_e164, sizeof(p->exten)-1); } else { @@ -1064,7 +1103,7 @@ if (strlen(user->callerid)) strncpy(p->callerid, user->callerid, sizeof(p->callerid) - 1); else - sprintf(p->callerid, "%s <%s>", p->cd.call_source_aliases, p->cd.call_source_e164); + sprintf(p->callerid, "%s <%s>", p->cd.call_source_name, p->cd.call_source_e164); if (strlen(p->cd.call_dest_e164)) { strncpy(p->exten, cd.call_dest_e164, sizeof(p->exten)-1); @@ -1162,8 +1201,38 @@ c = p->owner; ast_setstate(c, AST_STATE_UP); + ast_queue_control(c, AST_CONTROL_ANSWER, 0); + return; } +/** + * Call-back function to signal asterisk that the channel is ringing + + * Returns nothing + */ + +void chan_ringing(unsigned call_reference) +{ + struct ast_channel *c = NULL; + struct oh323_pvt *p = NULL; + + p = find_call(call_reference); + + if (!p) + ast_log(LOG_ERROR, "Something is wrong: ringing\n"); + + + if (!p->owner) { + ast_log(LOG_ERROR, "Channel has no owner\n"); + return; + } + c = p->owner; + ast_setstate(c, AST_STATE_RINGING); + ast_queue_control(c, AST_CONTROL_RINGING, 0); + + return; +} + /** * Call-back function to cleanup communication @@ -1793,6 +1862,7 @@ create_connection, setup_rtp_connection, cleanup_connection, + chan_ringing, connection_made, send_digit); -------------- next part -------------- --- ast_h323.h.072 Tue Jan 13 04:06:06 2004 +++ ast_h323.h Thu Mar 18 16:00:46 2004 @@ -198,7 +198,7 @@ public: - int MakeCall(const PString &, PString &, unsigned int *, unsigned int, char *); + int MakeCall(const PString &, PString &, unsigned int *, unsigned int, char *, char *); BOOL ClearCall(const PString &); void OnClosedLogicalChannel(H323Connection &, const H323Channel &); @@ -252,6 +252,45 @@ WORD sessionId; BOOL bridging; // Used to help determine which IP to use }; + +class MyH323_ExternalRTPChannel : public H323_ExternalRTPChannel { + + PCLASSINFO(MyH323_ExternalRTPChannel, H323_ExternalRTPChannel); + + public: + MyH323_ExternalRTPChannel( + MyH323Connection & connection, /// Connection to endpoint for channel + const H323Capability & capability, /// Capability channel is using + Directions direction, /// Direction of channel + unsigned sessionID /// Session ID for channel + ); + MyH323_ExternalRTPChannel( + MyH323Connection & connection, /// Connection to endpoint for channel + const H323Capability & capability, /// Capability channel is using + Directions direction, /// Direction of channel + unsigned sessionID, /// Session ID for channel + const H323TransportAddress & data, /// Data address + const H323TransportAddress & control/// Control address + ); + /**Create a new channel. + */ + MyH323_ExternalRTPChannel( + MyH323Connection & connection, /// Connection to endpoint for channel + const H323Capability & capability, /// Capability channel is using + Directions direction, /// Direction of channel + unsigned sessionID, /// Session ID for channel + const PIPSocket::Address & ip, /// IP address of media server + WORD dataPort /// Data port (control is dataPort+1) + ); + + BOOL OnReceivedAckPDU(const H245_H2250LogicalChannelAckParameters & param); + + PIPSocket::Address externalIpAddress; // IP address of media server + PIPSocket::Address remoteIpAddress; // IP Address of remote + WORD externalPort; // local media s + WORD remotePort; + +}; /** * The MyProcess is a necessary descendant PProcess class so that the H323EndPoint -------------- next part -------------- --- ast_h323.cpp.072 Tue Jan 13 09:31:13 2004 +++ ast_h323.cpp Thu Mar 18 16:12:58 2004 @@ -219,7 +219,7 @@ * port = 1720. */ int MyH323EndPoint::MakeCall(const PString & dest, PString & token, - unsigned int *callReference, unsigned int port, char *callerid) + unsigned int *callReference, unsigned int port, char *callerid, char *callername) { PString fullAddress; MyH323Connection * connection; @@ -243,8 +243,15 @@ *callReference = connection->GetCallReference(); - if (callerid) - connection->SetLocalPartyName(PString(callerid)); + if (callername) { + localAliasNames.RemoveAll(); + connection->SetLocalPartyName(PString(callername)); + if (callerid) + localAliasNames.AppendString(PString(callerid)); + } else if (callerid) { + localAliasNames.RemoveAll(); + connection->SetLocalPartyName(PString(callerid)); + } connection->Unlock(); @@ -447,6 +454,8 @@ if (noH245Tunnelling) options |= H323Connection::H245TunnelingOptionDisable; + SetAudioJitterDelay(10, 50); + return new MyH323Connection(*this, callReference, options); } @@ -478,7 +487,7 @@ { /* The call will be answered later with "AnsweringCall()" function. */ - return H323Connection::AnswerCallAlertWithMedia; + return H323Connection::AnswerCallDeferred; } BOOL MyH323Connection::OnAlerting(const H323SignalPDU & /*alertingPDU*/, const PString & username) @@ -487,6 +496,7 @@ if (h323debug) { cout << " -- Ringing phone for \"" << username << "\"" << endl; } + on_chan_ringing(GetCallReference()); return TRUE; } @@ -499,6 +509,7 @@ call_details_t cd; PString sourceE164; + PString sourceName; PString destE164; PString sourceAliases; PString destAliases; @@ -511,6 +522,8 @@ sourceE164 = ""; setupPDU.GetSourceE164(sourceE164); + sourceName = ""; + sourceName=setupPDU.GetQ931().GetDisplayName(); destE164 = ""; setupPDU.GetDestinationE164(destE164); @@ -538,6 +551,7 @@ cd.call_source_e164 = (const char *)sourceE164; cd.call_dest_e164 = (const char *)destE164; cd.sourceIp = (const char *)sourceIp; + cd.call_source_name = (const char *)sourceName; /* Notify Asterisk of the request */ int res = on_incoming_call(cd); @@ -683,7 +697,7 @@ cout << " -- SessionID: " << sessionID << endl; cout << " -- Direction: " << dir << endl; } - return new H323_ExternalRTPChannel(*this, capability, dir, sessionID, externalIpAddress, externalPort); + return new MyH323_ExternalRTPChannel(*this, capability, dir, sessionID, externalIpAddress, externalPort); } /** This callback function is invoked once upon creation of each @@ -717,6 +731,49 @@ } +MyH323_ExternalRTPChannel::MyH323_ExternalRTPChannel(MyH323Connection & connection, + const H323Capability & capability, + Directions direction, + unsigned id) +: +H323_ExternalRTPChannel::H323_ExternalRTPChannel(connection, capability, direction, id) +{ +} + +MyH323_ExternalRTPChannel::MyH323_ExternalRTPChannel(MyH323Connection & connection, const H323Capability & capability, + Directions direction, + unsigned id, + const H323TransportAddress & data, + const H323TransportAddress & control) : H323_ExternalRTPChannel::H323_ExternalRTPChannel(connection, capability, direction, id, data, control) +{ +} + +MyH323_ExternalRTPChannel::MyH323_ExternalRTPChannel(MyH323Connection & connection, + const H323Capability & capability, + Directions direction, + unsigned id, + const PIPSocket::Address & ip, + WORD dataPort) + : H323_ExternalRTPChannel::H323_ExternalRTPChannel(connection, capability, direction, id, ip, dataPort) +{ +} + +BOOL MyH323_ExternalRTPChannel::OnReceivedAckPDU(const H245_H2250LogicalChannelAckParameters & param) +{ + H323_ExternalRTPChannel::OnReceivedAckPDU(param); + + H323_ExternalRTPChannel::GetRemoteAddress(remoteIpAddress, remotePort); + + if (h323debug) { + cout << " -- remoteIpAddress: " << remoteIpAddress << endl; + cout << " -- remotePort: " << remotePort << endl; + } + /* Notify Asterisk of remote RTP information */ + on_start_logical_channel(connection.GetCallReference(), (const char *)remoteIpAddress.AsString(), remotePort); + + return TRUE; +} + /** IMPLEMENTATION OF C FUNCTIONS */ /** @@ -772,6 +829,7 @@ on_connection_cb confunc, start_logchan_cb lfunc, clear_con_cb clfunc, + chan_ringing_cb rfunc, con_established_cb efunc, send_digit_cb dfunc) { @@ -780,6 +838,7 @@ on_create_connection = confunc; on_start_logical_channel = lfunc; on_connection_cleared = clfunc; + on_chan_ringing = rfunc; on_connection_established = efunc; on_send_digit = dfunc; } @@ -1011,7 +1070,7 @@ PString dest(host); - res = endPoint->MakeCall(dest, token, &cd->call_reference, call_options.port, call_options.callerid); + res = endPoint->MakeCall(dest, token, &cd->call_reference, call_options.port, call_options.callerid, call_options.callername); memcpy((char *)(cd->call_token), (const unsigned char *)token, token.GetLength()); return res; @@ -1026,6 +1085,47 @@ endPoint->ClearCall(PString(call_token)); return 0; }; + +/* Send Alerting PDU to H.323 caller */ + +int h323_send_alerting(const char *token) +{ + const PString currentToken(token); + H323Connection * connection; + + connection = endPoint->FindConnectionWithLock(currentToken); + + if (connection == NULL) { + cout << "No connection found for " << token << endl; + return -1; + } + + connection->AnsweringCall(H323Connection::AnswerCallPending); + connection->Unlock(); + + return 0; + +} + +/* Send Progress PDU to H.323 caller */ + +int h323_send_progress(const char *token) +{ + const PString currentToken(token); + H323Connection * connection; + + connection = endPoint->FindConnectionWithLock(currentToken); + + if (connection == NULL) { + cout << "No connection found for " << token << endl; + return -1; + } + + connection->AnsweringCall(H323Connection::AnswerCallDeferredWithMedia); + connection->Unlock(); + + return 0; +} /** This function tells the h.323 stack to either answer or deny an incoming call */
Bartosz Jozwiak
2004-Mar-18 09:03 UTC
[Asterisk-Users] Several H323 bugfixes - working SIP <-> H.323 translator
> Hi all, > > in an effort to create a SIP <-> H.323 translator we've found and fixed > several problems in H.323 channel. These inlcude: > > for SIP->H.323 calls > > - no ringback tone > - ringback not related to H.323 events > - one-way audio with Cisco CallManager > - incorrect Caller ID > > for H.323->SIP calls > > - not able to establish call with Cisco IOS 12.3(4)T > - ringback not related to SIP events > - no support for 183 Call Progress > - incorrect Caller ID > > > Please find the patches against aterisk 0.7.2 release below. > > > M. >Did you put these files to bugs.digium.com ?
Billy Huddleston
2004-Mar-18 10:22 UTC
[Asterisk-Users] Several H323 bugfixes - working SIP <-> H.323 translator
I just tried this, and it's not working for me.. I can't call a 2600 or a CCM... What version of OpenH323 and PWLIB did you all use? ----- Original Message ----- From: "Marian Durkovic" <md@bts.sk> To: <asterisk-users@lists.digium.com> Sent: Thursday, March 18, 2004 10:35 AM Subject: [Asterisk-Users] Several H323 bugfixes - working SIP <-> H.323 translator> Hi all, > > in an effort to create a SIP <-> H.323 translator we've found and fixed > several problems in H.323 channel. These inlcude: > > for SIP->H.323 calls > > - no ringback tone > - ringback not related to H.323 events > - one-way audio with Cisco CallManager > - incorrect Caller ID > > for H.323->SIP calls > > - not able to establish call with Cisco IOS 12.3(4)T > - ringback not related to SIP events > - no support for 183 Call Progress > - incorrect Caller ID > > > Please find the patches against aterisk 0.7.2 release below. > > > M. > > > -------------------------------------------------------------------------- > ---- ---- > ---- Marian Durkovic network manager ---- > ---- ---- > ---- Slovak Technical University Tel: +421 2 524 51 301 ---- > ---- Computer Centre, Nam. Slobody 17 Fax: +421 2 524 94 351 ---- > ---- 812 43 Bratislava, Slovak Republic E-mail/sip: md@bts.sk ---- > ---- ---- > -------------------------------------------------------------------------- >