dd8d9274ae7f0f19de2b77b3beb989cd40428e65
[asterisk/asterisk.git] / channels / h323 / ast_h323.cpp
1 /*
2  * ast_h323.cpp
3  *
4  * OpenH323 Channel Driver for ASTERISK PBX.
5  *                      By  Jeremy McNamara
6  *                      For The NuFone Network
7  * 
8  * chan_h323 has been derived from code created by
9  *               Michael Manousos and Mark Spencer
10  *
11  * This file is part of the chan_h323 driver for Asterisk
12  *
13  * chan_h323 is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version. 
17  *
18  * chan_h323 is distributed WITHOUT ANY WARRANTY; without even 
19  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
20  * PURPOSE. See the GNU General Public License for more details. 
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
25  *
26  * Version Info: $Id$
27  */
28 #include <arpa/inet.h>
29
30 #include <list>
31 #include <string>
32 #include <algorithm>
33
34 #include <ptlib.h>
35 #include <h323.h>
36 #include <h323pdu.h>
37 #include <mediafmt.h>
38 #include <lid.h>
39
40 #ifdef __cplusplus
41 extern "C" {
42 #endif   
43 #include <asterisk/logger.h>
44 #ifdef __cplusplus
45 }
46 #endif
47
48 #include "chan_h323.h"
49 #include "ast_h323.h"
50
51 /* PWlib Required Components  */
52 #define MAJOR_VERSION 1
53 #define MINOR_VERSION 0
54 #define BUILD_TYPE    ReleaseCode
55 #define BUILD_NUMBER  0
56
57 /** Counter for the number of connections */
58 int channelsOpen;
59
60 /* DTMF Mode */
61 int mode = H323_DTMF_RFC2833;
62
63 /**
64  * We assume that only one endPoint should exist.
65  * The application cannot run the h323_end_point_create() more than once
66  * FIXME: Singleton this, for safety
67  */
68 MyH323EndPoint *endPoint = NULL;
69
70 /** PWLib entry point */
71 MyProcess *localProcess = NULL;
72
73 MyProcess::MyProcess(): PProcess("The NuFone Network's", "H.323 Channel Driver for Asterisk",
74              MAJOR_VERSION, MINOR_VERSION, BUILD_TYPE, BUILD_NUMBER)
75 {
76         Resume();
77 }
78
79 void MyProcess::Main()
80 {
81         ast_verbose("  == Creating H.323 Endpoint\n");
82         endPoint = new MyH323EndPoint();
83         PTrace::Initialise(0, NULL, PTrace::Timestamp | PTrace::Thread | PTrace::FileAndLine);
84 }
85
86 #define H323_G7231 OPAL_G7231_6k3"{sw}"
87 #define H323_G729  OPAL_G729 "{sw}"
88 #define H323_G729A OPAL_G729A"{sw}"
89
90 H323_REGISTER_CAPABILITY(H323_G7231Capability, H323_G7231);
91 H323_REGISTER_CAPABILITY(AST_G729Capability,  H323_G729);
92 H323_REGISTER_CAPABILITY(AST_G729ACapability, H323_G729A);
93
94 H323_G7231Capability::H323_G7231Capability(BOOL annexA_)
95   : H323AudioCapability(7, 4)
96 {
97   annexA = annexA_;
98 }
99
100 PObject::Comparison H323_G7231Capability::Compare(const PObject & obj) const
101 {
102   Comparison result = H323AudioCapability::Compare(obj);
103   if (result != EqualTo)
104     return result;
105
106   PINDEX otherAnnexA = ((const H323_G7231Capability &)obj).annexA;
107   if (annexA < otherAnnexA)
108     return LessThan;
109   if (annexA > otherAnnexA)
110     return GreaterThan;
111   return EqualTo;
112 }
113
114 PObject * H323_G7231Capability::Clone() const
115 {
116   return new H323_G7231Capability(*this);
117 }
118
119 PString H323_G7231Capability::GetFormatName() const
120 {
121   return H323_G7231;
122 }
123
124 unsigned H323_G7231Capability::GetSubType() const
125 {
126   return H245_AudioCapability::e_g7231;
127 }
128
129 BOOL H323_G7231Capability::OnSendingPDU(H245_AudioCapability & cap,
130                                           unsigned packetSize) const
131 {
132   cap.SetTag(H245_AudioCapability::e_g7231);
133
134   H245_AudioCapability_g7231 & g7231 = cap;
135   g7231.m_maxAl_sduAudioFrames = packetSize;
136   g7231.m_silenceSuppression = annexA;
137
138   return TRUE;
139 }
140
141 BOOL H323_G7231Capability::OnReceivedPDU(const H245_AudioCapability & cap,
142                                            unsigned & packetSize)
143 {
144   if (cap.GetTag() != H245_AudioCapability::e_g7231)
145     return FALSE;
146
147   const H245_AudioCapability_g7231 & g7231 = cap;
148   packetSize = g7231.m_maxAl_sduAudioFrames;
149   annexA = g7231.m_silenceSuppression;
150
151   return TRUE;
152 }
153
154 H323Codec * H323_G7231Capability::CreateCodec(H323Codec::Direction direction) const
155 {
156   return NULL;
157 }
158
159 /////////////////////////////////////////////////////////////////////////////
160
161 AST_G729Capability::AST_G729Capability()
162   : H323AudioCapability(24, 6)
163 {
164 }
165
166 PObject * AST_G729Capability::Clone() const
167 {
168   return new AST_G729Capability(*this);
169 }
170
171 unsigned AST_G729Capability::GetSubType() const
172 {
173   return H245_AudioCapability::e_g729;
174 }
175
176 PString AST_G729Capability::GetFormatName() const
177 {
178   return H323_G729;
179 }
180
181 H323Codec * AST_G729Capability::CreateCodec(H323Codec::Direction direction) const
182 {
183   return NULL;
184 }
185
186 /////////////////////////////////////////////////////////////////////////////
187
188 AST_G729ACapability::AST_G729ACapability()
189   : H323AudioCapability(24, 6)
190 {
191 }
192
193 PObject * AST_G729ACapability::Clone() const
194 {
195   return new AST_G729ACapability(*this);
196 }
197
198 unsigned AST_G729ACapability::GetSubType() const
199 {
200   return H245_AudioCapability::e_g729AnnexA;
201 }
202
203 PString AST_G729ACapability::GetFormatName() const
204 {
205   return H323_G729A;
206 }
207
208 H323Codec * AST_G729ACapability::CreateCodec(H323Codec::Direction direction) const
209 {
210   return NULL;
211 }
212
213 /** MyH323EndPoint 
214   * The fullAddress parameter is used directly in the MakeCall method so
215   * the General form for the fullAddress argument is :
216   * [alias@][transport$]host[:port]
217   * default values:     alias = the same value as host.
218   *                                     transport = ip.
219   *                                     port = 1720.
220   */
221 int MyH323EndPoint::MakeCall(const PString & dest, PString & token, unsigned int *callReference, unsigned int port, char *cid_name, char *cid_name)
222 {
223         PString fullAddress;
224         MyH323Connection * connection;
225
226         /* Determine whether we are using a gatekeeper or not. */
227         if (GetGatekeeper()) {
228                 fullAddress = dest;
229                 if (h323debug) {
230                         cout << " -- Making call to " << fullAddress << " using gatekeeper." << endl;
231                 }
232         } else {
233                 fullAddress = dest; 
234                 if (h323debug) {
235                         cout << " -- Making call to " << fullAddress << "." << endl;
236                 }
237         }
238         if (!(connection = (MyH323Connection *)H323EndPoint::MakeCallLocked(fullAddress, token))) {
239                 if (h323debug) {
240                         cout << "Error making call to \"" << fullAddress << '"' << endl;
241                 }
242                 return 1;
243         }
244         *callReference = connection->GetCallReference();        
245         if (cid_name) {
246                 localAliasNames.RemoveAll();
247                 connection->SetLocalPartyName(PString(cid_name));
248                 if (cid_num) {
249                         localAliasNames.AppendString(PString(cid_num));
250                 }
251         } else if (cid_num) {
252                 localAliasNames.RemoveAll();
253                 connection->SetLocalPartyName(PString(cid_num));
254         }
255         if (h323debug) {
256                 cout << "       -- " << GetLocalUserName() << " is calling host " << fullAddress << endl;
257                 cout << "       -- " << "Call token is " << (const char *)token << endl;
258                 cout << "       -- Call reference is " << *callReference << endl;
259         }
260         connection->Unlock();   
261         return 0;
262 }
263
264 void MyH323EndPoint::SetEndpointTypeInfo( H225_EndpointType & info ) const
265 {
266   H323EndPoint::SetEndpointTypeInfo(info);
267   info.m_gateway.IncludeOptionalField(H225_GatewayInfo::e_protocol);
268   info.m_gateway.m_protocol.SetSize(1);
269   H225_SupportedProtocols &protocol=info.m_gateway.m_protocol[0];
270   protocol.SetTag(H225_SupportedProtocols::e_voice);
271   PINDEX as=SupportedPrefixes.GetSize();
272   ((H225_VoiceCaps &)protocol).m_supportedPrefixes.SetSize(as);
273   for (PINDEX p=0; p<as; p++) {
274     H323SetAliasAddress(SupportedPrefixes[p], ((H225_VoiceCaps &)protocol).m_supportedPrefixes[p].m_prefix);
275   }
276 }
277
278 void MyH323EndPoint::SetGateway(void)
279 {
280         terminalType = e_GatewayOnly;
281 }
282
283 H323Capabilities MyH323EndPoint::GetCapabilities(void)
284 {
285         return capabilities;
286 }
287
288 BOOL MyH323EndPoint::ClearCall(const PString & token)
289 {
290         if (h323debug) {
291                 cout << "       -- ClearCall: Request to clear call with token " << token << endl;
292         }
293         return H323EndPoint::ClearCall(token);
294 }
295
296 void MyH323EndPoint::SendUserTone(const PString &token, char tone)
297 {
298         H323Connection *connection = NULL;
299                 
300         connection = FindConnectionWithLock(token);
301         if (connection != NULL) {
302                 connection->SendUserInputTone(tone, 500);
303                 connection->Unlock();
304         }
305 }
306
307 void MyH323EndPoint::OnClosedLogicalChannel(H323Connection & connection, const H323Channel & channel)
308 {
309         channelsOpen--;
310         if (h323debug)
311                 cout << "               channelsOpen = " << channelsOpen << endl;
312         H323EndPoint::OnClosedLogicalChannel(connection, channel);
313 }
314
315 BOOL MyH323EndPoint::OnConnectionForwarded(H323Connection & connection,
316                 const PString & forwardParty,
317                 const H323SignalPDU & pdu)
318  {
319         if (h323debug) {
320                 cout << "       -- Call Forwarded to " << forwardParty << endl;
321         }
322         return FALSE;
323  }
324  
325 BOOL MyH323EndPoint::ForwardConnection(H323Connection & connection,
326                 const PString & forwardParty,
327                 const H323SignalPDU & pdu)
328 {
329         if (h323debug) {
330                 cout << "       -- Forwarding call to " << forwardParty << endl;
331         }
332         return H323EndPoint::ForwardConnection(connection, forwardParty, pdu);
333 }
334
335 void MyH323EndPoint::OnConnectionEstablished(H323Connection & connection, const PString & estCallToken)
336 {
337         if (h323debug) {
338                 cout << "\t=-= In OnConnectionEstablished for call " << connection.GetCallReference() << endl;
339                 cout << "\t\t-- Connection Established with \"" << connection.GetRemotePartyName() << "\"" << endl;
340         }
341         on_connection_established(connection.GetCallReference(), (const char *)connection.GetCallToken());
342 }
343
344 /** OnConnectionCleared callback function is called upon the dropping of an established
345   * H323 connection. 
346   */
347 void MyH323EndPoint::OnConnectionCleared(H323Connection & connection, const PString & clearedCallToken)
348 {
349         PString remoteName;
350         call_details_t cd;
351         PIPSocket::Address Ip;
352         WORD sourcePort;
353
354         remoteName = connection.GetRemotePartyName();
355
356         cd.call_reference = connection.GetCallReference();
357         cd.call_token = strdup((const char *)clearedCallToken);
358         cd.call_source_aliases = strdup((const char *)connection.GetRemotePartyName());
359         
360         connection.GetSignallingChannel()->GetRemoteAddress().GetIpAndPort(Ip, sourcePort);
361         cd.sourceIp = strdup((const char *)Ip.AsString());
362         
363         /* Convert complex strings */
364         char *s;
365         if ((s = strchr(cd.call_source_aliases, ' ')) != NULL)
366                 *s = '\0';
367
368         switch (connection.GetCallEndReason()) {
369                 case H323Connection::EndedByCallForwarded :
370                         if (h323debug)
371                                 cout << " -- " << remoteName << " has forwarded the call" << endl;
372                         break;
373                 case H323Connection::EndedByRemoteUser :
374                         if (h323debug)
375                                 cout << " -- " << remoteName << " has cleared the call" << endl;
376                         break;
377                 case H323Connection::EndedByCallerAbort :
378                         if (h323debug)
379                                 cout << " -- " << remoteName << " has stopped calling" << endl;
380                         break;
381                 case H323Connection::EndedByRefusal :
382                         if (h323debug)
383                                 cout << " -- " << remoteName << " did not accept your call" << endl;
384                         break;
385                 case H323Connection::EndedByRemoteBusy :
386                         if (h323debug)
387                         cout << " -- " << remoteName << " was busy" << endl;
388                         break;
389                 case H323Connection::EndedByRemoteCongestion :
390                         if (h323debug)
391                                 cout << " -- Congested link to " << remoteName << endl;
392                         break;
393                 case H323Connection::EndedByNoAnswer :
394                         if (h323debug)
395                                 cout << " -- " << remoteName << " did not answer your call" << endl;
396                         break;
397                 case H323Connection::EndedByTransportFail :
398                         if (h323debug)
399                                 cout << " -- Call with " << remoteName << " ended abnormally" << endl;
400                         break;
401                 case H323Connection::EndedByCapabilityExchange :
402                         if (h323debug)
403                                 cout << " -- Could not find common codec with " << remoteName << endl;
404                         break;
405                 case H323Connection::EndedByNoAccept :
406                         if (h323debug)
407                                 cout << " -- Did not accept incoming call from " << remoteName << endl;
408                         break;
409                 case H323Connection::EndedByAnswerDenied :
410                         if (h323debug)
411                                 cout << " -- Refused incoming call from " << remoteName << endl;
412                         break;
413                 case H323Connection::EndedByNoUser :
414                         if (h323debug)
415                                 cout << " -- Remote endpoint could not find user: " << remoteName << endl;
416                         break;
417                 case H323Connection::EndedByNoBandwidth :
418                         if (h323debug)
419                                 cout << " -- Call to " << remoteName << " aborted, insufficient bandwidth." << endl;
420                         break;
421                 case H323Connection::EndedByUnreachable :
422                         if (h323debug)
423                                 cout << " -- " << remoteName << " could not be reached." << endl;
424                         break;
425                 case H323Connection::EndedByHostOffline :
426                         if (h323debug)
427                                 cout << " -- " << remoteName << " is not online." << endl;
428                         break;
429                 case H323Connection::EndedByNoEndPoint :
430                         if (h323debug)
431                                 cout << " -- No phone running for " << remoteName << endl;
432                         break;
433                 case H323Connection::EndedByConnectFail :
434                         if (h323debug)
435                                 cout << " -- Transport error calling " << remoteName << endl;
436                         break;
437                 default :
438                         if (h323debug)
439                                 cout << " -- Call with " << remoteName << " completed (" << connection.GetCallEndReason() << ")" << endl;
440
441         }
442
443         if(connection.IsEstablished()) 
444                 if (h323debug)
445                         cout << "        -- Call duration " << setprecision(0) << setw(5) << (PTime() - connection.GetConnectionStartTime()) << endl;
446
447         /* Invoke the PBX application registered callback */
448         on_connection_cleared(cd);
449
450         return;
451 }
452
453
454 H323Connection * MyH323EndPoint::CreateConnection(unsigned callReference, void *o)
455 {
456         unsigned options = 0;
457         call_options_t *opts = (call_options_t *)o;
458
459         if (opts && opts->noFastStart) {
460                 options |= H323Connection::FastStartOptionDisable;
461         } else {
462                 options |= H323Connection::FastStartOptionEnable;
463         }
464         if (opts && opts->noH245Tunneling) {
465                 options |= H323Connection::H245TunnelingOptionDisable;
466         } else {
467                 options |= H323Connection::H245TunnelingOptionEnable;
468         }
469 #if 0
470         if (opts->noSilenceSuppression) {
471                 options |= H323Connection::SilenceSuppresionOptionDisable;
472         } else {
473                 options |= H323Connection::SilenceSUppressionOptionEnable;
474         }
475 #endif
476         return new MyH323Connection(*this, callReference, options);
477 }
478
479 /* MyH323Connection */    
480 MyH323Connection::MyH323Connection(MyH323EndPoint & ep, unsigned callReference,
481                                                         unsigned options)
482         : H323Connection(ep, callReference, options)
483 {
484         if (h323debug) {
485                 cout << "       == New H.323 Connection created." << endl;
486         }
487         return;
488 }
489
490 MyH323Connection::~MyH323Connection()
491 {
492         if (h323debug) {
493                 cout << "       == H.323 Connection deleted." << endl;
494         }
495         return;
496 }
497
498 H323Connection::AnswerCallResponse MyH323Connection::OnAnswerCall(const PString & caller,
499                                                                   const H323SignalPDU & /*setupPDU*/,
500                                                                   H323SignalPDU & /*connectPDU*/)
501 {
502
503        if (h323debug)
504                cout << "\t=-= In OnAnswerCall for call " << GetCallReference() << endl;
505         
506         if (!on_answer_call(GetCallReference(), (const char *)GetCallToken())) {
507                 return H323Connection::AnswerCallDenied;
508         }
509         /* The call will be answered later with "AnsweringCall()" function.
510          */ 
511         return H323Connection::AnswerCallDeferred;
512 }
513
514 BOOL  MyH323Connection::OnAlerting(const H323SignalPDU & /*alertingPDU*/, const PString & username)
515 {
516         if (h323debug) {
517                 cout << "\t =-= In OnAlerting for call " << GetCallReference()
518                       << ": sessionId=" << sessionId << endl;
519                  cout << "       -- Ringing phone for \"" << username << "\"" << endl;
520         }     
521         on_chan_ringing(GetCallReference(), (const char *)GetCallToken() );
522         return TRUE;
523 }
524
525 BOOL MyH323Connection::OnReceivedSignalSetup(const H323SignalPDU & setupPDU)
526 {
527         
528         if (h323debug) {
529                 ast_verbose("   -- Received SETUP message\n");
530         }
531         
532         call_details_t cd;
533         PString sourceE164;
534         PString destE164;
535         PString sourceName;
536         PString sourceAliases;  
537         PString destAliases;
538         PIPSocket::Address Ip;
539         WORD sourcePort;
540         char *s, *s1; 
541
542         sourceAliases = setupPDU.GetSourceAliases();
543         destAliases = setupPDU.GetDestinationAlias();
544                         
545         sourceE164 = "";
546         setupPDU.GetSourceE164(sourceE164);
547         sourceName = "";
548         sourceName=setupPDU.GetQ931().GetDisplayName();
549         destE164 = "";
550         setupPDU.GetDestinationE164(destE164);
551
552         /* Convert complex strings */
553         //  FIXME: deal more than one source alias 
554         if ((s = strchr(sourceAliases, ' ')) != NULL)
555                 *s = '\0';
556         if ((s = strchr(sourceAliases, '\t')) != NULL)
557                 *s = '\0';
558         if ((s1 = strchr(destAliases, ' ')) != NULL)
559                 *s1 = '\0';
560         if ((s1 = strchr(destAliases, '\t')) != NULL)
561                 *s1 = '\0';
562
563
564         cd.call_reference = GetCallReference();
565         Lock();
566         cd.call_token = strdup((const char *)GetCallToken());
567         Unlock();
568         cd.call_source_aliases  =  strdup((const char *)sourceAliases);
569         cd.call_dest_alias = strdup((const char *)destAliases);
570         cd.call_source_e164 = strdup((const char *)sourceE164);
571         cd.call_dest_e164 = strdup((const char *)destE164);
572         cd.call_source_name = strdup((const char *)sourceName);
573
574         GetSignallingChannel()->GetRemoteAddress().GetIpAndPort(Ip, sourcePort);
575         cd.sourceIp = strdup((const char *)Ip.AsString());
576
577         /* Notify Asterisk of the request */
578         int res = on_incoming_call(cd); 
579
580         if (!res) {
581                 if (h323debug) {
582                         cout << "       -- Call Failed" << endl;
583                 }
584                 return FALSE;
585         }
586         
587         return H323Connection::OnReceivedSignalSetup(setupPDU);
588 }
589
590 BOOL MyH323Connection::OnSendSignalSetup(H323SignalPDU & setupPDU)
591 {
592         call_details_t cd;
593         char *s, *s1;
594
595         if (h323debug) { 
596                 cout << "       -- Sending SETUP message" << endl;
597         }
598         sourceAliases = setupPDU.GetSourceAliases();
599         destAliases = setupPDU.GetDestinationAlias();
600
601         sourceE164 = "";
602         setupPDU.GetSourceE164(sourceE164);
603         destE164 = "";
604         setupPDU.GetDestinationE164(destE164);
605
606         /* Convert complex strings */
607         //  FIXME: deal more than one source alias 
608         
609         if ((s = strchr(sourceAliases, ' ')) != NULL)
610                 *s = '\0';
611         if ((s = strchr(sourceAliases, '\t')) != NULL)
612                 *s = '\0';
613         if ((s1 = strchr(destAliases, ' ')) != NULL)
614                  *s1 = '\0';
615         if ((s1 = strchr(destAliases, '\t')) != NULL)
616                 *s1 = '\0';
617
618         cd.call_reference = GetCallReference();
619         Lock();
620         cd.call_token = strdup((const char *)GetCallToken());
621         Unlock();
622         cd.call_source_aliases = strdup((const char *)sourceAliases);
623         cd.call_dest_alias = strdup((const char *)destAliases);
624         cd.call_source_e164 = strdup((const char *)sourceE164);
625         cd.call_dest_e164 = strdup((const char *)destE164);
626
627         int res = on_outgoing_call(cd); 
628                 
629         if (!res) {
630                 if (h323debug) {
631                         cout << "       -- Call Failed" << endl;
632                 }
633                 return FALSE;
634         }
635
636         return H323Connection::OnSendSignalSetup(setupPDU);
637 }
638
639 BOOL MyH323Connection::OnSendReleaseComplete(H323SignalPDU & releaseCompletePDU)
640 {
641         if (h323debug) {
642                 cout << "       -- Sending RELEASE COMPLETE" << endl;
643         }
644         return H323Connection::OnSendReleaseComplete(releaseCompletePDU);
645 }
646
647 BOOL MyH323Connection::OnReceivedFacility(const H323SignalPDU & pdu)
648 {
649         if (h323debug) {
650                 cout << "       -- Received Facility message... " << endl;
651         }       
652         return H323Connection::OnReceivedFacility(pdu);
653 }
654
655 void MyH323Connection::OnReceivedReleaseComplete(const H323SignalPDU & pdu)
656 {
657         if (h323debug) {
658                 cout <<  "      -- Received RELEASE COMPLETE message..." << endl;
659         }
660         return H323Connection::OnReceivedReleaseComplete(pdu);
661 }
662
663 BOOL MyH323Connection::OnClosingLogicalChannel(H323Channel & channel)
664 {
665         if (h323debug) {
666                 cout << "       -- Closing logical channel..." << endl;
667         }
668         return H323Connection::OnClosingLogicalChannel(channel);
669 }
670
671
672 void MyH323Connection::SendUserInputTone(char tone, unsigned duration)
673 {
674         if (h323debug) {
675                 cout << "       -- Sending user input tone (" << tone << ") to remote" << endl;
676         }
677         on_send_digit(GetCallReference(), tone, (const char *)GetCallToken());  
678         H323Connection::SendUserInputTone(tone, duration);
679 }
680
681 void MyH323Connection::OnUserInputTone(char tone, unsigned duration, unsigned logicalChannel, unsigned rtpTimestamp)
682 {
683         if (mode == H323_DTMF_INBAND) {
684                 if (h323debug) {
685                         cout << "       -- Received user input tone (" << tone << ") from remote" << endl;
686                 }
687                 on_send_digit(GetCallReference(), tone, (const char *)GetCallToken());
688         }
689         H323Connection::OnUserInputTone(tone, duration, logicalChannel, rtpTimestamp);
690 }
691
692 void MyH323Connection::OnUserInputString(const PString &value)
693 {
694         if (mode == H323_DTMF_RFC2833) {
695                 if (h323debug) {
696                         cout <<  "      -- Received user input string (" << value << ") from remote." << endl;
697                 }
698                 on_send_digit(GetCallReference(), value[0], (const char *)GetCallToken());
699         }       
700 }
701
702 H323Channel * MyH323Connection::CreateRealTimeLogicalChannel(const H323Capability & capability, 
703                                                                    H323Channel::Directions dir,
704                                                                    unsigned sessionID,
705                                                                    const H245_H2250LogicalChannelParameters * /*param*/,
706                                                                    RTP_QOS * /*param*/ )
707 {
708         return new MyH323_ExternalRTPChannel(*this, capability, dir, sessionID);
709 }
710
711 /** This callback function is invoked once upon creation of each
712   * channel for an H323 session 
713   */
714 BOOL MyH323Connection::OnStartLogicalChannel(H323Channel & channel)
715 {    
716         if (h323debug) {
717                 cout << "\t-- Started logical channel: ";       
718                 cout << ((channel.GetDirection()==H323Channel::IsTransmitter)?"sending ":((channel.GetDirection()==H323Channel::IsReceiver)?"receiving ":" ")); 
719                 cout << (const char *)(channel.GetCapability()).GetFormatName() << endl;
720         }
721
722         /* adjust the count of channels we have open */
723         channelsOpen++;
724
725         if (h323debug) {
726                 cout <<  "\t\t-- channelsOpen = " << channelsOpen << endl;
727         }
728
729         return TRUE;    
730 }
731
732 /* MyH323_ExternalRTPChannel */
733 MyH323_ExternalRTPChannel::MyH323_ExternalRTPChannel(MyH323Connection & connection,
734                                                      const H323Capability & capability,
735                                                      Directions direction,
736                                                      unsigned id)
737  : H323_ExternalRTPChannel::H323_ExternalRTPChannel(connection, capability, direction, id)
738 {   
739         struct rtp_info *info;
740
741         /* Determine the Local (A side) IP Address and port */
742         info = on_external_rtp_create(connection.GetCallReference(), (const char *)connection.GetCallToken()); 
743         if (!info) {
744                 cout << "\tERROR: on_external_rtp_create failure" << endl;
745                 return;
746         } else {
747                 localIpAddr = info->addr;
748                 localPort = info->port;
749                 /* tell the H.323 stack  */ 
750                 SetExternalAddress(H323TransportAddress(localIpAddr, localPort), H323TransportAddress(localIpAddr, localPort + 1));
751                 /* clean up allocated memory */
752                 free(info);
753         }
754
755         // Get the payload code 
756         OpalMediaFormat format(capability.GetFormatName(), FALSE);
757         payloadCode = format.GetPayloadType();
758
759
760 MyH323_ExternalRTPChannel::~MyH323_ExternalRTPChannel() 
761 {
762         if (h323debug) {
763                 cout << "\tExternalRTPChannel Destroyed" << endl;
764         }
765 }
766
767 BOOL MyH323_ExternalRTPChannel::Start(void)
768 {
769         /* Call ancestor first */
770         if (!H323_ExternalRTPChannel::Start()) {
771                 return FALSE;
772         }
773
774         /* Collect the remote information */
775         GetRemoteAddress(remoteIpAddr, remotePort);
776
777         if (h323debug) {
778                 cout << "\t\tExternal RTP Session Starting" << endl;
779                 cout << "\t\tRTP channel id " << sessionID << " parameters:" << endl;
780                 cout << "\t\t-- remoteIpAddress: " << remoteIpAddr << endl;
781                 cout << "\t\t-- remotePort: " << remotePort << endl;
782                 cout << "\t\t-- ExternalIpAddress: " <<  localIpAddr << endl;
783                 cout << "\t\t-- ExternalPort: " << localPort << endl;
784         }
785
786         /* Notify Asterisk of remote RTP information */
787         on_start_rtp_channel(connection.GetCallReference(), (const char *)remoteIpAddr.AsString(), remotePort, 
788                 (const char *)connection.GetCallToken());
789         return TRUE;
790 }
791
792 /** IMPLEMENTATION OF C FUNCTIONS */
793
794 /**
795  * The extern "C" directive takes care for 
796  * the ANSI-C representation of linkable symbols 
797  */
798
799 extern "C" {
800
801 int h323_end_point_exist(void)
802 {
803         if (!endPoint) {
804                 return 0;
805         }
806         return 1;
807 }
808     
809 void h323_end_point_create(void)
810 {
811         channelsOpen = 0;
812         localProcess = new MyProcess(); 
813         localProcess->Main();
814 }
815
816 void h323_gk_urq(void)
817 {
818         if (!h323_end_point_exist()) {
819                 cout << " ERROR: [h323_gk_urq] No Endpoint, this is bad" << endl;
820                 return;
821         }       
822         endPoint->RemoveGatekeeper();
823 }
824
825 void h323_end_process(void)
826 {
827         endPoint->ClearAllCalls();
828         endPoint->RemoveListener(NULL);
829         delete endPoint;
830         delete localProcess;
831 }
832
833 void h323_debug(int flag, unsigned level)
834 {
835         if (flag) {
836                 PTrace:: SetLevel(level); 
837         } else { 
838                 PTrace:: SetLevel(0); 
839         }
840 }
841         
842 /** Installs the callback functions on behalf of the PBX application  */
843 void h323_callback_register(setup_incoming_cb   ifunc,
844                             setup_outbound_cb   sfunc,
845                             on_rtp_cb           rtpfunc,
846                             start_rtp_cb        lfunc,
847                             clear_con_cb        clfunc,
848                             chan_ringing_cb     rfunc,
849                             con_established_cb  efunc,
850                             send_digit_cb       dfunc,
851                             answer_call_cb      acfunc)
852 {
853         on_incoming_call = ifunc;
854         on_outgoing_call = sfunc;
855         on_external_rtp_create = rtpfunc;
856         on_start_rtp_channel = lfunc;
857         on_connection_cleared = clfunc;
858         on_chan_ringing = rfunc;
859         on_connection_established = efunc;
860         on_send_digit = dfunc;
861         on_answer_call = acfunc;
862 }
863
864 /**
865  * Add capability to the capability table of the end point. 
866  */
867 int h323_set_capability(int cap, int dtmfMode)
868 {
869         H323Capabilities oldcaps;
870         PStringArray codecs;
871         int g711Frames = 30;
872 //      int gsmFrames  = 4;
873
874         if (!h323_end_point_exist()) {
875                 cout << " ERROR: [h323_set_capablity] No Endpoint, this is bad" << endl;
876                 return 1;
877         }
878
879         /* clean up old capabilities list before changing */
880         oldcaps = endPoint->GetCapabilities();
881         for (PINDEX i=0; i< oldcaps.GetSize(); i++) {
882                  codecs.AppendString(oldcaps[i].GetFormatName());
883          }
884          endPoint->RemoveCapabilities(codecs);
885
886         mode = dtmfMode;
887         if (dtmfMode == H323_DTMF_INBAND) {
888             endPoint->SetSendUserInputMode(H323Connection::SendUserInputAsTone);
889         } else {
890                 endPoint->SetSendUserInputMode(H323Connection::SendUserInputAsInlineRFC2833);
891         }
892 #if 0
893         if (cap & AST_FORMAT_SPEEX) {
894                 /* Not real sure if Asterisk acutally supports all
895                    of the various different bit rates so add them 
896                    all and figure it out later*/
897
898                 endPoint->SetCapability(0, 0, new SpeexNarrow2AudioCapability());
899                 endPoint->SetCapability(0, 0, new SpeexNarrow3AudioCapability());
900                 endPoint->SetCapability(0, 0, new SpeexNarrow4AudioCapability());
901                 endPoint->SetCapability(0, 0, new SpeexNarrow5AudioCapability());
902                 endPoint->SetCapability(0, 0, new SpeexNarrow6AudioCapability());
903         }
904 #endif 
905         if (cap & AST_FORMAT_G729A) {
906                 AST_G729ACapability *g729aCap;
907                 AST_G729Capability *g729Cap;
908                 endPoint->SetCapability(0, 0, g729aCap = new AST_G729ACapability);
909                 endPoint->SetCapability(0, 0, g729Cap = new AST_G729Capability);
910         }
911         
912         if (cap & AST_FORMAT_G723_1) {
913                 H323_G7231Capability *g7231Cap;
914                 endPoint->SetCapability(0, 0, g7231Cap = new H323_G7231Capability);
915         } 
916 #if 0
917         if (cap & AST_FORMAT_GSM) {
918                 H323_GSM0610Capability *gsmCap;
919                 endPoint->SetCapability(0, 0, gsmCap = new H323_GSM0610Capability);
920                 gsmCap->SetTxFramesInPacket(gsmFrames);
921         } 
922 #endif
923         if (cap & AST_FORMAT_ULAW) {
924                 H323_G711Capability *g711uCap;
925                 endPoint->SetCapability(0, 0, g711uCap = new H323_G711Capability(H323_G711Capability::muLaw));
926                 g711uCap->SetTxFramesInPacket(g711Frames);
927         } 
928
929         if (cap & AST_FORMAT_ALAW) {
930                 H323_G711Capability *g711aCap;
931                 endPoint->SetCapability(0, 0, g711aCap = new H323_G711Capability(H323_G711Capability::ALaw));
932                 g711aCap->SetTxFramesInPacket(g711Frames);
933         } 
934
935         if (h323debug) {
936                 cout <<  "Allowed Codecs:\n\t" << setprecision(2) << endPoint->GetCapabilities() << endl;
937         }
938         return 0;
939 }
940
941 /** Start the H.323 listener */
942 int h323_start_listener(int listenPort, struct sockaddr_in bindaddr)
943 {
944         
945         if (!h323_end_point_exist()) {
946                 cout << "ERROR: [h323_start_listener] No Endpoint, this is bad!" << endl;
947                 return 1;
948         }
949         
950         PIPSocket::Address interfaceAddress(bindaddr.sin_addr);
951
952         if (!listenPort) {
953                 listenPort = 1720;
954         }
955
956         /** H.323 listener */  
957         H323ListenerTCP *tcpListener;
958
959         tcpListener = new H323ListenerTCP(*endPoint, interfaceAddress, (WORD)listenPort);
960
961         if (!endPoint->StartListener(tcpListener)) {
962                 cout << "ERROR: Could not open H.323 listener port on " << ((H323ListenerTCP *) tcpListener)->GetListenerPort() << endl;
963                 delete tcpListener;
964                 return 1;
965                 
966         }
967         cout << "  == H.323 listener started" << endl;
968
969         return 0;
970 };
971  
972    
973 int h323_set_alias(struct oh323_alias *alias)
974 {
975         char *p;
976         char *num;
977         PString h323id(alias->name);
978         PString e164(alias->e164);
979         
980         if (!h323_end_point_exist()) {
981                 cout << "ERROR: [h323_set_alias] No Endpoint, this is bad!" << endl;
982                 return 1;
983         }
984
985         cout << "  == Adding alias \"" << h323id << "\" to endpoint" << endl;
986         endPoint->AddAliasName(h323id); 
987         endPoint->RemoveAliasName(localProcess->GetUserName());
988
989         if (!e164.IsEmpty()) {
990                 cout << "  == Adding E.164 \"" << e164 << "\" to endpoint" << endl;
991                 endPoint->AddAliasName(e164);
992         }
993         if (strlen(alias->prefix)) {
994                 p = alias->prefix;
995                 num = strsep(&p, ",");
996                 while(num) {
997                 cout << "  == Adding Prefix \"" << num << "\" to endpoint" << endl;
998                         endPoint->SupportedPrefixes += PString(num);
999                         endPoint->SetGateway();
1000                 num = strsep(&p, ",");          
1001                 }
1002         }
1003
1004         return 0;
1005 }
1006
1007
1008 void h323_set_id(char *id)
1009 {
1010         PString h323id(id);
1011
1012         if (h323debug) {
1013                 cout << "  == Using '" << h323id << "' as our H.323ID for this call" << endl;
1014         }
1015
1016         /* EVIL HACK */
1017         endPoint->SetLocalUserName(h323id);
1018 }
1019
1020 void h323_show_tokens(void)
1021 {
1022         cout << "Current call tokens: " << setprecision(2) << endPoint->GetAllConnections() << endl;
1023 }
1024
1025
1026 /** Establish Gatekeeper communiations, if so configured, 
1027   *     register aliases for the H.323 endpoint to respond to.
1028   */
1029 int h323_set_gk(int gatekeeper_discover, char *gatekeeper, char *secret)
1030 {
1031         PString gkName = PString(gatekeeper);
1032         PString pass   = PString(secret);
1033         H323TransportUDP *rasChannel;
1034
1035         if (!h323_end_point_exist()) {
1036                 cout << "ERROR: [h323_set_gk] No Endpoint, this is bad!" << endl;
1037                 return 1;
1038         }
1039
1040         if (!gatekeeper) {
1041                 cout << "Error: Gatekeeper cannot be NULL" << endl;
1042                 return 1;
1043         }
1044
1045         if (strlen(secret)) {
1046                 endPoint->SetGatekeeperPassword(pass);
1047         }
1048
1049         if (gatekeeper_discover) {
1050                 /* discover the gk using multicast */
1051                 if (endPoint->DiscoverGatekeeper(new H323TransportUDP(*endPoint))) {
1052                         cout << "  == Using " << (endPoint->GetGatekeeper())->GetName() << " as our Gatekeeper." << endl;
1053                 } else {
1054                         cout << "  *** Could not find a gatekeeper." << endl;
1055                         return 1;
1056                 }       
1057         } else {
1058                 rasChannel = new H323TransportUDP(*endPoint);
1059
1060                 if (!rasChannel) {
1061                         cout << "  *** No RAS Channel, this is bad" << endl;
1062                         return 1;
1063                 }
1064                 if (endPoint->SetGatekeeper(gkName, rasChannel)) {
1065                         cout << "  == Using " << (endPoint->GetGatekeeper())->GetName() << " as our Gatekeeper." << endl;
1066                 } else {
1067                         cout << "  *** Error registering with gatekeeper \"" << gkName << "\". " << endl;
1068                         
1069                         /* XXX Maybe we should fire a new thread to attempt to re-register later and not kill asterisk here? */
1070                         return 1;
1071                 }
1072         }
1073         
1074         return 0;
1075 }
1076
1077 /** Send a DTMF tone over the H323Connection with the
1078   * specified token.
1079   */
1080 void h323_send_tone(const char *call_token, char tone)
1081 {
1082         if (!h323_end_point_exist()) {
1083                 cout << "ERROR: [h323_send_tone] No Endpoint, this is bad!" << endl;
1084                 return;
1085         }
1086
1087         PString token = PString(call_token);
1088         endPoint->SendUserTone(token, tone);
1089 }
1090
1091 /** Make a call to the remote endpoint.
1092   */
1093 int h323_make_call(char *host, call_details_t *cd, call_options_t call_options)
1094 {
1095         int res;
1096         PString token;
1097         PString dest(host);
1098
1099         if (!h323_end_point_exist()) {
1100                 return 1;
1101         }
1102         res = endPoint->MakeCall(dest, token, &cd->call_reference, call_options.port, call_options.cid_num, call_options.cid_name);
1103         memcpy((char *)(cd->call_token), (const unsigned char *)token, token.GetLength());
1104         return res;
1105 };
1106
1107 int h323_clear_call(const char *call_token)
1108 {
1109         if (!h323_end_point_exist()) {
1110                 return 1;
1111         }
1112
1113         endPoint->ClearCall(PString(call_token));
1114         return 0;
1115 };
1116
1117 /* Send Alerting PDU to H.323 caller */
1118 int h323_send_alerting(const char *token)
1119 {
1120         const PString currentToken(token);
1121         H323Connection * connection;
1122
1123         connection = endPoint->FindConnectionWithLock(currentToken);
1124
1125         if (h323debug)
1126                 ast_verbose("\tSending alerting\n");
1127         
1128         if (!connection) {
1129                 cout << "No connection found for " << token << endl;
1130                 return -1;
1131         }
1132
1133         connection->AnsweringCall(H323Connection::AnswerCallPending);
1134         connection->Unlock();
1135
1136         return 0; 
1137
1138 }
1139
1140 /* Send Progress PDU to H.323 caller */
1141 int h323_send_progress(const char *token)
1142 {
1143         const PString currentToken(token);
1144         H323Connection * connection;
1145
1146         connection = endPoint->FindConnectionWithLock(currentToken);
1147
1148         if (!connection) {
1149                 cout << "No connection found for " << token << endl;
1150                 return -1;
1151         }
1152
1153         connection->AnsweringCall(H323Connection::AnswerCallDeferredWithMedia);
1154         connection->Unlock();
1155
1156         return 0;  
1157 }
1158
1159 /** This function tells the h.323 stack to either 
1160     answer or deny an incoming call  */
1161 int h323_answering_call(const char *token, int busy) 
1162 {
1163         const PString currentToken(token);
1164         H323Connection * connection;
1165         
1166         connection = endPoint->FindConnectionWithLock(currentToken);
1167         
1168         if (connection == NULL) {
1169                 cout << "No connection found for " << token << endl;
1170                 return -1;
1171         }
1172
1173         if (!busy) {
1174                 if (h323debug)
1175                         ast_verbose("\tanswering call\n");
1176                 connection->AnsweringCall(H323Connection::AnswerCallNow);
1177         } else {
1178                 if (h323debug)
1179                         ast_verbose("\tdenying call\n");
1180                 connection->AnsweringCall(H323Connection::AnswerCallDenied);
1181         }
1182         connection->Unlock();
1183         return 0;
1184 }
1185
1186
1187 int h323_show_codec(int fd, int argc, char *argv[])
1188 {
1189         cout <<  "Allowed Codecs:\n\t" << setprecision(2) << endPoint->GetCapabilities() << endl;
1190         return 0;
1191 }
1192
1193 int h323_soft_hangup(const char *data)
1194 {
1195         PString token(data);
1196         BOOL result;
1197         
1198         result = endPoint->ClearCall(token);    
1199         return result;
1200 }
1201
1202 /* alas, this doesn't work :(   */
1203 void h323_native_bridge(const char *token, const char *them, char *capability)
1204 {
1205         H323Channel *channel;
1206         MyH323Connection *connection = (MyH323Connection *)endPoint->FindConnectionWithLock(token);
1207         
1208         if (!connection){
1209                 cout << "ERROR: No connection found, this is bad\n";
1210                 return;
1211         }
1212
1213         cout << "Native Bridge:  them [" << them << "]" << endl; 
1214
1215         channel = connection->FindChannel(connection->sessionId, TRUE);
1216         connection->bridging = TRUE;
1217         connection->CloseLogicalChannelNumber(channel->GetNumber());
1218         
1219         connection->Unlock();
1220         return;
1221
1222 }
1223
1224 } /* extern "C" */
1225