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