finish implementing type=peer, implement setting of FastStart and H.245 Tunneling...
[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 *callerid, char *callername)
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 (callerid) {
246                 connection->SetLocalPartyName(PString(callerid));
247         }
248         if (callername) {
249                 localAliasNames.RemoveAll();
250                 connection->SetLocalPartyName(PString(callername));
251                 if (callerid) {
252                         localAliasNames.AppendString(PString(callerid));
253                 }
254         } else if (callerid) {
255                 localAliasNames.RemoveAll();
256                 connection->SetLocalPartyName(PString(callerid));
257         }
258         if (h323debug) {
259                 cout << "       -- " << GetLocalUserName() << " is calling host " << fullAddress << endl;
260                 cout << "       -- " << "Call token is " << (const char *)token << endl;
261                 cout << "       -- Call reference is " << *callReference << endl;
262         }
263         connection->Unlock();   
264         return 0;
265 }
266
267 void MyH323EndPoint::SetEndpointTypeInfo( H225_EndpointType & info ) const
268 {
269   H323EndPoint::SetEndpointTypeInfo(info);
270   info.m_gateway.IncludeOptionalField(H225_GatewayInfo::e_protocol);
271   info.m_gateway.m_protocol.SetSize(1);
272   H225_SupportedProtocols &protocol=info.m_gateway.m_protocol[0];
273   protocol.SetTag(H225_SupportedProtocols::e_voice);
274   PINDEX as=SupportedPrefixes.GetSize();
275   ((H225_VoiceCaps &)protocol).m_supportedPrefixes.SetSize(as);
276   for (PINDEX p=0; p<as; p++) {
277     H323SetAliasAddress(SupportedPrefixes[p], ((H225_VoiceCaps &)protocol).m_supportedPrefixes[p].m_prefix);
278   }
279 }
280
281 void MyH323EndPoint::SetGateway(void)
282 {
283         terminalType = e_GatewayOnly;
284 }
285
286 H323Capabilities MyH323EndPoint::GetCapabilities(void)
287 {
288         return capabilities;
289 }
290
291 BOOL MyH323EndPoint::ClearCall(const PString & token)
292 {
293         if (h323debug) {
294                 cout << "       -- ClearCall: Request to clear call with token " << token << endl;
295         }
296         return H323EndPoint::ClearCall(token);
297 }
298
299 void MyH323EndPoint::SendUserTone(const PString &token, char tone)
300 {
301         H323Connection *connection = NULL;
302                 
303         connection = FindConnectionWithLock(token);
304         if (connection != NULL) {
305                 connection->SendUserInputTone(tone, 500);
306                 connection->Unlock();
307         }
308 }
309
310 void MyH323EndPoint::OnClosedLogicalChannel(H323Connection & connection, const H323Channel & channel)
311 {
312         channelsOpen--;
313         if (h323debug)
314                 cout << "               channelsOpen = " << channelsOpen << endl;
315         H323EndPoint::OnClosedLogicalChannel(connection, channel);
316 }
317
318 BOOL MyH323EndPoint::OnConnectionForwarded(H323Connection & connection,
319                 const PString & forwardParty,
320                 const H323SignalPDU & pdu)
321  {
322         if (h323debug) {
323                 cout << "       -- Call Forwarded to " << forwardParty << endl;
324         }
325         return FALSE;
326  }
327  
328 BOOL MyH323EndPoint::ForwardConnection(H323Connection & connection,
329                 const PString & forwardParty,
330                 const H323SignalPDU & pdu)
331 {
332         if (h323debug) {
333                 cout << "       -- Forwarding call to " << forwardParty << endl;
334         }
335         return H323EndPoint::ForwardConnection(connection, forwardParty, pdu);
336 }
337
338 void MyH323EndPoint::OnConnectionEstablished(H323Connection & connection, const PString & estCallToken)
339 {
340         if (h323debug) {
341                 cout << "\t=-= In OnConnectionEstablished for call " << connection.GetCallReference() << endl;
342                 cout << "\t\t-- Connection Established with \"" << connection.GetRemotePartyName() << "\"" << endl;
343         }
344         on_connection_established(connection.GetCallReference(), (const char *)connection.GetCallToken());
345 }
346
347 /** OnConnectionCleared callback function is called upon the dropping of an established
348   * H323 connection. 
349   */
350 void MyH323EndPoint::OnConnectionCleared(H323Connection & connection, const PString & clearedCallToken)
351 {
352         PString remoteName;
353         call_details_t cd;
354         PIPSocket::Address Ip;
355         WORD sourcePort;
356
357         remoteName = connection.GetRemotePartyName();
358
359         cd.call_reference = connection.GetCallReference();
360         cd.call_token = strdup((const char *)clearedCallToken);
361         cd.call_source_aliases = strdup((const char *)connection.GetRemotePartyName());
362         
363         connection.GetSignallingChannel()->GetRemoteAddress().GetIpAndPort(Ip, sourcePort);
364         cd.sourceIp = strdup((const char *)Ip.AsString());
365         
366         /* Convert complex strings */
367         char *s;
368         if ((s = strchr(cd.call_source_aliases, ' ')) != NULL)
369                 *s = '\0';
370
371         switch (connection.GetCallEndReason()) {
372                 case H323Connection::EndedByCallForwarded :
373                         if (h323debug)
374                                 cout << " -- " << remoteName << " has forwarded the call" << endl;
375                         break;
376                 case H323Connection::EndedByRemoteUser :
377                         if (h323debug)
378                                 cout << " -- " << remoteName << " has cleared the call" << endl;
379                         break;
380                 case H323Connection::EndedByCallerAbort :
381                         if (h323debug)
382                                 cout << " -- " << remoteName << " has stopped calling" << endl;
383                         break;
384                 case H323Connection::EndedByRefusal :
385                         if (h323debug)
386                                 cout << " -- " << remoteName << " did not accept your call" << endl;
387                         break;
388                 case H323Connection::EndedByRemoteBusy :
389                         if (h323debug)
390                         cout << " -- " << remoteName << " was busy" << endl;
391                         break;
392                 case H323Connection::EndedByRemoteCongestion :
393                         if (h323debug)
394                                 cout << " -- Congested link to " << remoteName << endl;
395                         break;
396                 case H323Connection::EndedByNoAnswer :
397                         if (h323debug)
398                                 cout << " -- " << remoteName << " did not answer your call" << endl;
399                         break;
400                 case H323Connection::EndedByTransportFail :
401                         if (h323debug)
402                                 cout << " -- Call with " << remoteName << " ended abnormally" << endl;
403                         break;
404                 case H323Connection::EndedByCapabilityExchange :
405                         if (h323debug)
406                                 cout << " -- Could not find common codec with " << remoteName << endl;
407                         break;
408                 case H323Connection::EndedByNoAccept :
409                         if (h323debug)
410                                 cout << " -- Did not accept incoming call from " << remoteName << endl;
411                         break;
412                 case H323Connection::EndedByAnswerDenied :
413                         if (h323debug)
414                                 cout << " -- Refused incoming call from " << remoteName << endl;
415                         break;
416                 case H323Connection::EndedByNoUser :
417                         if (h323debug)
418                                 cout << " -- Remote endpoint could not find user: " << remoteName << endl;
419                         break;
420                 case H323Connection::EndedByNoBandwidth :
421                         if (h323debug)
422                                 cout << " -- Call to " << remoteName << " aborted, insufficient bandwidth." << endl;
423                         break;
424                 case H323Connection::EndedByUnreachable :
425                         if (h323debug)
426                                 cout << " -- " << remoteName << " could not be reached." << endl;
427                         break;
428                 case H323Connection::EndedByHostOffline :
429                         if (h323debug)
430                                 cout << " -- " << remoteName << " is not online." << endl;
431                         break;
432                 case H323Connection::EndedByNoEndPoint :
433                         if (h323debug)
434                                 cout << " -- No phone running for " << remoteName << endl;
435                         break;
436                 case H323Connection::EndedByConnectFail :
437                         if (h323debug)
438                                 cout << " -- Transport error calling " << remoteName << endl;
439                         break;
440                 default :
441                         if (h323debug)
442                                 cout << " -- Call with " << remoteName << " completed (" << connection.GetCallEndReason() << ")" << endl;
443
444         }
445
446         if(connection.IsEstablished()) 
447                 if (h323debug)
448                         cout << "        -- Call duration " << setprecision(0) << setw(5) << (PTime() - connection.GetConnectionStartTime()) << endl;
449
450         /* Invoke the PBX application registered callback */
451         on_connection_cleared(cd);
452
453         return;
454 }
455
456
457 H323Connection * MyH323EndPoint::CreateConnection(unsigned callReference, void *o)
458 {
459         unsigned options = 0;
460         call_options_t *opts = (call_options_t *)o;
461
462         if (opts && opts->noFastStart) {
463                 options |= H323Connection::FastStartOptionDisable;
464         } else {
465                 options |= H323Connection::FastStartOptionEnable;
466         }
467         if (opts && opts->noH245Tunneling) {
468                 options |= H323Connection::H245TunnelingOptionDisable;
469         } else {
470                 options |= H323Connection::H245TunnelingOptionEnable;
471         }
472 #if 0
473         if (opts->noSilenceSuppression) {
474                 options |= H323Connection::SilenceSuppresionOptionDisable;
475         } else {
476                 options |= H323Connection::SilenceSUppressionOptionEnable;
477         }
478 #endif
479         return new MyH323Connection(*this, callReference, options);
480 }
481
482 /* MyH323Connection */    
483 MyH323Connection::MyH323Connection(MyH323EndPoint & ep, unsigned callReference,
484                                                         unsigned options)
485         : H323Connection(ep, callReference, options)
486 {
487         if (h323debug) {
488                 cout << "       == New H.323 Connection created." << endl;
489         }
490         return;
491 }
492
493 MyH323Connection::~MyH323Connection()
494 {
495         if (h323debug) {
496                 cout << "       == H.323 Connection deleted." << endl;
497         }
498         return;
499 }
500
501 H323Connection::AnswerCallResponse MyH323Connection::OnAnswerCall(const PString & caller,
502                                                                   const H323SignalPDU & /*setupPDU*/,
503                                                                   H323SignalPDU & /*connectPDU*/)
504 {
505
506        if (h323debug)
507                cout << "\t=-= In OnAnswerCall for call " << GetCallReference() << endl;
508         
509         if (!on_answer_call(GetCallReference(), (const char *)GetCallToken())) {
510                 return H323Connection::AnswerCallDenied;
511         }
512         /* The call will be answered later with "AnsweringCall()" function.
513          */ 
514         return H323Connection::AnswerCallDeferred;
515 }
516
517 BOOL  MyH323Connection::OnAlerting(const H323SignalPDU & /*alertingPDU*/, const PString & username)
518 {
519         if (h323debug) {
520                 cout << "\t =-= In OnAlerting for call " << GetCallReference()
521                       << ": sessionId=" << sessionId << endl;
522                  cout << "       -- Ringing phone for \"" << username << "\"" << endl;
523         }     
524         on_chan_ringing(GetCallReference(), (const char *)GetCallToken() );
525         return TRUE;
526 }
527
528 BOOL MyH323Connection::OnReceivedSignalSetup(const H323SignalPDU & setupPDU)
529 {
530         
531         if (h323debug) {
532                 ast_verbose("   -- Received SETUP message\n");
533         }
534         
535         call_details_t cd;
536         PString sourceE164;
537         PString destE164;
538         PString sourceName;
539         PString sourceAliases;  
540         PString destAliases;
541         PIPSocket::Address Ip;
542         WORD sourcePort;
543         char *s, *s1; 
544
545         sourceAliases = setupPDU.GetSourceAliases();
546         destAliases = setupPDU.GetDestinationAlias();
547                         
548         sourceE164 = "";
549         setupPDU.GetSourceE164(sourceE164);
550         sourceName = "";
551         sourceName=setupPDU.GetQ931().GetDisplayName();
552         destE164 = "";
553         setupPDU.GetDestinationE164(destE164);
554
555         /* Convert complex strings */
556         //  FIXME: deal more than one source alias 
557         if ((s = strchr(sourceAliases, ' ')) != NULL)
558                 *s = '\0';
559         if ((s = strchr(sourceAliases, '\t')) != NULL)
560                 *s = '\0';
561         if ((s1 = strchr(destAliases, ' ')) != NULL)
562                 *s1 = '\0';
563         if ((s1 = strchr(destAliases, '\t')) != NULL)
564                 *s1 = '\0';
565
566
567         cd.call_reference = GetCallReference();
568         Lock();
569         cd.call_token = strdup((const char *)GetCallToken());
570         Unlock();
571         cd.call_source_aliases  =  strdup((const char *)sourceAliases);
572         cd.call_dest_alias = strdup((const char *)destAliases);
573         cd.call_source_e164 = strdup((const char *)sourceE164);
574         cd.call_dest_e164 = strdup((const char *)destE164);
575         cd.call_source_name = strdup((const char *)sourceName);
576
577         GetSignallingChannel()->GetRemoteAddress().GetIpAndPort(Ip, sourcePort);
578         cd.sourceIp = strdup((const char *)Ip.AsString());
579
580         /* Notify Asterisk of the request */
581         int res = on_incoming_call(cd); 
582
583         if (!res) {
584                 if (h323debug) {
585                         cout << "       -- Call Failed" << endl;
586                 }
587                 return FALSE;
588         }
589         
590         return H323Connection::OnReceivedSignalSetup(setupPDU);
591 }
592
593 BOOL MyH323Connection::OnSendSignalSetup(H323SignalPDU & setupPDU)
594 {
595         call_details_t cd;
596         char *s, *s1;
597
598         if (h323debug) { 
599                 cout << "       -- Sending SETUP message" << endl;
600         }
601         sourceAliases = setupPDU.GetSourceAliases();
602         destAliases = setupPDU.GetDestinationAlias();
603
604         sourceE164 = "";
605         setupPDU.GetSourceE164(sourceE164);
606         destE164 = "";
607         setupPDU.GetDestinationE164(destE164);
608
609         /* Convert complex strings */
610         //  FIXME: deal more than one source alias 
611         
612         if ((s = strchr(sourceAliases, ' ')) != NULL)
613                 *s = '\0';
614         if ((s = strchr(sourceAliases, '\t')) != NULL)
615                 *s = '\0';
616         if ((s1 = strchr(destAliases, ' ')) != NULL)
617                  *s1 = '\0';
618         if ((s1 = strchr(destAliases, '\t')) != NULL)
619                 *s1 = '\0';
620
621         cd.call_reference = GetCallReference();
622         Lock();
623         cd.call_token = strdup((const char *)GetCallToken());
624         Unlock();
625         cd.call_source_aliases = strdup((const char *)sourceAliases);
626         cd.call_dest_alias = strdup((const char *)destAliases);
627         cd.call_source_e164 = strdup((const char *)sourceE164);
628         cd.call_dest_e164 = strdup((const char *)destE164);
629
630         int res = on_outgoing_call(cd); 
631                 
632         if (!res) {
633                 if (h323debug) {
634                         cout << "       -- Call Failed" << endl;
635                 }
636                 return FALSE;
637         }
638
639         return H323Connection::OnSendSignalSetup(setupPDU);
640 }
641
642 BOOL MyH323Connection::OnSendReleaseComplete(H323SignalPDU & releaseCompletePDU)
643 {
644         if (h323debug) {
645                 cout << "       -- Sending RELEASE COMPLETE" << endl;
646         }
647         return H323Connection::OnSendReleaseComplete(releaseCompletePDU);
648 }
649
650 BOOL MyH323Connection::OnReceivedFacility(const H323SignalPDU & pdu)
651 {
652         if (h323debug) {
653                 cout << "       -- Received Facility message... " << endl;
654         }       
655         return H323Connection::OnReceivedFacility(pdu);
656 }
657
658 void MyH323Connection::OnReceivedReleaseComplete(const H323SignalPDU & pdu)
659 {
660         if (h323debug) {
661                 cout <<  "      -- Received RELEASE COMPLETE message..." << endl;
662         }
663         return H323Connection::OnReceivedReleaseComplete(pdu);
664 }
665
666 BOOL MyH323Connection::OnClosingLogicalChannel(H323Channel & channel)
667 {
668         if (h323debug) {
669                 cout << "       -- Closing logical channel..." << endl;
670         }
671         return H323Connection::OnClosingLogicalChannel(channel);
672 }
673
674
675 void MyH323Connection::SendUserInputTone(char tone, unsigned duration)
676 {
677         if (h323debug) {
678                 cout << "       -- Sending user input tone (" << tone << ") to remote" << endl;
679         }
680         on_send_digit(GetCallReference(), tone, (const char *)GetCallToken());  
681         H323Connection::SendUserInputTone(tone, duration);
682 }
683
684 void MyH323Connection::OnUserInputTone(char tone, unsigned duration, unsigned logicalChannel, unsigned rtpTimestamp)
685 {
686         if (mode == H323_DTMF_INBAND) {
687                 if (h323debug) {
688                         cout << "       -- Received user input tone (" << tone << ") from remote" << endl;
689                 }
690                 on_send_digit(GetCallReference(), tone, (const char *)GetCallToken());
691         }
692         H323Connection::OnUserInputTone(tone, duration, logicalChannel, rtpTimestamp);
693 }
694
695 void MyH323Connection::OnUserInputString(const PString &value)
696 {
697         if (mode == H323_DTMF_RFC2833) {
698                 if (h323debug) {
699                         cout <<  "      -- Received user input string (" << value << ") from remote." << endl;
700                 }
701                 on_send_digit(GetCallReference(), value[0], (const char *)GetCallToken());
702         }       
703 }
704
705 H323Channel * MyH323Connection::CreateRealTimeLogicalChannel(const H323Capability & capability, 
706                                                                    H323Channel::Directions dir,
707                                                                    unsigned sessionID,
708                                                                    const H245_H2250LogicalChannelParameters * /*param*/,
709                                                                    RTP_QOS * /*param*/ )
710 {
711         return new MyH323_ExternalRTPChannel(*this, capability, dir, sessionID);
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 << "\t-- 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
725         /* adjust the count of channels we have open */
726         channelsOpen++;
727
728         if (h323debug) {
729                 cout <<  "\t\t-- channelsOpen = " << channelsOpen << endl;
730         }
731
732         return TRUE;    
733 }
734
735 /* MyH323_ExternalRTPChannel */
736 MyH323_ExternalRTPChannel::MyH323_ExternalRTPChannel(MyH323Connection & connection,
737                                                      const H323Capability & capability,
738                                                      Directions direction,
739                                                      unsigned id)
740  : H323_ExternalRTPChannel::H323_ExternalRTPChannel(connection, capability, direction, id)
741 {   
742         struct rtp_info *info;
743
744         /* Determine the Local (A side) IP Address and port */
745         info = on_external_rtp_create(connection.GetCallReference(), (const char *)connection.GetCallToken()); 
746         if (!info) {
747                 cout << "\tERROR: on_external_rtp_create failure" << endl;
748                 return;
749         } else {
750                 localIpAddr = (PIPSocket::Address)info->addr;
751                 localPort = (WORD)info->port;
752                 /* tell the H.323 stack  */ 
753                 SetExternalAddress(H323TransportAddress(localIpAddr, localPort), H323TransportAddress(localIpAddr, localPort + 1));
754                 /* clean up allocated memory */
755                 free(info);
756         }
757
758         // Get the payload code 
759         OpalMediaFormat format(capability.GetFormatName(), FALSE);
760         payloadCode = format.GetPayloadType();
761
762
763 MyH323_ExternalRTPChannel::~MyH323_ExternalRTPChannel() 
764 {
765         if (h323debug) {
766                 cout << "\tExternalRTPChannel Destroyed" << endl;
767         }
768 }
769
770 BOOL MyH323_ExternalRTPChannel::Start(void)
771 {
772         /* Call ancestor first */
773         if (!H323_ExternalRTPChannel::Start()) {
774                 return FALSE;
775         }
776
777         /* Collect the remote information */
778         GetRemoteAddress(remoteIpAddr, remotePort);
779
780         if (h323debug) {
781                 cout << "\t\tExternal RTP Session Starting" << endl;
782                 cout << "\t\tRTP channel id " << sessionID << " parameters:" << endl;
783                 cout << "\t\t-- remoteIpAddress: " << remoteIpAddr << endl;
784                 cout << "\t\t-- remotePort: " << remotePort << endl;
785                 cout << "\t\t-- ExternalIpAddress: " <<  localIpAddr << endl;
786                 cout << "\t\t-- ExternalPort: " << localPort << endl;
787         }
788
789         /* Notify Asterisk of remote RTP information */
790         on_start_rtp_channel(connection.GetCallReference(), (const char *)remoteIpAddr.AsString(), remotePort, 
791                 (const char *)connection.GetCallToken());
792         return TRUE;
793 }
794
795 /** IMPLEMENTATION OF C FUNCTIONS */
796
797 /**
798  * The extern "C" directive takes care for 
799  * the ANSI-C representation of linkable symbols 
800  */
801
802 extern "C" {
803
804 int h323_end_point_exist(void)
805 {
806         if (!endPoint) {
807                 return 0;
808         }
809         return 1;
810 }
811     
812 void h323_end_point_create(void)
813 {
814         channelsOpen = 0;
815         localProcess = new MyProcess(); 
816         localProcess->Main();
817 }
818
819 void h323_gk_urq(void)
820 {
821         if (!h323_end_point_exist()) {
822                 cout << " ERROR: [h323_gk_urq] No Endpoint, this is bad" << endl;
823                 return;
824         }       
825         endPoint->RemoveGatekeeper();
826 }
827
828 void h323_end_process(void)
829 {
830         endPoint->ClearAllCalls();
831         endPoint->RemoveListener(NULL);
832         delete endPoint;
833         delete localProcess;
834 }
835
836 void h323_debug(int flag, unsigned level)
837 {
838         if (flag) {
839                 PTrace:: SetLevel(level); 
840         } else { 
841                 PTrace:: SetLevel(0); 
842         }
843 }
844         
845 /** Installs the callback functions on behalf of the PBX application  */
846 void h323_callback_register(setup_incoming_cb   ifunc,
847                             setup_outbound_cb   sfunc,
848                             on_rtp_cb           rtpfunc,
849                             start_rtp_cb        lfunc,
850                             clear_con_cb        clfunc,
851                             chan_ringing_cb     rfunc,
852                             con_established_cb  efunc,
853                             send_digit_cb       dfunc,
854                             answer_call_cb      acfunc)
855 {
856         on_incoming_call = ifunc;
857         on_outgoing_call = sfunc;
858         on_external_rtp_create = rtpfunc;
859         on_start_rtp_channel = lfunc;
860         on_connection_cleared = clfunc;
861         on_chan_ringing = rfunc;
862         on_connection_established = efunc;
863         on_send_digit = dfunc;
864         on_answer_call = acfunc;
865 }
866
867 /**
868  * Add capability to the capability table of the end point. 
869  */
870 int h323_set_capability(int cap, int dtmfMode)
871 {
872         H323Capabilities oldcaps;
873         PStringArray codecs;
874         int g711Frames = 30;
875 //      int gsmFrames  = 4;
876
877         if (!h323_end_point_exist()) {
878                 cout << " ERROR: [h323_set_capablity] No Endpoint, this is bad" << endl;
879                 return 1;
880         }
881
882         /* clean up old capabilities list before changing */
883         oldcaps = endPoint->GetCapabilities();
884         for (PINDEX i=0; i< oldcaps.GetSize(); i++) {
885                  codecs.AppendString(oldcaps[i].GetFormatName());
886          }
887          endPoint->RemoveCapabilities(codecs);
888
889         mode = dtmfMode;
890         if (dtmfMode == H323_DTMF_INBAND) {
891             endPoint->SetSendUserInputMode(H323Connection::SendUserInputAsTone);
892         } else {
893                 endPoint->SetSendUserInputMode(H323Connection::SendUserInputAsInlineRFC2833);
894         }
895 #if 0
896         if (cap & AST_FORMAT_SPEEX) {
897                 /* Not real sure if Asterisk acutally supports all
898                    of the various different bit rates so add them 
899                    all and figure it out later*/
900
901                 endPoint->SetCapability(0, 0, new SpeexNarrow2AudioCapability());
902                 endPoint->SetCapability(0, 0, new SpeexNarrow3AudioCapability());
903                 endPoint->SetCapability(0, 0, new SpeexNarrow4AudioCapability());
904                 endPoint->SetCapability(0, 0, new SpeexNarrow5AudioCapability());
905                 endPoint->SetCapability(0, 0, new SpeexNarrow6AudioCapability());
906         }
907 #endif 
908         if (cap & AST_FORMAT_G729A) {
909                 AST_G729ACapability *g729aCap;
910                 AST_G729Capability *g729Cap;
911                 endPoint->SetCapability(0, 0, g729aCap = new AST_G729ACapability);
912                 endPoint->SetCapability(0, 0, g729Cap = new AST_G729Capability);
913         }
914         
915         if (cap & AST_FORMAT_G723_1) {
916                 H323_G7231Capability *g7231Cap;
917                 endPoint->SetCapability(0, 0, g7231Cap = new H323_G7231Capability);
918         } 
919 #if 0
920         if (cap & AST_FORMAT_GSM) {
921                 H323_GSM0610Capability *gsmCap;
922                 endPoint->SetCapability(0, 0, gsmCap = new H323_GSM0610Capability);
923                 gsmCap->SetTxFramesInPacket(gsmFrames);
924         } 
925 #endif
926         if (cap & AST_FORMAT_ULAW) {
927                 H323_G711Capability *g711uCap;
928                 endPoint->SetCapability(0, 0, g711uCap = new H323_G711Capability(H323_G711Capability::muLaw));
929                 g711uCap->SetTxFramesInPacket(g711Frames);
930         } 
931
932         if (cap & AST_FORMAT_ALAW) {
933                 H323_G711Capability *g711aCap;
934                 endPoint->SetCapability(0, 0, g711aCap = new H323_G711Capability(H323_G711Capability::ALaw));
935                 g711aCap->SetTxFramesInPacket(g711Frames);
936         } 
937
938         if (h323debug) {
939                 cout <<  "Allowed Codecs:\n\t" << setprecision(2) << endPoint->GetCapabilities() << endl;
940         }
941         return 0;
942 }
943
944 /** Start the H.323 listener */
945 int h323_start_listener(int listenPort, struct sockaddr_in bindaddr)
946 {
947         
948         if (!h323_end_point_exist()) {
949                 cout << "ERROR: [h323_start_listener] No Endpoint, this is bad!" << endl;
950                 return 1;
951         }
952         
953         PIPSocket::Address interfaceAddress(bindaddr.sin_addr);
954
955         if (!listenPort) {
956                 listenPort = 1720;
957         }
958
959         /** H.323 listener */  
960         H323ListenerTCP *tcpListener;
961
962         tcpListener = new H323ListenerTCP(*endPoint, interfaceAddress, (WORD)listenPort);
963
964         if (!endPoint->StartListener(tcpListener)) {
965                 cout << "ERROR: Could not open H.323 listener port on " << ((H323ListenerTCP *) tcpListener)->GetListenerPort() << endl;
966                 delete tcpListener;
967                 return 1;
968                 
969         }
970         cout << "  == H.323 listener started" << endl;
971
972         return 0;
973 };
974  
975    
976 int h323_set_alias(struct oh323_alias *alias)
977 {
978         char *p;
979         char *num;
980         PString h323id(alias->name);
981         PString e164(alias->e164);
982         
983         if (!h323_end_point_exist()) {
984                 cout << "ERROR: [h323_set_alias] No Endpoint, this is bad!" << endl;
985                 return 1;
986         }
987
988         cout << "  == Adding alias \"" << h323id << "\" to endpoint" << endl;
989         endPoint->AddAliasName(h323id); 
990         endPoint->RemoveAliasName(localProcess->GetUserName());
991
992         if (!e164.IsEmpty()) {
993                 cout << "  == Adding E.164 \"" << e164 << "\" to endpoint" << endl;
994                 endPoint->AddAliasName(e164);
995         }
996         if (strlen(alias->prefix)) {
997                 p = alias->prefix;
998                 num = strsep(&p, ",");
999                 while(num) {
1000                 cout << "  == Adding Prefix \"" << num << "\" to endpoint" << endl;
1001                         endPoint->SupportedPrefixes += PString(num);
1002                         endPoint->SetGateway();
1003                 num = strsep(&p, ",");          
1004                 }
1005         }
1006
1007         return 0;
1008 }
1009
1010
1011 void h323_set_id(char *id)
1012 {
1013         PString h323id(id);
1014
1015         if (h323debug) {
1016                 cout << "  == Using '" << h323id << "' as our H.323ID for this call" << endl;
1017         }
1018
1019         /* EVIL HACK */
1020         endPoint->SetLocalUserName(h323id);
1021 }
1022
1023 void h323_show_tokens(void)
1024 {
1025         cout << "Current call tokens: " << setprecision(2) << endPoint->GetAllConnections() << endl;
1026 }
1027
1028
1029 /** Establish Gatekeeper communiations, if so configured, 
1030   *     register aliases for the H.323 endpoint to respond to.
1031   */
1032 int h323_set_gk(int gatekeeper_discover, char *gatekeeper, char *secret)
1033 {
1034         PString gkName = PString(gatekeeper);
1035         PString pass   = PString(secret);
1036         H323TransportUDP *rasChannel;
1037
1038         if (!h323_end_point_exist()) {
1039                 cout << "ERROR: [h323_set_gk] No Endpoint, this is bad!" << endl;
1040                 return 1;
1041         }
1042
1043         if (!gatekeeper) {
1044                 cout << "Error: Gatekeeper cannot be NULL" << endl;
1045                 return 1;
1046         }
1047
1048         if (strlen(secret)) {
1049                 endPoint->SetGatekeeperPassword(pass);
1050         }
1051
1052         if (gatekeeper_discover) {
1053                 /* discover the gk using multicast */
1054                 if (endPoint->DiscoverGatekeeper(new H323TransportUDP(*endPoint))) {
1055                         cout << "  == Using " << (endPoint->GetGatekeeper())->GetName() << " as our Gatekeeper." << endl;
1056                 } else {
1057                         cout << "  *** Could not find a gatekeeper." << endl;
1058                         return 1;
1059                 }       
1060         } else {
1061                 rasChannel = new H323TransportUDP(*endPoint);
1062
1063                 if (!rasChannel) {
1064                         cout << "  *** No RAS Channel, this is bad" << endl;
1065                         return 1;
1066                 }
1067                 if (endPoint->SetGatekeeper(gkName, rasChannel)) {
1068                         cout << "  == Using " << (endPoint->GetGatekeeper())->GetName() << " as our Gatekeeper." << endl;
1069                 } else {
1070                         cout << "  *** Error registering with gatekeeper \"" << gkName << "\". " << endl;
1071                         
1072                         /* XXX Maybe we should fire a new thread to attempt to re-register later and not kill asterisk here? */
1073                         return 1;
1074                 }
1075         }
1076         
1077         return 0;
1078 }
1079
1080 /** Send a DTMF tone over the H323Connection with the
1081   * specified token.
1082   */
1083 void h323_send_tone(const char *call_token, char tone)
1084 {
1085         if (!h323_end_point_exist()) {
1086                 cout << "ERROR: [h323_send_tone] No Endpoint, this is bad!" << endl;
1087                 return;
1088         }
1089
1090         PString token = PString(call_token);
1091         endPoint->SendUserTone(token, tone);
1092 }
1093
1094 /** Make a call to the remote endpoint.
1095   */
1096 int h323_make_call(char *host, call_details_t *cd, call_options_t call_options)
1097 {
1098         int res;
1099         PString token;
1100         PString dest(host);
1101
1102         if (!h323_end_point_exist()) {
1103                 return 1;
1104         }
1105         res = endPoint->MakeCall(dest, token, &cd->call_reference, call_options.port, call_options.callerid, call_options.callername);
1106         memcpy((char *)(cd->call_token), (const unsigned char *)token, token.GetLength());
1107         return res;
1108 };
1109
1110 int h323_clear_call(const char *call_token)
1111 {
1112         if (!h323_end_point_exist()) {
1113                 return 1;
1114         }
1115
1116         endPoint->ClearCall(PString(call_token));
1117         return 0;
1118 };
1119
1120 /* Send Alerting PDU to H.323 caller */
1121 int h323_send_alerting(const char *token)
1122 {
1123         const PString currentToken(token);
1124         H323Connection * connection;
1125
1126         connection = endPoint->FindConnectionWithLock(currentToken);
1127
1128         if (h323debug)
1129                 ast_verbose("\tSending alerting\n");
1130         
1131         if (!connection) {
1132                 cout << "No connection found for " << token << endl;
1133                 return -1;
1134         }
1135
1136         connection->AnsweringCall(H323Connection::AnswerCallPending);
1137         connection->Unlock();
1138
1139         return 0; 
1140
1141 }
1142
1143 /* Send Progress PDU to H.323 caller */
1144 int h323_send_progress(const char *token)
1145 {
1146         const PString currentToken(token);
1147         H323Connection * connection;
1148
1149         connection = endPoint->FindConnectionWithLock(currentToken);
1150
1151         if (!connection) {
1152                 cout << "No connection found for " << token << endl;
1153                 return -1;
1154         }
1155
1156         connection->AnsweringCall(H323Connection::AnswerCallDeferredWithMedia);
1157         connection->Unlock();
1158
1159         return 0;  
1160 }
1161
1162 /** This function tells the h.323 stack to either 
1163     answer or deny an incoming call  */
1164 int h323_answering_call(const char *token, int busy) 
1165 {
1166         const PString currentToken(token);
1167         H323Connection * connection;
1168         
1169         connection = endPoint->FindConnectionWithLock(currentToken);
1170         
1171         if (connection == NULL) {
1172                 cout << "No connection found for " << token << endl;
1173                 return -1;
1174         }
1175
1176         if (!busy) {
1177                 if (h323debug)
1178                         ast_verbose("\tanswering call\n");
1179                 connection->AnsweringCall(H323Connection::AnswerCallNow);
1180         } else {
1181                 if (h323debug)
1182                         ast_verbose("\tdenying call\n");
1183                 connection->AnsweringCall(H323Connection::AnswerCallDenied);
1184         }
1185         connection->Unlock();
1186         return 0;
1187 }
1188
1189
1190 int h323_show_codec(int fd, int argc, char *argv[])
1191 {
1192         cout <<  "Allowed Codecs:\n\t" << setprecision(2) << endPoint->GetCapabilities() << endl;
1193         return 0;
1194 }
1195
1196 int h323_soft_hangup(const char *data)
1197 {
1198         PString token(data);
1199         BOOL result;
1200         
1201         result = endPoint->ClearCall(token);    
1202         return result;
1203 }
1204
1205 /* alas, this doesn't work :(   */
1206 void h323_native_bridge(const char *token, const char *them, char *capability)
1207 {
1208         H323Channel *channel;
1209         MyH323Connection *connection = (MyH323Connection *)endPoint->FindConnectionWithLock(token);
1210         
1211         if (!connection){
1212                 cout << "ERROR: No connection found, this is bad\n";
1213                 return;
1214         }
1215
1216         cout << "Native Bridge:  them [" << them << "]" << endl; 
1217
1218         channel = connection->FindChannel(connection->sessionId, TRUE);
1219         connection->bridging = TRUE;
1220         connection->CloseLogicalChannelNumber(channel->GetNumber());
1221         
1222         connection->Unlock();
1223         return;
1224
1225 }
1226
1227 } /* extern "C" */
1228