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