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