3c1a56c4b55af092f042aebf7f1b302ff28a2baa
[asterisk/asterisk.git] / channels / h323 / ast_h323.cxx
1 #ifndef _GNU_SOURCE
2 #define _GNU_SOURCE
3 #endif
4 /*
5  * ast_h323.cpp
6  *
7  * OpenH323 Channel Driver for ASTERISK PBX.
8  *                      By  Jeremy McNamara
9  *                      For The NuFone Network
10  *
11  * chan_h323 has been derived from code created by
12  *               Michael Manousos and Mark Spencer
13  *
14  * This file is part of the chan_h323 driver for Asterisk
15  *
16  * chan_h323 is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 2 of the License, or
19  * (at your option) any later version.
20  *
21  * chan_h323 is distributed WITHOUT ANY WARRANTY; without even
22  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
23  * PURPOSE. See the GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28  *
29  * Version Info: $Id$
30  */
31 #include <arpa/inet.h>
32
33 #include <list>
34 #include <string>
35 #include <algorithm>
36
37 #include <ptlib.h>
38 #include <h323.h>
39 #include <h323pdu.h>
40 #include <h323neg.h>
41 #include <mediafmt.h>
42 #include <lid.h>
43 #ifdef H323_H450
44 #include "h4501.h"
45 #include "h4504.h"
46 #include "h45011.h"
47 #include "h450pdu.h"
48 #endif
49
50 #ifdef __cplusplus
51 extern "C" {
52 #endif
53 #include "asterisk/logger.h"
54 #include "asterisk/channel.h"
55 #include "asterisk/astobj.h"
56 #ifdef __cplusplus
57 }
58 #endif
59
60 #include "chan_h323.h"
61 #include "ast_h323.h"
62 #include "cisco-h225.h"
63 #include "caps_h323.h"
64
65 /* PWlib Required Components  */
66 #define MAJOR_VERSION 1
67 #define MINOR_VERSION 0
68 #define BUILD_TYPE    ReleaseCode
69 #define BUILD_NUMBER  0
70
71 /** Counter for the number of connections */
72 static int channelsOpen;
73
74 /**
75  * We assume that only one endPoint should exist.
76  * The application cannot run the h323_end_point_create() more than once
77  * FIXME: Singleton this, for safety
78  */
79 static MyH323EndPoint *endPoint = NULL;
80
81 /** PWLib entry point */
82 static MyProcess *localProcess = NULL;
83
84 static int _timerChangePipe[2];
85
86 static unsigned traceOptions = PTrace::Timestamp | PTrace::Thread | PTrace::FileAndLine;
87
88 class PAsteriskLog : public PObject, public iostream {
89         PCLASSINFO(PAsteriskLog, PObject);
90
91         public:
92         PAsteriskLog() : iostream(cout.rdbuf()) { init(&buffer); }
93         ~PAsteriskLog() { flush(); }
94
95         private:
96         PAsteriskLog(const PAsteriskLog &) : iostream(cout.rdbuf()) { }
97         PAsteriskLog & operator=(const PAsteriskLog &) { return *this; }
98
99         class Buffer : public streambuf {
100                 public:
101                 virtual int overflow(int=EOF);
102                 virtual int underflow();
103                 virtual int sync();
104                 PString string;
105         } buffer;
106         friend class Buffer;
107 };
108
109 static PAsteriskLog *logstream = NULL;
110
111 int PAsteriskLog::Buffer::overflow(int c)
112 {
113         if (pptr() >= epptr()) {
114                 int ppos = pptr() - pbase();
115                 char *newptr = string.GetPointer(string.GetSize() + 2000);
116                 setp(newptr, newptr + string.GetSize() - 1);
117                 pbump(ppos);
118         }
119         if (c != EOF) {
120                 *pptr() = (char)c;
121                 pbump(1);
122         }
123         return 0;
124 }
125
126 int PAsteriskLog::Buffer::underflow()
127 {
128         return EOF;
129 }
130
131 int PAsteriskLog::Buffer::sync()
132 {
133         char *str = strdup(string);
134         char *s, *s1;
135         char c;
136
137         /* Pass each line with different ast_verbose() call */
138         for (s = str; s && *s; s = s1) {
139                 s1 = strchr(s, '\n');
140                 if (!s1)
141                         s1 = s + strlen(s);
142                 else
143                         s1++;
144                 c = *s1;
145                 *s1 = '\0';
146                 ast_verbose("%s", s);
147                 *s1 = c;
148         }
149         free(str);
150
151         string = PString();
152         char *base = string.GetPointer(2000);
153         setp(base, base + string.GetSize() - 1);
154         return 0;
155 }
156
157 static ostream &my_endl(ostream &os)
158 {
159         if (logstream) {
160                 PTrace::SetOptions(traceOptions);
161                 return PTrace::End(os);
162         }
163         return endl(os);
164 }
165
166 #define cout \
167         (logstream ? (PTrace::ClearOptions((unsigned)-1), PTrace::Begin(0, __FILE__, __LINE__)) : std::cout)
168 #define endl my_endl
169
170 /* Special class designed to call cleanup code on module destruction */
171 class MyH323_Shutdown {
172         public:
173         MyH323_Shutdown() { };
174         ~MyH323_Shutdown()
175         {
176                 h323_end_process();
177         };
178 };
179
180 MyProcess::MyProcess(): PProcess("The NuFone Network's",
181                         "H.323 Channel Driver for Asterisk",
182                         MAJOR_VERSION, MINOR_VERSION, BUILD_TYPE, BUILD_NUMBER)
183 {
184         /* Call shutdown when module being unload or asterisk has been stopped */
185         static MyH323_Shutdown x;
186
187         /* Fix missed one in PWLib */
188         PX_firstTimeStart = FALSE;
189         Resume();
190 }
191
192 MyProcess::~MyProcess()
193 {
194         _timerChangePipe[0] = timerChangePipe[0];
195         _timerChangePipe[1] = timerChangePipe[1];
196 }
197
198 void MyProcess::Main()
199 {
200         PTrace::Initialise(PTrace::GetLevel(), NULL, traceOptions);
201         PTrace::SetStream(logstream);
202
203         cout << "  == Creating H.323 Endpoint" << endl;
204         if (endPoint) {
205                 cout << "  == ENDPOINT ALREADY CREATED" << endl;
206                 return;
207         }
208         endPoint = new MyH323EndPoint();
209         /* Due to a bug in the H.323 recomendation/stack we should request a sane
210            amount of bandwidth from the GK - this function is ignored if not using a GK
211            We are requesting 128 (64k in each direction), which is the worst case codec. */
212         endPoint->SetInitialBandwidth(1280);
213 }
214
215 void PAssertFunc(const char *msg)
216 {
217         ast_log(LOG_ERROR, "%s\n", msg);
218         /* XXX: Probably we need to crash here */
219 }
220
221
222 /** MyH323EndPoint
223   */
224 MyH323EndPoint::MyH323EndPoint()
225                 : H323EndPoint()
226 {
227         /* Capabilities will be negotiated on per-connection basis */
228         capabilities.RemoveAll();
229
230         /* Reset call setup timeout to some more reasonable value than 1 minute */
231         signallingChannelCallTimeout = PTimeInterval(0, 0, 10); /* 10 minutes */
232 }
233
234 /** The fullAddress parameter is used directly in the MakeCall method so
235   * the General form for the fullAddress argument is :
236   * [alias@][transport$]host[:port]
237   * default values:     alias = the same value as host.
238   *                                     transport = ip.
239   *                                     port = 1720.
240   */
241 int MyH323EndPoint::MyMakeCall(const PString & dest, PString & token, void *_callReference, void *_opts)
242 {
243         PString fullAddress;
244         MyH323Connection * connection;
245         H323Transport *transport = NULL;
246         unsigned int *callReference = (unsigned int *)_callReference;
247         call_options_t *opts = (call_options_t *)_opts;
248
249         /* Determine whether we are using a gatekeeper or not. */
250         if (GetGatekeeper()) {
251                 fullAddress = dest;
252                 if (h323debug) {
253                         cout << " -- Making call to " << fullAddress << " using gatekeeper." << endl;
254                 }
255         } else {
256                 fullAddress = dest;
257                 if (h323debug) {
258                         cout << " -- Making call to " << fullAddress << " without gatekeeper." << endl;
259                 }
260                 /* Use bindaddr for outgoing calls too if we don't use gatekeeper */
261                 if (listeners.GetSize() > 0) {
262                         H323TransportAddress taddr = listeners[0].GetTransportAddress();
263                         PIPSocket::Address addr;
264                         WORD port;
265                         if (taddr.GetIpAndPort(addr, port)) {
266                                 /* Create own transport for specific addresses only */
267                                 if (addr) {
268                                         if (h323debug)
269                                                 cout << "Using " << addr << " for outbound call" << endl;
270                                         transport = new MyH323TransportTCP(*this, addr);
271                                         if (!transport)
272                                                 cout << "Unable to create transport for outgoing call" << endl;
273                                 }
274                         } else
275                                 cout << "Unable to get address and port" << endl;
276                 }
277         }
278         if (!(connection = (MyH323Connection *)H323EndPoint::MakeCallLocked(fullAddress, token, opts, transport))) {
279                 if (h323debug) {
280                         cout << "Error making call to \"" << fullAddress << '"' << endl;
281                 }
282                 return 1;
283         }
284         *callReference = connection->GetCallReference();
285
286         if (h323debug) {
287                 cout << "\t-- " << GetLocalUserName() << " is calling host " << fullAddress << endl;
288                 cout << "\t-- Call token is " << (const char *)token << endl;
289                 cout << "\t-- Call reference is " << *callReference << endl;
290                 cout << "\t-- DTMF Payload is " << connection->dtmfCodec << endl;
291         }
292         connection->Unlock();
293         return 0;
294 }
295
296 void MyH323EndPoint::SetEndpointTypeInfo( H225_EndpointType & info ) const
297 {
298         H323EndPoint::SetEndpointTypeInfo(info);
299
300         if (terminalType == e_GatewayOnly){
301                 info.RemoveOptionalField(H225_EndpointType::e_terminal);
302                 info.IncludeOptionalField(H225_EndpointType::e_gateway);
303         }
304
305         info.m_gateway.IncludeOptionalField(H225_GatewayInfo::e_protocol);
306         info.m_gateway.m_protocol.SetSize(1);
307         H225_SupportedProtocols &protocol=info.m_gateway.m_protocol[0];
308         protocol.SetTag(H225_SupportedProtocols::e_voice);
309         PINDEX as=SupportedPrefixes.GetSize();
310         ((H225_VoiceCaps &)protocol).m_supportedPrefixes.SetSize(as);
311         for (PINDEX p=0; p<as; p++) {
312                 H323SetAliasAddress(SupportedPrefixes[p], ((H225_VoiceCaps &)protocol).m_supportedPrefixes[p].m_prefix, H225_AliasAddress::e_dialedDigits);
313         }
314 }
315
316 void MyH323EndPoint::SetGateway(void)
317 {
318         terminalType = e_GatewayOnly;
319 }
320
321 BOOL MyH323EndPoint::ClearCall(const PString & token, H323Connection::CallEndReason reason)
322 {
323         if (h323debug) {
324 #ifdef PTRACING
325                 cout << "\t-- ClearCall: Request to clear call with token " << token << ", cause " << reason << endl;
326 #else
327                 cout << "\t-- ClearCall: Request to clear call with token " << token << ", cause [" << (int)reason << "]" << endl;
328 #endif
329         }
330         return H323EndPoint::ClearCall(token, reason);
331 }
332
333 BOOL MyH323EndPoint::ClearCall(const PString & token)
334 {
335         if (h323debug) {
336                 cout << "\t-- ClearCall: Request to clear call with token " << token << endl;
337         }
338         return H323EndPoint::ClearCall(token, H323Connection::EndedByLocalUser);
339 }
340
341 void MyH323EndPoint::SendUserTone(const PString &token, char tone)
342 {
343         H323Connection *connection = NULL;
344
345         connection = FindConnectionWithLock(token);
346         if (connection != NULL) {
347                 connection->SendUserInputTone(tone, 500);
348                 connection->Unlock();
349         }
350 }
351
352 void MyH323EndPoint::OnClosedLogicalChannel(H323Connection & connection, const H323Channel & channel)
353 {
354         channelsOpen--;
355         if (h323debug) {
356                 cout << "\t\tchannelsOpen = " << channelsOpen << endl;
357         }
358         H323EndPoint::OnClosedLogicalChannel(connection, channel);
359 }
360
361 BOOL MyH323EndPoint::OnConnectionForwarded(H323Connection & connection,
362                 const PString & forwardParty,
363                 const H323SignalPDU & pdu)
364 {
365         if (h323debug) {
366                 cout << "\t-- Call Forwarded to " << forwardParty << endl;
367         }
368         return FALSE;
369 }
370
371 BOOL MyH323EndPoint::ForwardConnection(H323Connection & connection,
372                 const PString & forwardParty,
373                 const H323SignalPDU & pdu)
374 {
375         if (h323debug) {
376                 cout << "\t-- Forwarding call to " << forwardParty << endl;
377         }
378         return H323EndPoint::ForwardConnection(connection, forwardParty, pdu);
379 }
380
381 void MyH323EndPoint::OnConnectionEstablished(H323Connection & connection, const PString & estCallToken)
382 {
383         if (h323debug) {
384                 cout << "\t=-= In OnConnectionEstablished for call " << connection.GetCallReference() << endl;
385                 cout << "\t\t-- Connection Established with \"" << connection.GetRemotePartyName() << "\"" << endl;
386         }
387         on_connection_established(connection.GetCallReference(), (const char *)connection.GetCallToken());
388 }
389
390 /** OnConnectionCleared callback function is called upon the dropping of an established
391   * H323 connection.
392   */
393 void MyH323EndPoint::OnConnectionCleared(H323Connection & connection, const PString & clearedCallToken)
394 {
395         PString remoteName = connection.GetRemotePartyName();
396
397         switch (connection.GetCallEndReason()) {
398                 case H323Connection::EndedByCallForwarded:
399                         if (h323debug) {
400                                 cout << "-- " << remoteName << " has forwarded the call" << endl;
401                         }
402                         break;
403                 case H323Connection::EndedByRemoteUser:
404                         if (h323debug) {
405                                 cout << "-- " << remoteName << " has cleared the call" << endl;
406                         }
407                         break;
408                 case H323Connection::EndedByCallerAbort:
409                         if (h323debug) {
410                                 cout << "-- " << remoteName << " has stopped calling" << endl;
411                         }
412                         break;
413                 case H323Connection::EndedByRefusal:
414                         if (h323debug) {
415                                 cout << "-- " << remoteName << " did not accept your call" << endl;
416                         }
417                         break;
418                 case H323Connection::EndedByRemoteBusy:
419                         if (h323debug) {
420                                 cout << "-- " << remoteName << " was busy" << endl;
421                         }
422                         break;
423                 case H323Connection::EndedByRemoteCongestion:
424                         if (h323debug) {
425                                 cout << "-- Congested link to " << remoteName << endl;
426                         }
427                         break;
428                 case H323Connection::EndedByNoAnswer:
429                         if (h323debug) {
430                                 cout << "-- " << remoteName << " did not answer your call" << endl;
431                         }
432                         break;
433                 case H323Connection::EndedByTransportFail:
434                         if (h323debug) {
435                                 cout << "-- Call with " << remoteName << " ended abnormally" << endl;
436                         }
437                         break;
438                 case H323Connection::EndedByCapabilityExchange:
439                         if (h323debug) {
440                                 cout << "-- Could not find common codec with " << remoteName << endl;
441                         }
442                         break;
443                 case H323Connection::EndedByNoAccept:
444                         if (h323debug) {
445                                 cout << "-- Did not accept incoming call from " << remoteName << endl;
446                         }
447                         break;
448                 case H323Connection::EndedByAnswerDenied:
449                         if (h323debug) {
450                                 cout << "-- Refused incoming call from " << remoteName << endl;
451                         }
452                         break;
453                 case H323Connection::EndedByNoUser:
454                         if (h323debug) {
455                                 cout << "-- Remote endpoint could not find user: " << remoteName << endl;
456                         }
457                         break;
458                 case H323Connection::EndedByNoBandwidth:
459                         if (h323debug) {
460                                 cout << "-- Call to " << remoteName << " aborted, insufficient bandwidth." << endl;
461                         }
462                         break;
463                 case H323Connection::EndedByUnreachable:
464                         if (h323debug) {
465                                 cout << "-- " << remoteName << " could not be reached." << endl;
466                         }
467                         break;
468                 case H323Connection::EndedByHostOffline:
469                         if (h323debug) {
470                                 cout << "-- " << remoteName << " is not online." << endl;
471                         }
472                         break;
473                 case H323Connection::EndedByNoEndPoint:
474                         if (h323debug) {
475                                 cout << "-- No phone running for " << remoteName << endl;
476                         }
477                         break;
478                 case H323Connection::EndedByConnectFail:
479                         if (h323debug) {
480                                 cout << "-- Transport error calling " << remoteName << endl;
481                         }
482                         break;
483                 default:
484                         if (h323debug) {
485 #ifdef PTRACING
486                                 cout << " -- Call with " << remoteName << " completed (" << connection.GetCallEndReason() << ")" << endl;
487 #else
488                                 cout << " -- Call with " << remoteName << " completed ([" << (int)connection.GetCallEndReason() << "])" << endl;
489 #endif
490                         }
491         }
492
493         if (connection.IsEstablished()) {
494                 if (h323debug) {
495                         cout << "\t-- Call duration " << setprecision(0) << setw(5) << (PTime() - connection.GetConnectionStartTime()) << endl;
496                 }
497         }
498         /* Invoke the PBX application registered callback */
499         on_connection_cleared(connection.GetCallReference(), clearedCallToken);
500         return;
501 }
502
503 H323Connection * MyH323EndPoint::CreateConnection(unsigned callReference, void *userData, H323Transport *transport, H323SignalPDU *setupPDU)
504 {
505         unsigned options = 0;
506         call_options_t *opts = (call_options_t *)userData;
507         MyH323Connection *conn;
508
509         if (opts && opts->fastStart) {
510                 options |= H323Connection::FastStartOptionEnable;
511         } else {
512                 options |= H323Connection::FastStartOptionDisable;
513         }
514         if (opts && opts->h245Tunneling) {
515                 options |= H323Connection::H245TunnelingOptionEnable;
516         } else {
517                 options |= H323Connection::H245TunnelingOptionDisable;
518         }
519 /* Disable until I can figure out the proper way to deal with this */
520 #if 0
521         if (opts->silenceSuppression) {
522                 options |= H323Connection::SilenceSuppresionOptionEnable;
523         } else {
524                 options |= H323Connection::SilenceSUppressionOptionDisable;
525         }
526 #endif
527         conn = new MyH323Connection(*this, callReference, options);
528         if (conn) {
529                 if (opts)
530                         conn->SetCallOptions(opts, (setupPDU ? TRUE : FALSE));
531         }
532         return conn;
533 }
534
535 /* MyH323Connection Implementation */
536 MyH323Connection::MyH323Connection(MyH323EndPoint & ep, unsigned callReference,
537                                                         unsigned options)
538         : H323Connection(ep, callReference, options)
539 {
540 #ifdef H323_H450
541         /* Dispatcher will free out all registered handlers */
542         if (h450dispatcher)
543                 delete h450dispatcher;
544         h450dispatcher = new H450xDispatcher(*this);
545         h4502handler = new H4502Handler(*this, *h450dispatcher);
546         h4504handler = new MyH4504Handler(*this, *h450dispatcher);
547         h4506handler = new H4506Handler(*this, *h450dispatcher);
548         h45011handler = new H45011Handler(*this, *h450dispatcher);
549 #endif
550         cause = -1;
551         sessionId = 0;
552         bridging = FALSE;
553         holdHandling = progressSetup = progressAlert = 0;
554         dtmfMode = 0;
555         dtmfCodec[0] = dtmfCodec[1] = (RTP_DataFrame::PayloadTypes)0;
556         redirect_reason = -1;
557 #ifdef TUNNELLING
558         tunnelOptions = remoteTunnelOptions = 0;
559 #endif
560         if (h323debug) {
561                 cout << "       == New H.323 Connection created." << endl;
562         }
563         return;
564 }
565
566 MyH323Connection::~MyH323Connection()
567 {
568         if (h323debug) {
569                 cout << "       == H.323 Connection deleted." << endl;
570         }
571         return;
572 }
573
574 BOOL MyH323Connection::OnReceivedProgress(const H323SignalPDU &pdu)
575 {
576         BOOL isInband;
577         unsigned pi;
578
579         if (!H323Connection::OnReceivedProgress(pdu)) {
580                 return FALSE;
581         }
582
583         if (!pdu.GetQ931().GetProgressIndicator(pi))
584                 pi = 0;
585         if (h323debug) {
586                 cout << "\t- Progress Indicator: " << pi << endl;
587         }
588
589         switch(pi) {
590         case Q931::ProgressNotEndToEndISDN:
591         case Q931::ProgressInbandInformationAvailable:
592                 isInband = TRUE;
593                 break;
594         default:
595                 isInband = FALSE;
596         }
597         on_progress(GetCallReference(), (const char *)GetCallToken(), isInband);
598
599         return connectionState != ShuttingDownConnection;
600 }
601
602 BOOL MyH323Connection::MySendProgress()
603 {
604         /* The code taken from H323Connection::AnsweringCall() but ALWAYS send
605            PROGRESS message, including slow start operations */
606         H323SignalPDU progressPDU;
607         H225_Progress_UUIE &prog = progressPDU.BuildProgress(*this);
608
609         if (!mediaWaitForConnect) {
610                 if (SendFastStartAcknowledge(prog.m_fastStart))
611                         prog.IncludeOptionalField(H225_Progress_UUIE::e_fastStart);
612                 else {
613                         if (connectionState == ShuttingDownConnection)
614                                 return FALSE;
615
616                         /* Do early H.245 start */
617                         earlyStart = TRUE;
618                         if (!h245Tunneling) {
619                                 if (!H323Connection::StartControlChannel())
620                                         return FALSE;
621                                 prog.IncludeOptionalField(H225_Progress_UUIE::e_h245Address);
622                                 controlChannel->SetUpTransportPDU(prog.m_h245Address, TRUE);
623                         }
624                 }
625         }
626         progressPDU.GetQ931().SetProgressIndicator(Q931::ProgressInbandInformationAvailable);
627
628 #ifdef TUNNELLING
629         EmbedTunneledInfo(progressPDU);
630 #endif
631         HandleTunnelPDU(&progressPDU);
632         WriteSignalPDU(progressPDU);
633
634         return TRUE;
635 }
636
637 H323Connection::AnswerCallResponse MyH323Connection::OnAnswerCall(const PString & caller,
638                                                                 const H323SignalPDU & setupPDU,
639                                                                 H323SignalPDU & connectPDU)
640 {
641         unsigned pi;
642
643         if (h323debug) {
644                 cout << "\t=-= In OnAnswerCall for call " << GetCallReference() << endl;
645         }
646
647         if (connectionState == ShuttingDownConnection)
648                 return H323Connection::AnswerCallDenied;
649
650         if (!setupPDU.GetQ931().GetProgressIndicator(pi)) {
651                 pi = 0;
652         }
653         if (h323debug) {
654                 cout << "\t\t- Progress Indicator: " << pi << endl;
655         }
656         if (progressAlert) {
657                 pi = progressAlert;
658         } else if (pi == Q931::ProgressOriginNotISDN) {
659                 pi = Q931::ProgressInbandInformationAvailable;
660         }
661         if (pi && alertingPDU) {
662                 alertingPDU->GetQ931().SetProgressIndicator(pi);
663         }
664         if (h323debug) {
665                 cout << "\t\t- Inserting PI of " << pi << " into ALERTING message" << endl;
666         }
667
668 #ifdef TUNNELLING
669         if (alertingPDU)
670                 EmbedTunneledInfo(*alertingPDU);
671         EmbedTunneledInfo(connectPDU);
672 #endif
673
674         if (!on_answer_call(GetCallReference(), (const char *)GetCallToken())) {
675                 return H323Connection::AnswerCallDenied;
676         }
677         /* The call will be answered later with "AnsweringCall()" function.
678          */
679         return ((pi || (fastStartState != FastStartDisabled)) ? AnswerCallDeferredWithMedia : AnswerCallDeferred);
680 }
681
682 BOOL MyH323Connection::OnAlerting(const H323SignalPDU & alertingPDU, const PString & username)
683 {
684         if (h323debug) {
685                 cout << "\t=-= In OnAlerting for call " << GetCallReference()
686                         << ": sessionId=" << sessionId << endl;
687                 cout << "\t-- Ringing phone for \"" << username << "\"" << endl;
688         }
689
690         if (on_progress) {
691                 BOOL isInband;
692                 unsigned alertingPI;
693
694                 if (!alertingPDU.GetQ931().GetProgressIndicator(alertingPI)) {
695                         alertingPI = 0;
696                 }
697                 if (h323debug) {
698                         cout << "\t\t- Progress Indicator: " << alertingPI << endl;
699                 }
700
701                 switch(alertingPI) {
702                 case Q931::ProgressNotEndToEndISDN:
703                 case Q931::ProgressInbandInformationAvailable:
704                         isInband = TRUE;
705                         break;
706                 default:
707                         isInband = FALSE;
708                 }
709                 on_progress(GetCallReference(), (const char *)GetCallToken(), isInband);
710         }
711         on_chan_ringing(GetCallReference(), (const char *)GetCallToken() );
712         return connectionState != ShuttingDownConnection;
713 }
714
715 void MyH323Connection::SetCallOptions(void *o, BOOL isIncoming)
716 {
717         call_options_t *opts = (call_options_t *)o;
718
719         progressSetup = opts->progress_setup;
720         progressAlert = opts->progress_alert;
721         holdHandling = opts->holdHandling;
722         dtmfCodec[0] = (RTP_DataFrame::PayloadTypes)opts->dtmfcodec[0];
723         dtmfCodec[1] = (RTP_DataFrame::PayloadTypes)opts->dtmfcodec[1];
724         dtmfMode = opts->dtmfmode;
725
726         if (isIncoming) {
727                 fastStartState = (opts->fastStart ? FastStartInitiate : FastStartDisabled);
728                 h245Tunneling = (opts->h245Tunneling ? TRUE : FALSE);
729         } else {
730                 SetLocalPartyName(PString(opts->cid_num));
731                 SetDisplayName(PString(opts->cid_name));
732                 if (opts->redirect_reason >= 0) {
733                         rdnis = PString(opts->cid_rdnis);
734                         redirect_reason = opts->redirect_reason;
735                 }
736                 cid_presentation = opts->presentation;
737                 cid_ton = opts->type_of_number;
738         }
739         tunnelOptions = opts->tunnelOptions;
740 }
741
742 void MyH323Connection::SetCallDetails(void *callDetails, const H323SignalPDU &setupPDU, BOOL isIncoming)
743 {
744         PString sourceE164;
745         PString destE164;
746         PString sourceAliases;
747         PString destAliases;
748         char *s, *s1;
749         call_details_t *cd = (call_details_t *)callDetails;
750
751         memset(cd, 0, sizeof(*cd));
752         cd->call_reference = GetCallReference();
753         cd->call_token = strdup((const char *)GetCallToken());
754
755         sourceE164 = "";
756         setupPDU.GetSourceE164(sourceE164);
757         cd->call_source_e164 = strdup((const char *)sourceE164);
758
759         destE164 = "";
760         setupPDU.GetDestinationE164(destE164);
761         cd->call_dest_e164 = strdup((const char *)destE164);
762
763         /* XXX Is it possible to have this information for outgoing calls too? XXX */
764         if (isIncoming) {
765                 PString sourceName;
766                 PIPSocket::Address Ip;
767                 WORD sourcePort;
768                 PString redirect_number;
769                 unsigned redirect_reason;
770                 unsigned plan, type, screening, presentation;
771
772                 /* Fetch presentation and type information about calling party's number */
773                 if (setupPDU.GetQ931().GetCallingPartyNumber(sourceName, &plan, &type, &presentation, &screening, 2, 3)) {
774                         /* Construct fields back */
775                         cd->type_of_number = (type << 4) | screening;
776                         cd->presentation = (presentation << 5) | screening;
777                 } else {
778                         cd->type_of_number = 0;         /* UNKNOWN */
779                         cd->presentation = 0x43;        /* NUMBER NOT AVAILABLE */
780                 }
781
782                 sourceName = setupPDU.GetQ931().GetDisplayName();
783                 cd->call_source_name = strdup((const char *)sourceName);
784
785                 GetSignallingChannel()->GetRemoteAddress().GetIpAndPort(Ip, sourcePort);
786                 cd->sourceIp = strdup((const char *)Ip.AsString());
787
788                 if(setupPDU.GetQ931().GetRedirectingNumber(redirect_number, NULL, NULL, NULL, NULL, &redirect_reason, 0, 0, 0)) {
789                         cd->redirect_number = strdup((const char *)redirect_number);
790                         cd->redirect_reason = redirect_reason;
791                 }
792                 else
793                         cd->redirect_reason = -1;
794         }
795
796         /* Convert complex strings */
797         //  FIXME: deal more than one source alias
798         sourceAliases = setupPDU.GetSourceAliases();
799         s1 = strdup((const char *)sourceAliases);
800         if ((s = strchr(s1, ' ')) != NULL)
801                 *s = '\0';
802         if ((s = strchr(s1, '\t')) != NULL)
803                 *s = '\0';
804         cd->call_source_aliases = s1;
805
806         destAliases = setupPDU.GetDestinationAlias();
807         s1 = strdup((const char *)destAliases);
808         if ((s = strchr(s1, ' ')) != NULL)
809                 *s = '\0';
810         if ((s = strchr(s1, '\t')) != NULL)
811                 *s = '\0';
812         cd->call_dest_alias = s1;
813 }
814
815 #ifdef TUNNELLING
816 static BOOL FetchInformationElements(Q931 &q931, const PBYTEArray &data)
817 {
818         PINDEX offset = 0;
819
820         while (offset < data.GetSize()) {
821                 // Get field discriminator
822                 int discriminator = data[offset++];
823
824 #if 0
825                 /* Do not overwrite existing IEs */
826                 if (q931.HasIE((Q931::InformationElementCodes)discriminator)) {
827                         if ((discriminatir & 0x80) == 0)
828                                 offset += data[offset++];
829                         if (offset > data.GetSize())
830                                 return FALSE;
831                         continue;
832                 }
833 #endif
834
835                 PBYTEArray * item = new PBYTEArray;
836
837                 // For discriminator with high bit set there is no data
838                 if ((discriminator & 0x80) == 0) {
839                         int len = data[offset++];
840
841 #if 0           // That is not H.225 but regular Q.931 (ISDN) IEs
842                         if (discriminator == UserUserIE) {
843                                 // Special case of User-user field. See 7.2.2.31/H.225.0v4.
844                                 len <<= 8;
845                                 len |= data[offset++];
846
847                                 // we also have a protocol discriminator, which we ignore
848                                 offset++;
849
850                                 // before decrementing the length, make sure it is not zero
851                                 if (len == 0)
852                                         return FALSE;
853
854                                 // adjust for protocol discriminator
855                                 len--;
856                         }
857 #endif
858
859                         if (offset + len > data.GetSize()) {
860                                 delete item;
861                                 return FALSE;
862                         }
863
864                         memcpy(item->GetPointer(len), (const BYTE *)data+offset, len);
865                         offset += len;
866                 }
867
868                 q931.SetIE((Q931::InformationElementCodes)discriminator, *item);
869                 delete item;
870         }
871         return TRUE;
872 }
873
874 static BOOL FetchCiscoTunneledInfo(Q931 &q931, const H323SignalPDU &pdu)
875 {
876         BOOL res = FALSE;
877         const H225_H323_UU_PDU &uuPDU = pdu.m_h323_uu_pdu;
878
879         if(uuPDU.HasOptionalField(H225_H323_UU_PDU::e_nonStandardControl)) {
880                 for(int i = 0; i < uuPDU.m_nonStandardControl.GetSize(); ++i) {
881                         const H225_NonStandardParameter &np = uuPDU.m_nonStandardControl[i];
882                         const H225_NonStandardIdentifier &id = np.m_nonStandardIdentifier;
883                         if (id.GetTag() == H225_NonStandardIdentifier::e_h221NonStandard) {
884                                 const H225_H221NonStandard &ni = id;
885                                 /* Check for Cisco */
886                                 if ((ni.m_t35CountryCode == 181) && (ni.m_t35Extension == 0) && (ni.m_manufacturerCode == 18)) {
887                                         const PBYTEArray &data = np.m_data;
888                                         if (h323debug)
889                                                 cout << setprecision(0) << "Received non-standard Cisco extension data " << np.m_data << endl;
890                                         CISCO_H225_H323_UU_NonStdInfo c;
891                                         PPER_Stream strm(data);
892                                         if (c.Decode(strm)) {
893                                                 BOOL haveIEs = FALSE;
894                                                 if (h323debug)
895                                                         cout << setprecision(0) << "H323_UU_NonStdInfo = " << c << endl;
896                                                 if (c.HasOptionalField(CISCO_H225_H323_UU_NonStdInfo::e_protoParam)) {
897                                                         FetchInformationElements(q931, c.m_protoParam.m_qsigNonStdInfo.m_rawMesg);
898                                                         haveIEs = TRUE;
899                                                 }
900                                                 if (c.HasOptionalField(CISCO_H225_H323_UU_NonStdInfo::e_commonParam)) {
901                                                         FetchInformationElements(q931, c.m_commonParam.m_redirectIEinfo.m_redirectIE);
902                                                         haveIEs = TRUE;
903                                                 }
904                                                 if (haveIEs && h323debug)
905                                                         cout << setprecision(0) << "Information elements collected:" << q931 << endl;
906                                                 res = TRUE;
907                                         } else {
908                                                 cout << "ERROR while decoding non-standard Cisco extension" << endl;
909                                                 return FALSE;
910                                         }
911                                 }
912                         }
913                 }
914         }
915         return res;
916 }
917
918 static BOOL EmbedCiscoTunneledInfo(H323SignalPDU &pdu)
919 {
920         const static struct {
921                 Q931::InformationElementCodes ie;
922                 BOOL dontDelete;
923         } codes[] = {
924                 { Q931::RedirectingNumberIE, },
925                 { Q931::FacilityIE, },
926                 { Q931::CallingPartyNumberIE, TRUE },
927         };
928
929         BOOL res = FALSE;
930         BOOL notRedirOnly = FALSE;
931         Q931 tmpQ931;
932         Q931 &q931 = pdu.GetQ931();
933
934         for(unsigned i = 0; i < (sizeof(codes) / sizeof(codes[0])); ++i) {
935                 if (q931.HasIE(codes[i].ie)) {
936                         tmpQ931.SetIE(codes[i].ie, q931.GetIE(codes[i].ie));
937                         if (!codes[i].dontDelete)
938                                 q931.RemoveIE(codes[i].ie);
939                         if (codes[i].ie != Q931::RedirectingNumberIE)
940                                 notRedirOnly = TRUE;
941                         res = TRUE;
942                 }
943         }
944         /* Have something to embed */
945         if (res) {
946                 PBYTEArray msg;
947                 if (!tmpQ931.Encode(msg))
948                         return FALSE;
949                 PBYTEArray ies(msg.GetPointer() + 5, msg.GetSize() - 5);
950
951                 H225_H323_UU_PDU &uuPDU = pdu.m_h323_uu_pdu;
952                 if(!uuPDU.HasOptionalField(H225_H323_UU_PDU::e_nonStandardControl)) {
953                         uuPDU.IncludeOptionalField(H225_H323_UU_PDU::e_nonStandardControl);
954                         uuPDU.m_nonStandardControl.SetSize(0);
955                 }
956                 H225_NonStandardParameter *np = new H225_NonStandardParameter;
957                 uuPDU.m_nonStandardControl.Append(np);
958                 H225_NonStandardIdentifier &nsi = (*np).m_nonStandardIdentifier;
959                 nsi.SetTag(H225_NonStandardIdentifier::e_h221NonStandard);
960                 H225_H221NonStandard &ns = nsi;
961                 ns.m_t35CountryCode = 181;
962                 ns.m_t35Extension = 0;
963                 ns.m_manufacturerCode = 18;
964
965                 CISCO_H225_H323_UU_NonStdInfo c;
966                 c.IncludeOptionalField(CISCO_H225_H323_UU_NonStdInfo::e_version);
967                 c.m_version = 0;
968
969                 if (notRedirOnly) {
970                         c.IncludeOptionalField(CISCO_H225_H323_UU_NonStdInfo::e_protoParam);
971                         CISCO_H225_QsigNonStdInfo &qsigInfo = c.m_protoParam.m_qsigNonStdInfo;
972                         qsigInfo.m_iei = ies[0];
973                         qsigInfo.m_rawMesg = ies;
974                 } else {
975                         c.IncludeOptionalField(CISCO_H225_H323_UU_NonStdInfo::e_commonParam);
976                         c.m_commonParam.m_redirectIEinfo.m_redirectIE = ies;
977                 }
978                 PPER_Stream stream;
979                 c.Encode(stream);
980                 stream.CompleteEncoding();
981                 (*np).m_data = stream;
982         }
983         return res;
984 }
985
986 static const char OID_QSIG[] = "1.3.12.9";
987
988 static BOOL FetchQSIGTunneledInfo(Q931 &q931, const H323SignalPDU &pdu)
989 {
990         BOOL res = FALSE;
991         const H225_H323_UU_PDU &uuPDU = pdu.m_h323_uu_pdu;
992         if (uuPDU.HasOptionalField(H225_H323_UU_PDU::e_tunnelledSignallingMessage)) {
993                 const H225_H323_UU_PDU_tunnelledSignallingMessage &sig = uuPDU.m_tunnelledSignallingMessage;
994                 const H225_TunnelledProtocol_id &proto = sig.m_tunnelledProtocolID.m_id;
995                 if ((proto.GetTag() == H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID) &&
996                                 (((const PASN_ObjectId &)proto).AsString() == OID_QSIG)) {
997                         const H225_ArrayOf_PASN_OctetString &sigs = sig.m_messageContent;
998                         for(int i = 0; i < sigs.GetSize(); ++i) {
999                                 const PASN_OctetString &msg = sigs[i];
1000                                 if (h323debug)
1001                                         cout << setprecision(0) << "Q.931 message data is " << msg << endl;
1002                                 if(!q931.Decode((const PBYTEArray &)msg)) {
1003                                         cout << "Error while decoding Q.931 message" << endl;
1004                                         return FALSE;
1005                                 }
1006                                 res = TRUE;
1007                                 if (h323debug)
1008                                         cout << setprecision(0) << "Received QSIG message " << q931 << endl;
1009                         }
1010                 }
1011         }
1012         return res;
1013 }
1014
1015 static H225_EndpointType *GetEndpointType(H323SignalPDU &pdu)
1016 {
1017         if (!pdu.GetQ931().HasIE(Q931::UserUserIE))
1018                 return NULL;
1019
1020         H225_H323_UU_PDU_h323_message_body &body = pdu.m_h323_uu_pdu.m_h323_message_body;
1021         switch (body.GetTag()) {
1022         case H225_H323_UU_PDU_h323_message_body::e_setup:
1023                 return &((H225_Setup_UUIE &)body).m_sourceInfo;
1024         case H225_H323_UU_PDU_h323_message_body::e_callProceeding:
1025                 return &((H225_CallProceeding_UUIE &)body).m_destinationInfo;
1026         case H225_H323_UU_PDU_h323_message_body::e_connect:
1027                 return &((H225_Connect_UUIE &)body).m_destinationInfo;
1028         case H225_H323_UU_PDU_h323_message_body::e_alerting:
1029                 return &((H225_Alerting_UUIE &)body).m_destinationInfo;
1030         case H225_H323_UU_PDU_h323_message_body::e_facility:
1031                 return &((H225_Facility_UUIE &)body).m_destinationInfo;
1032         case H225_H323_UU_PDU_h323_message_body::e_progress:
1033                 return &((H225_Progress_UUIE &)body).m_destinationInfo;
1034         }
1035         return NULL;
1036 }
1037
1038 static BOOL QSIGTunnelRequested(H323SignalPDU &pdu)
1039 {
1040         H225_EndpointType *epType = GetEndpointType(pdu);
1041         if (epType) {
1042                 if (!(*epType).HasOptionalField(H225_EndpointType::e_supportedTunnelledProtocols)) {
1043                         return FALSE;
1044                 }
1045                 H225_ArrayOf_TunnelledProtocol &protos = (*epType).m_supportedTunnelledProtocols;
1046                 for (int i = 0; i < protos.GetSize(); ++i)
1047                 {
1048                         if ((protos[i].GetTag() == H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID) &&
1049                                         (((const PASN_ObjectId &)protos[i]).AsString() == OID_QSIG)) {
1050                                 return TRUE;
1051                         }
1052                 }
1053         }
1054         return FALSE;
1055 }
1056
1057 static BOOL EmbedQSIGTunneledInfo(H323SignalPDU &pdu)
1058 {
1059         const static Q931::InformationElementCodes codes[] =
1060         { Q931::RedirectingNumberIE, Q931::FacilityIE };
1061
1062         Q931 &q931 = pdu.GetQ931();
1063         PBYTEArray message;
1064
1065         q931.Encode(message);
1066
1067         /* Remove non-standard IEs */
1068         for(unsigned i = 0; i < (sizeof(codes) / sizeof(codes[0])); ++i) {
1069                 if (q931.HasIE(codes[i])) {
1070                         q931.RemoveIE(codes[i]);
1071                 }
1072         }
1073
1074         H225_H323_UU_PDU &uuPDU = pdu.m_h323_uu_pdu;
1075         H225_EndpointType *epType = GetEndpointType(pdu);
1076         if (epType) {
1077                 if (!(*epType).HasOptionalField(H225_EndpointType::e_supportedTunnelledProtocols)) {
1078                         (*epType).IncludeOptionalField(H225_EndpointType::e_supportedTunnelledProtocols);
1079                         (*epType).m_supportedTunnelledProtocols.SetSize(0);
1080                 }
1081                 H225_ArrayOf_TunnelledProtocol &protos = (*epType).m_supportedTunnelledProtocols;
1082                 BOOL addQSIG = TRUE;
1083                 for (int i = 0; i < protos.GetSize(); ++i)
1084                 {
1085                         if ((protos[i].GetTag() == H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID) &&
1086                                         (((PASN_ObjectId &)protos[i]).AsString() == OID_QSIG)) {
1087                                 addQSIG = FALSE;
1088                                 break;
1089                         }
1090                 }
1091                 if (addQSIG) {
1092                         H225_TunnelledProtocol *proto = new H225_TunnelledProtocol;
1093                         (*proto).m_id.SetTag(H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID);
1094                         (PASN_ObjectId &)(proto->m_id) = OID_QSIG;
1095                         protos.Append(proto);
1096                 }
1097         }
1098         if (!uuPDU.HasOptionalField(H225_H323_UU_PDU::e_tunnelledSignallingMessage))
1099                 uuPDU.IncludeOptionalField(H225_H323_UU_PDU::e_tunnelledSignallingMessage);
1100         H225_H323_UU_PDU_tunnelledSignallingMessage &sig = uuPDU.m_tunnelledSignallingMessage;
1101         H225_TunnelledProtocol_id &proto = sig.m_tunnelledProtocolID.m_id;
1102         if ((proto.GetTag() != H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID) ||
1103                         (((const PASN_ObjectId &)proto).AsString() != OID_QSIG)) {
1104                 proto.SetTag(H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID);
1105                 (PASN_ObjectId &)proto = OID_QSIG;
1106                 sig.m_messageContent.SetSize(0);
1107         }
1108         PASN_OctetString *msg = new PASN_OctetString;
1109         sig.m_messageContent.Append(msg);
1110         *msg = message;
1111         return TRUE;
1112 }
1113
1114 BOOL MyH323Connection::EmbedTunneledInfo(H323SignalPDU &pdu)
1115 {
1116         if ((tunnelOptions & H323_TUNNEL_QSIG) || (remoteTunnelOptions & H323_TUNNEL_QSIG))
1117                 EmbedQSIGTunneledInfo(pdu);
1118         if ((tunnelOptions & H323_TUNNEL_CISCO) || (remoteTunnelOptions & H323_TUNNEL_CISCO))
1119                 EmbedCiscoTunneledInfo(pdu);
1120
1121         return TRUE;
1122 }
1123
1124 /* Handle tunneled messages */
1125 BOOL MyH323Connection::HandleSignalPDU(H323SignalPDU &pdu)
1126 {
1127         if (pdu.GetQ931().HasIE(Q931::UserUserIE)) {
1128                 Q931 tunneledInfo;
1129                 const Q931 *q931Info;
1130
1131                 q931Info = NULL;
1132                 if (FetchCiscoTunneledInfo(tunneledInfo, pdu)) {
1133                         q931Info = &tunneledInfo;
1134                         remoteTunnelOptions |= H323_TUNNEL_CISCO;
1135                 }
1136                 if (FetchQSIGTunneledInfo(tunneledInfo, pdu)) {
1137                         q931Info = &tunneledInfo;
1138                         remoteTunnelOptions |= H323_TUNNEL_QSIG;
1139                 }
1140                 if (!(remoteTunnelOptions & H323_TUNNEL_QSIG) && QSIGTunnelRequested(pdu)) {
1141                         remoteTunnelOptions |= H323_TUNNEL_QSIG;
1142                 }
1143                 if (q931Info) {
1144                         if (q931Info->HasIE(Q931::RedirectingNumberIE)) {
1145                                 pdu.GetQ931().SetIE(Q931::RedirectingNumberIE, q931Info->GetIE(Q931::RedirectingNumberIE));
1146                                 if (h323debug) {
1147                                         PString number;
1148                                         unsigned reason;
1149                                         if(q931Info->GetRedirectingNumber(number, NULL, NULL, NULL, NULL, &reason, 0, 0, 0))
1150                                                 cout << "Got redirection from " << number << ", reason " << reason << endl;
1151                                 }
1152                         }
1153                 }
1154         }
1155
1156         return H323Connection::HandleSignalPDU(pdu);
1157 }
1158 #endif
1159
1160 BOOL MyH323Connection::OnReceivedSignalSetup(const H323SignalPDU & setupPDU)
1161 {
1162         call_details_t cd;
1163
1164         if (h323debug) {
1165                 cout << "\t--Received SETUP message" << endl;
1166         }
1167
1168         if (connectionState == ShuttingDownConnection)
1169                 return FALSE;
1170
1171         SetCallDetails(&cd, setupPDU, TRUE);
1172
1173         /* Notify Asterisk of the request */
1174         call_options_t *res = on_incoming_call(&cd);
1175
1176         if (!res) {
1177                 if (h323debug) {
1178                         cout << "\t-- Call Failed" << endl;
1179                 }
1180                 return FALSE;
1181         }
1182
1183         SetCallOptions(res, TRUE);
1184
1185         /* Disable fastStart if requested by remote side */
1186         if (h245Tunneling && !setupPDU.m_h323_uu_pdu.m_h245Tunneling) {
1187                 masterSlaveDeterminationProcedure->Stop();
1188                 capabilityExchangeProcedure->Stop();
1189                 PTRACE(3, "H225\tFast Start DISABLED!");
1190                 h245Tunneling = FALSE;
1191         }
1192
1193         return H323Connection::OnReceivedSignalSetup(setupPDU);
1194 }
1195
1196 BOOL MyH323Connection::OnSendSignalSetup(H323SignalPDU & setupPDU)
1197 {
1198         call_details_t cd;
1199
1200         if (h323debug) {
1201                 cout << "\t-- Sending SETUP message" << endl;
1202         }
1203
1204         if (connectionState == ShuttingDownConnection)
1205                 return FALSE;
1206
1207         if (progressSetup)
1208                 setupPDU.GetQ931().SetProgressIndicator(progressSetup);
1209
1210         if (redirect_reason >= 0) {
1211                 setupPDU.GetQ931().SetRedirectingNumber(rdnis, 0, 0, 0, 0, redirect_reason);
1212                 /* OpenH323 incorrectly fills number IE when redirecting reason is specified - fix it */
1213                 PBYTEArray IE(setupPDU.GetQ931().GetIE(Q931::RedirectingNumberIE));
1214                 IE[0] = IE[0] & 0x7f;
1215                 IE[1] = IE[1] & 0x7f;
1216                 setupPDU.GetQ931().SetIE(Q931::RedirectingNumberIE, IE);
1217         }
1218
1219         SetCallDetails(&cd, setupPDU, FALSE);
1220
1221         int res = on_outgoing_call(&cd);
1222         if (!res) {
1223                 if (h323debug) {
1224                         cout << "\t-- Call Failed" << endl;
1225                 }
1226                 return FALSE;
1227         }
1228
1229         /* OpenH323 will build calling party information with default
1230            type and presentation information, so build it to be recorded
1231            by embedding routines */
1232         setupPDU.GetQ931().SetCallingPartyNumber(GetLocalPartyName(), (cid_ton >> 4) & 0x07,
1233                         cid_ton & 0x0f, (cid_presentation >> 5) & 0x03, cid_presentation & 0x1f);
1234
1235 #ifdef TUNNELLING
1236         EmbedTunneledInfo(setupPDU);
1237 #endif
1238
1239         return H323Connection::OnSendSignalSetup(setupPDU);
1240 }
1241
1242 BOOL MyH323Connection::OnSendReleaseComplete(H323SignalPDU & releaseCompletePDU)
1243 {
1244         if (h323debug) {
1245                 cout << "\t-- Sending RELEASE COMPLETE" << endl;
1246         }
1247         if (cause > 0)
1248                 releaseCompletePDU.GetQ931().SetCause((Q931::CauseValues)cause);
1249
1250 #ifdef TUNNELLING
1251         EmbedTunneledInfo(releaseCompletePDU);
1252 #endif
1253
1254         return H323Connection::OnSendReleaseComplete(releaseCompletePDU);
1255 }
1256
1257 BOOL MyH323Connection::OnReceivedFacility(const H323SignalPDU & pdu)
1258 {
1259         if (h323debug) {
1260                 cout << "\t-- Received Facility message... " << endl;
1261         }
1262         return H323Connection::OnReceivedFacility(pdu);
1263 }
1264
1265 void MyH323Connection::OnReceivedReleaseComplete(const H323SignalPDU & pdu)
1266 {
1267         if (h323debug) {
1268                 cout << "\t-- Received RELEASE COMPLETE message..." << endl;
1269         }
1270         if (on_hangup)
1271                 on_hangup(GetCallReference(), (const char *)GetCallToken(), pdu.GetQ931().GetCause());
1272         return H323Connection::OnReceivedReleaseComplete(pdu);
1273 }
1274
1275 BOOL MyH323Connection::OnClosingLogicalChannel(H323Channel & channel)
1276 {
1277         if (h323debug) {
1278                 cout << "\t-- Closing logical channel..." << endl;
1279         }
1280         return H323Connection::OnClosingLogicalChannel(channel);
1281 }
1282
1283 void MyH323Connection::SendUserInputTone(char tone, unsigned duration, unsigned logicalChannel, unsigned rtpTimestamp)
1284 {
1285         SendUserInputModes mode = GetRealSendUserInputMode();
1286 //      That is recursive call... Why?
1287 //      on_receive_digit(GetCallReference(), tone, (const char *)GetCallToken());
1288         if ((tone != ' ') || (mode == SendUserInputAsTone) || (mode == SendUserInputAsInlineRFC2833)) {
1289                 if (h323debug) {
1290                         cout << "\t-- Sending user input tone (" << tone << ") to remote" << endl;
1291                 }
1292                 H323Connection::SendUserInputTone(tone, duration);
1293         }
1294 }
1295
1296 void MyH323Connection::OnUserInputTone(char tone, unsigned duration, unsigned logicalChannel, unsigned rtpTimestamp)
1297 {
1298         /* Why we should check this? */
1299         if ((dtmfMode & (H323_DTMF_CISCO | H323_DTMF_RFC2833 | H323_DTMF_SIGNAL)) != 0) {
1300                 if (h323debug) {
1301                         cout << "\t-- Received user input tone (" << tone << ") from remote" << endl;
1302                 }
1303                 on_receive_digit(GetCallReference(), tone, (const char *)GetCallToken(), duration);
1304         }
1305 }
1306
1307 void MyH323Connection::OnUserInputString(const PString &value)
1308 {
1309         if (h323debug) {
1310                 cout << "\t-- Received user input string (" << value << ") from remote." << endl;
1311         }
1312         on_receive_digit(GetCallReference(), value[0], (const char *)GetCallToken(), 0);
1313 }
1314
1315 void MyH323Connection::OnSendCapabilitySet(H245_TerminalCapabilitySet & pdu)
1316 {
1317         PINDEX i;
1318
1319         H323Connection::OnSendCapabilitySet(pdu);
1320
1321         H245_ArrayOf_CapabilityTableEntry & tables = pdu.m_capabilityTable;
1322         for(i = 0; i < tables.GetSize(); i++)
1323         {
1324                 H245_CapabilityTableEntry & entry = tables[i];
1325                 if (entry.HasOptionalField(H245_CapabilityTableEntry::e_capability)) {
1326                         H245_Capability & cap = entry.m_capability;
1327                         if (cap.GetTag() == H245_Capability::e_receiveRTPAudioTelephonyEventCapability) {
1328                                 H245_AudioTelephonyEventCapability & atec = cap;
1329                                 atec.m_dynamicRTPPayloadType = dtmfCodec[0];
1330 //                              on_set_rfc2833_payload(GetCallReference(), (const char *)GetCallToken(), (int)dtmfCodec[0]);
1331                                 if (h323debug) {
1332                                         cout << "\t-- Receiving RFC2833 on payload " <<
1333                                                 atec.m_dynamicRTPPayloadType << endl;
1334                                 }
1335                         }
1336                 }
1337         }
1338 }
1339
1340 void MyH323Connection::OnSetLocalCapabilities()
1341 {
1342         if (on_setcapabilities)
1343                 on_setcapabilities(GetCallReference(), (const char *)callToken);
1344 }
1345
1346 BOOL MyH323Connection::OnReceivedCapabilitySet(const H323Capabilities & remoteCaps,
1347                                                         const H245_MultiplexCapability * muxCap,
1348                                                         H245_TerminalCapabilitySetReject & reject)
1349 {
1350         struct __codec__ {
1351                 unsigned int asterisk_codec;
1352                 unsigned int h245_cap;
1353                 const char *oid;
1354                 const char *formatName;
1355         };
1356         static const struct __codec__ codecs[] = {
1357                 { AST_FORMAT_G723_1, H245_AudioCapability::e_g7231 },
1358                 { AST_FORMAT_GSM, H245_AudioCapability::e_gsmFullRate },
1359                 { AST_FORMAT_ULAW, H245_AudioCapability::e_g711Ulaw64k },
1360                 { AST_FORMAT_ALAW, H245_AudioCapability::e_g711Alaw64k },
1361                 { AST_FORMAT_G729A, H245_AudioCapability::e_g729AnnexA },
1362                 { AST_FORMAT_G729A, H245_AudioCapability::e_g729 },
1363                 { AST_FORMAT_G726_AAL2, H245_AudioCapability::e_nonStandard, NULL, CISCO_G726r32 },
1364 #ifdef AST_FORMAT_MODEM
1365                 { AST_FORMAT_MODEM, H245_DataApplicationCapability_application::e_t38fax },
1366 #endif
1367                 { 0 }
1368         };
1369
1370 #if 0
1371         static const struct __codec__ vcodecs[] = {
1372 #ifdef HAVE_H261
1373                 { AST_FORMAT_H261, H245_VideoCapability::e_h261VideoCapability },
1374 #endif
1375 #ifdef HAVE_H263
1376                 { AST_FORMAT_H263, H245_VideoCapability::e_h263VideoCapability },
1377 #endif
1378 #ifdef HAVE_H264
1379                 { AST_FORMAT_H264, H245_VideoCapability::e_genericVideoCapability, "0.0.8.241.0.0.1" },
1380 #endif
1381                 { 0 }
1382         };
1383 #endif
1384         struct ast_codec_pref prefs;
1385         RTP_DataFrame::PayloadTypes pt;
1386
1387         if (!H323Connection::OnReceivedCapabilitySet(remoteCaps, muxCap, reject)) {
1388                 return FALSE;
1389         }
1390
1391         memset(&prefs, 0, sizeof(prefs));
1392         int peer_capabilities = 0;
1393         for (int i = 0; i < remoteCapabilities.GetSize(); ++i) {
1394                 unsigned int subType = remoteCapabilities[i].GetSubType();
1395                 if (h323debug) {
1396                         cout << "Peer capability is " << remoteCapabilities[i] << endl;
1397                 }
1398                 switch(remoteCapabilities[i].GetMainType()) {
1399                 case H323Capability::e_Audio:
1400                         for (int x = 0; codecs[x].asterisk_codec > 0; ++x) {
1401                                 if ((subType == codecs[x].h245_cap) && (!codecs[x].formatName || (!strcmp(codecs[x].formatName, (const char *)remoteCapabilities[i].GetFormatName())))) {
1402                                         int ast_codec = codecs[x].asterisk_codec;
1403                                         int ms = 0;
1404                                         if (!(peer_capabilities & ast_codec)) {
1405                                                 struct ast_format_list format;
1406                                                 ast_codec_pref_append(&prefs, ast_codec);
1407                                                 format = ast_codec_pref_getsize(&prefs, ast_codec);
1408                                                 if ((ast_codec == AST_FORMAT_ALAW) || (ast_codec == AST_FORMAT_ULAW)) {
1409                                                         ms = remoteCapabilities[i].GetTxFramesInPacket();
1410                                                         if (ms > 60)
1411                                                                 ms = format.cur_ms;
1412                                                 } else
1413                                                         ms = remoteCapabilities[i].GetTxFramesInPacket() * format.inc_ms;
1414                                                 ast_codec_pref_setsize(&prefs, ast_codec, ms);
1415                                         }
1416                                         if (h323debug) {
1417                                                 cout << "Found peer capability " << remoteCapabilities[i] << ", Asterisk code is " << ast_codec << ", frame size (in ms) is " << ms << endl;
1418                                         }
1419                                         peer_capabilities |= ast_codec;
1420                                 }
1421                         }
1422                         break;
1423                 case H323Capability::e_Data:
1424                         if (!strcmp((const char *)remoteCapabilities[i].GetFormatName(), CISCO_DTMF_RELAY)) {
1425                                 pt = remoteCapabilities[i].GetPayloadType();
1426                                 if ((dtmfMode & H323_DTMF_CISCO) != 0) {
1427                                         on_set_rfc2833_payload(GetCallReference(), (const char *)GetCallToken(), (int)pt, 1);
1428 //                                      if (sendUserInputMode == SendUserInputAsTone)
1429 //                                              sendUserInputMode = SendUserInputAsInlineRFC2833;
1430                                 }
1431                                 if (h323debug) {
1432                                         cout << "\t-- Outbound Cisco RTP DTMF on payload " << pt << endl;
1433                                 }
1434                         }
1435                         break;
1436                 case H323Capability::e_UserInput:
1437                         if (!strcmp((const char *)remoteCapabilities[i].GetFormatName(), H323_UserInputCapability::SubTypeNames[H323_UserInputCapability::SignalToneRFC2833])) {
1438                                 pt = remoteCapabilities[i].GetPayloadType();
1439                                 if ((dtmfMode & H323_DTMF_RFC2833) != 0) {
1440                                         on_set_rfc2833_payload(GetCallReference(), (const char *)GetCallToken(), (int)pt, 0);
1441 //                                      if (sendUserInputMode == SendUserInputAsTone)
1442 //                                              sendUserInputMode = SendUserInputAsInlineRFC2833;
1443                                 }
1444                                 if (h323debug) {
1445                                         cout << "\t-- Outbound RFC2833 on payload " << pt << endl;
1446                                 }
1447                         }
1448                         break;
1449 #if 0
1450                 case H323Capability::e_Video:
1451                         for (int x = 0; vcodecs[x].asterisk_codec > 0; ++x) {
1452                                 if (subType == vcodecs[x].h245_cap) {
1453                                         H245_CapabilityIdentifier *cap = NULL;
1454                                         H245_GenericCapability y;
1455                                         if (vcodecs[x].oid) {
1456                                                 cap = new H245_CapabilityIdentifier(H245_CapabilityIdentifier::e_standard);
1457                                                 PASN_ObjectId &object_id = *cap;
1458                                                 object_id = vcodecs[x].oid;
1459                                                 y.m_capabilityIdentifier = *cap;
1460                                         }
1461                                         if ((subType != H245_VideoCapability::e_genericVideoCapability) ||
1462                                                         (vcodecs[x].oid && ((const H323GenericVideoCapability &)remoteCapabilities[i]).IsGenericMatch((const H245_GenericCapability)y))) {
1463                                                 if (h323debug) {
1464                                                         cout << "Found peer video capability " << remoteCapabilities[i] << ", Asterisk code is " << vcodecs[x].asterisk_codec << endl;
1465                                                 }
1466                                                 peer_capabilities |= vcodecs[x].asterisk_codec;
1467                                         }
1468                                         if (cap)
1469                                                 delete(cap);
1470                                 }
1471                         }
1472                         break;
1473 #endif
1474                 default:
1475                         break;
1476                 }
1477         }
1478         if (h323debug) {
1479                 char caps_str[1024], caps2_str[1024];
1480                 ast_codec_pref_string(&prefs, caps2_str, sizeof(caps2_str));
1481                 cout << "Peer capabilities = " << ast_getformatname_multiple(caps_str, sizeof(caps_str), peer_capabilities)
1482                                 << ", ordered list is " << caps2_str << endl;
1483         }
1484 #if 0
1485         redir_capabilities &= peer_capabilities;
1486 #endif
1487         if (on_setpeercapabilities)
1488                 on_setpeercapabilities(GetCallReference(), (const char *)callToken, peer_capabilities, &prefs);
1489
1490         return TRUE;
1491 }
1492
1493 H323Channel * MyH323Connection::CreateRealTimeLogicalChannel(const H323Capability & capability,
1494                                                                         H323Channel::Directions dir,
1495                                                                         unsigned sessionID,
1496                                                                         const H245_H2250LogicalChannelParameters * /*param*/,
1497                                                                         RTP_QOS * /*param*/ )
1498 {
1499         /* Do not open tx channel when transmitter has been paused by empty TCS */
1500         if ((dir == H323Channel::IsTransmitter) && transmitterSidePaused)
1501                 return NULL;
1502
1503         return new MyH323_ExternalRTPChannel(*this, capability, dir, sessionID);
1504 }
1505
1506 /** This callback function is invoked once upon creation of each
1507   * channel for an H323 session
1508   */
1509 BOOL MyH323Connection::OnStartLogicalChannel(H323Channel & channel)
1510 {
1511         /* Increase the count of channels we have open */
1512         channelsOpen++;
1513
1514         if (h323debug) {
1515                 cout << "\t-- Started logical channel: "
1516                                 << ((channel.GetDirection() == H323Channel::IsTransmitter) ? "sending " : ((channel.GetDirection() == H323Channel::IsReceiver) ? "receiving " : " "))
1517                                 << (const char *)(channel.GetCapability()).GetFormatName() << endl;
1518                 cout << "\t\t-- channelsOpen = " << channelsOpen << endl;
1519         }
1520         return connectionState != ShuttingDownConnection;
1521 }
1522
1523 void MyH323Connection::SetCapabilities(int caps, int dtmf_mode, void *_prefs, int pref_codec)
1524 {
1525         PINDEX lastcap = -1; /* last common capability index */
1526         int alreadysent = 0;
1527         int codec;
1528         int x, y;
1529         char caps_str[1024];
1530         struct ast_codec_pref *prefs = (struct ast_codec_pref *)_prefs;
1531         struct ast_format_list format;
1532         int frames_per_packet;
1533         int max_frames_per_packet;
1534         H323Capability *cap;
1535
1536         localCapabilities.RemoveAll();
1537
1538         if (h323debug) {
1539                 cout << "Setting capabilities to " << ast_getformatname_multiple(caps_str, sizeof(caps_str), caps) << endl;
1540                 ast_codec_pref_string(prefs, caps_str, sizeof(caps_str));
1541                 cout << "Capabilities in preference order is " << caps_str << endl;
1542         }
1543         /* Add audio codecs in preference order first, then
1544            audio codecs without preference as allowed by mask */
1545         for (y = 0, x = -1; x < 32 + 32; ++x) {
1546                 if (x < 0)
1547                         codec = pref_codec;
1548                 else if (y || (!(codec = ast_codec_pref_index(prefs, x)))) {
1549                         if (!y)
1550                                 y = 1;
1551                         else if (y == AST_FORMAT_MAX_AUDIO)
1552                                 break;
1553                         else
1554                                 y <<= 1;
1555                         codec = y;
1556                 }
1557                 if (!(caps & codec) || (alreadysent & codec) || !(codec & AST_FORMAT_AUDIO_MASK))
1558                         continue;
1559                 alreadysent |= codec;
1560                 format = ast_codec_pref_getsize(prefs, codec);
1561                 frames_per_packet = (format.inc_ms ? format.cur_ms / format.inc_ms : format.cur_ms);
1562                 max_frames_per_packet = (format.inc_ms ? format.max_ms / format.inc_ms : 0);
1563                 switch(codec) {
1564 #if 0
1565                 case AST_FORMAT_SPEEX:
1566                         /* Not real sure if Asterisk acutally supports all
1567                            of the various different bit rates so add them
1568                            all and figure it out later*/
1569
1570                         lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow2AudioCapability());
1571                         lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow3AudioCapability());
1572                         lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow4AudioCapability());
1573                         lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow5AudioCapability());
1574                         lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow6AudioCapability());
1575                         break;
1576 #endif
1577                 case AST_FORMAT_G729A:
1578                         AST_G729ACapability *g729aCap;
1579                         AST_G729Capability *g729Cap;
1580                         lastcap = localCapabilities.SetCapability(0, 0, g729aCap = new AST_G729ACapability(frames_per_packet));
1581                         lastcap = localCapabilities.SetCapability(0, 0, g729Cap = new AST_G729Capability(frames_per_packet));
1582                         if (max_frames_per_packet) {
1583                                 g729aCap->SetTxFramesInPacket(max_frames_per_packet);
1584                                 g729Cap->SetTxFramesInPacket(max_frames_per_packet);
1585                         }
1586                         break;
1587                 case AST_FORMAT_G723_1:
1588                         AST_G7231Capability *g7231Cap;
1589                         lastcap = localCapabilities.SetCapability(0, 0, g7231Cap = new AST_G7231Capability(frames_per_packet, TRUE));
1590                         if (max_frames_per_packet)
1591                                 g7231Cap->SetTxFramesInPacket(max_frames_per_packet);
1592                         lastcap = localCapabilities.SetCapability(0, 0, g7231Cap = new AST_G7231Capability(frames_per_packet, FALSE));
1593                         if (max_frames_per_packet)
1594                                 g7231Cap->SetTxFramesInPacket(max_frames_per_packet);
1595                         break;
1596                 case AST_FORMAT_GSM:
1597                         AST_GSM0610Capability *gsmCap;
1598                         lastcap = localCapabilities.SetCapability(0, 0, gsmCap = new AST_GSM0610Capability(frames_per_packet));
1599                         if (max_frames_per_packet)
1600                                 gsmCap->SetTxFramesInPacket(max_frames_per_packet);
1601                         break;
1602                 case AST_FORMAT_ULAW:
1603                         AST_G711Capability *g711uCap;
1604                         lastcap = localCapabilities.SetCapability(0, 0, g711uCap = new AST_G711Capability(format.cur_ms, H323_G711Capability::muLaw));
1605                         if (format.max_ms)
1606                                 g711uCap->SetTxFramesInPacket(format.max_ms);
1607                         break;
1608                 case AST_FORMAT_ALAW:
1609                         AST_G711Capability *g711aCap;
1610                         lastcap = localCapabilities.SetCapability(0, 0, g711aCap = new AST_G711Capability(format.cur_ms, H323_G711Capability::ALaw));
1611                         if (format.max_ms)
1612                                 g711aCap->SetTxFramesInPacket(format.max_ms);
1613                         break;
1614                 case AST_FORMAT_G726_AAL2:
1615                         AST_CiscoG726Capability *g726Cap;
1616                         lastcap = localCapabilities.SetCapability(0, 0, g726Cap = new AST_CiscoG726Capability(frames_per_packet));
1617                         if (max_frames_per_packet)
1618                                 g726Cap->SetTxFramesInPacket(max_frames_per_packet);
1619                         break;
1620                 default:
1621                         alreadysent &= ~codec;
1622                         break;
1623                 }
1624         }
1625
1626         cap = new H323_UserInputCapability(H323_UserInputCapability::HookFlashH245);
1627         if (cap && cap->IsUsable(*this)) {
1628                 lastcap++;
1629                 lastcap = localCapabilities.SetCapability(0, lastcap, cap);
1630         } else if (cap)
1631                 delete cap;                             /* Capability is not usable */
1632
1633         dtmfMode = dtmf_mode;
1634         if (h323debug) {
1635                 cout << "DTMF mode is " << (int)dtmfMode << endl;
1636         }
1637         if (dtmfMode) {
1638                 lastcap++;
1639                 if (dtmfMode == H323_DTMF_INBAND) {
1640                         cap = new H323_UserInputCapability(H323_UserInputCapability::BasicString);
1641                         if (cap && cap->IsUsable(*this)) {
1642                                 lastcap = localCapabilities.SetCapability(0, lastcap, cap);
1643                         } else if (cap)
1644                                 delete cap;             /* Capability is not usable */
1645                         sendUserInputMode = SendUserInputAsString;
1646                 } else {
1647                         if ((dtmfMode & H323_DTMF_RFC2833) != 0) {
1648                                 cap = new H323_UserInputCapability(H323_UserInputCapability::SignalToneRFC2833);
1649                                 if (cap && cap->IsUsable(*this))
1650                                         lastcap = localCapabilities.SetCapability(0, lastcap, cap);
1651                                 else {
1652                                         dtmfMode |= H323_DTMF_SIGNAL;
1653                                         if (cap)
1654                                                 delete cap;     /* Capability is not usable */
1655                                 }
1656                         }
1657                         if ((dtmfMode & H323_DTMF_CISCO) != 0) {
1658                                 /* Try Cisco's RTP DTMF relay too, but prefer RFC2833 or h245-signal */
1659                                 cap = new AST_CiscoDtmfCapability();
1660                                 if (cap && cap->IsUsable(*this)) {
1661                                         lastcap = localCapabilities.SetCapability(0, lastcap, cap);
1662                                         /* We cannot send Cisco RTP DTMFs, use h245-signal instead */
1663                                         dtmfMode |= H323_DTMF_SIGNAL;
1664                                 } else {
1665                                         dtmfMode |= H323_DTMF_SIGNAL;
1666                                         if (cap)
1667                                                 delete cap;     /* Capability is not usable */
1668                                 }
1669                         }
1670                         if ((dtmfMode & H323_DTMF_SIGNAL) != 0) {
1671                                 /* Cisco usually sends DTMF correctly only through h245-alphanumeric or h245-signal */
1672                                 cap = new H323_UserInputCapability(H323_UserInputCapability::SignalToneH245);
1673                                 if (cap && cap->IsUsable(*this))
1674                                         lastcap = localCapabilities.SetCapability(0, lastcap, cap);
1675                                 else if (cap)
1676                                         delete cap;     /* Capability is not usable */
1677                         }
1678                         sendUserInputMode = SendUserInputAsTone;        /* RFC2833 transmission handled at Asterisk level */
1679                 }
1680         }
1681
1682         if (h323debug) {
1683                 cout << "Allowed Codecs for " << GetCallToken() << " (" << GetSignallingChannel()->GetLocalAddress() << "):\n\t" << setprecision(2) << localCapabilities << endl;
1684         }
1685 }
1686
1687 BOOL MyH323Connection::StartControlChannel(const H225_TransportAddress & h245Address)
1688 {
1689         // Check that it is an IP address, all we support at the moment
1690         if (h245Address.GetTag() != H225_TransportAddress::e_ipAddress
1691 #if P_HAS_IPV6
1692                 && h245Address.GetTag() != H225_TransportAddress::e_ip6Address
1693 #endif
1694         ) {
1695                 PTRACE(1, "H225\tConnect of H245 failed: Unsupported transport");
1696                 return FALSE;
1697         }
1698
1699         // Already have the H245 channel up.
1700         if (controlChannel != NULL)
1701                 return TRUE;
1702
1703         PIPSocket::Address addr;
1704         WORD port;
1705         GetSignallingChannel()->GetLocalAddress().GetIpAndPort(addr, port);
1706         if (addr) {
1707                 if (h323debug)
1708                         cout << "Using " << addr << " for outbound H.245 transport" << endl;
1709                 controlChannel = new MyH323TransportTCP(endpoint, addr);
1710         } else
1711                 controlChannel = new H323TransportTCP(endpoint);
1712         if (!controlChannel->SetRemoteAddress(h245Address)) {
1713                 PTRACE(1, "H225\tCould not extract H245 address");
1714                 delete controlChannel;
1715                 controlChannel = NULL;
1716                 return FALSE;
1717         }
1718         if (!controlChannel->Connect()) {
1719                 PTRACE(1, "H225\tConnect of H245 failed: " << controlChannel->GetErrorText());
1720                 delete controlChannel;
1721                 controlChannel = NULL;
1722                 return FALSE;
1723         }
1724
1725         controlChannel->StartControlChannel(*this);
1726         return TRUE;
1727 }
1728
1729 #ifdef H323_H450
1730 void MyH323Connection::OnReceivedLocalCallHold(int linkedId)
1731 {
1732         if (on_hold)
1733                 on_hold(GetCallReference(), (const char *)GetCallToken(), 1);
1734 }
1735
1736 void MyH323Connection::OnReceivedLocalCallRetrieve(int linkedId)
1737 {
1738         if (on_hold)
1739                 on_hold(GetCallReference(), (const char *)GetCallToken(), 0);
1740 }
1741 #endif
1742
1743 void MyH323Connection::MyHoldCall(BOOL isHold)
1744 {
1745         if (((holdHandling & H323_HOLD_NOTIFY) != 0) || ((holdHandling & H323_HOLD_Q931ONLY) != 0)) {
1746                 PBYTEArray x ((const BYTE *)(isHold ? "\xF9" : "\xFA"), 1);
1747                 H323SignalPDU signal;
1748                 signal.BuildNotify(*this);
1749                 signal.GetQ931().SetIE((Q931::InformationElementCodes)39 /* Q931::NotifyIE */, x);
1750                 if (h323debug)
1751                         cout << "Sending " << (isHold ? "HOLD" : "RETRIEVE") << " notification: " << signal << endl;
1752                 if ((holdHandling & H323_HOLD_Q931ONLY) != 0) {
1753                         PBYTEArray rawData;
1754                         signal.GetQ931().RemoveIE(Q931::UserUserIE);
1755                         signal.GetQ931().Encode(rawData);
1756                         signallingChannel->WritePDU(rawData);
1757                 } else
1758                         WriteSignalPDU(signal);
1759         }
1760 #ifdef H323_H450
1761         if ((holdHandling & H323_HOLD_H450) != 0) {
1762                 if (isHold)
1763                         h4504handler->HoldCall(TRUE);
1764                 else if (IsLocalHold())
1765                         h4504handler->RetrieveCall();
1766         }
1767 #endif
1768 }
1769
1770
1771 /* MyH323_ExternalRTPChannel */
1772 MyH323_ExternalRTPChannel::MyH323_ExternalRTPChannel(MyH323Connection & connection,
1773                                                         const H323Capability & capability,
1774                                                         Directions direction,
1775                                                         unsigned id)
1776         : H323_ExternalRTPChannel::H323_ExternalRTPChannel(connection, capability, direction, id)
1777 {
1778         struct rtp_info *info;
1779
1780         /* Determine the Local (A side) IP Address and port */
1781         info = on_external_rtp_create(connection.GetCallReference(), (const char *)connection.GetCallToken());
1782         if (!info) {
1783                 cout << "\tERROR: on_external_rtp_create failure" << endl;
1784                 return;
1785         } else {
1786                 localIpAddr = info->addr;
1787                 localPort = info->port;
1788                 /* tell the H.323 stack */
1789                 SetExternalAddress(H323TransportAddress(localIpAddr, localPort), H323TransportAddress(localIpAddr, localPort + 1));
1790                 /* clean up allocated memory */
1791                 free(info);
1792         }
1793
1794         /* Get the payload code */
1795         OpalMediaFormat format(capability.GetFormatName(), FALSE);
1796         payloadCode = format.GetPayloadType();
1797 }
1798
1799 MyH323_ExternalRTPChannel::~MyH323_ExternalRTPChannel()
1800 {
1801         if (h323debug) {
1802                 cout << "\tExternalRTPChannel Destroyed" << endl;
1803         }
1804 }
1805
1806 BOOL MyH323_ExternalRTPChannel::Start(void)
1807 {
1808         /* Call ancestor first */
1809         if (!H323_ExternalRTPChannel::Start()) {
1810                 return FALSE;
1811         }
1812
1813         if (h323debug) {
1814                 cout << "\t\tExternal RTP Session Starting" << endl;
1815                 cout << "\t\tRTP channel id " << sessionID << " parameters:" << endl;
1816         }
1817
1818         /* Collect the remote information */
1819         H323_ExternalRTPChannel::GetRemoteAddress(remoteIpAddr, remotePort);
1820
1821         if (h323debug) {
1822                 cout << "\t\t-- remoteIpAddress: " << remoteIpAddr << endl;
1823                 cout << "\t\t-- remotePort: " << remotePort << endl;
1824                 cout << "\t\t-- ExternalIpAddress: " << localIpAddr << endl;
1825                 cout << "\t\t-- ExternalPort: " << localPort << endl;
1826         }
1827         /* Notify Asterisk of remote RTP information */
1828         on_start_rtp_channel(connection.GetCallReference(), (const char *)remoteIpAddr.AsString(), remotePort,
1829                 (const char *)connection.GetCallToken(), (int)payloadCode);
1830         return TRUE;
1831 }
1832
1833 BOOL MyH323_ExternalRTPChannel::OnReceivedAckPDU(const H245_H2250LogicalChannelAckParameters & param)
1834 {
1835         if (h323debug) {
1836                 cout << "       MyH323_ExternalRTPChannel::OnReceivedAckPDU" << endl;
1837         }
1838
1839         if (H323_ExternalRTPChannel::OnReceivedAckPDU(param)) {
1840                 GetRemoteAddress(remoteIpAddr, remotePort);
1841                 if (h323debug) {
1842                         cout << "               -- remoteIpAddress: " << remoteIpAddr << endl;
1843                         cout << "               -- remotePort: " << remotePort << endl;
1844                 }
1845                 on_start_rtp_channel(connection.GetCallReference(), (const char *)remoteIpAddr.AsString(),
1846                                 remotePort, (const char *)connection.GetCallToken(), (int)payloadCode);
1847                 return TRUE;
1848         }
1849         return FALSE;
1850 }
1851
1852 #ifdef H323_H450
1853 MyH4504Handler::MyH4504Handler(MyH323Connection &_conn, H450xDispatcher &_disp)
1854         :H4504Handler(_conn, _disp)
1855 {
1856         conn = &_conn;
1857 }
1858
1859 void MyH4504Handler::OnReceivedLocalCallHold(int linkedId)
1860 {
1861         if (conn) {
1862                 conn->Lock();
1863                 conn->OnReceivedLocalCallHold(linkedId);
1864                 conn->Unlock();
1865         }
1866 }
1867
1868 void MyH4504Handler::OnReceivedLocalCallRetrieve(int linkedId)
1869 {
1870         if (conn) {
1871                 conn->Lock();
1872                 conn->OnReceivedLocalCallRetrieve(linkedId);
1873                 conn->Unlock();
1874         }
1875 }
1876 #endif
1877
1878
1879 /** IMPLEMENTATION OF C FUNCTIONS */
1880
1881 /**
1882  * The extern "C" directive takes care for
1883  * the ANSI-C representation of linkable symbols
1884  */
1885
1886 extern "C" {
1887
1888 int h323_end_point_exist(void)
1889 {
1890         if (!endPoint) {
1891                 return 0;
1892         }
1893         return 1;
1894 }
1895
1896 void h323_end_point_create(void)
1897 {
1898         channelsOpen = 0;
1899         logstream = new PAsteriskLog();
1900         localProcess = new MyProcess();
1901         localProcess->Main();
1902 }
1903
1904 void h323_gk_urq(void)
1905 {
1906         if (!h323_end_point_exist()) {
1907                 cout << " ERROR: [h323_gk_urq] No Endpoint, this is bad" << endl;
1908                 return;
1909         }
1910         endPoint->RemoveGatekeeper();
1911 }
1912
1913 void h323_debug(int flag, unsigned level)
1914 {
1915         if (flag) {
1916                 PTrace:: SetLevel(level);
1917         } else {
1918                 PTrace:: SetLevel(0);
1919         }
1920 }
1921
1922 /** Installs the callback functions on behalf of the PBX application */
1923 void h323_callback_register(setup_incoming_cb           ifunc,
1924                                                         setup_outbound_cb               sfunc,
1925                                                         on_rtp_cb                               rtpfunc,
1926                                                         start_rtp_cb                    lfunc,
1927                                                         clear_con_cb                    clfunc,
1928                                                         chan_ringing_cb                 rfunc,
1929                                                         con_established_cb              efunc,
1930                                                         receive_digit_cb                dfunc,
1931                                                         answer_call_cb                  acfunc,
1932                                                         progress_cb                             pgfunc,
1933                                                         rfc2833_cb                              dtmffunc,
1934                                                         hangup_cb                               hangupfunc,
1935                                                         setcapabilities_cb              capabilityfunc,
1936                                                         setpeercapabilities_cb  peercapabilityfunc,
1937                                                         onhold_cb                               holdfunc)
1938 {
1939         on_incoming_call = ifunc;
1940         on_outgoing_call = sfunc;
1941         on_external_rtp_create = rtpfunc;
1942         on_start_rtp_channel = lfunc;
1943         on_connection_cleared = clfunc;
1944         on_chan_ringing = rfunc;
1945         on_connection_established = efunc;
1946         on_receive_digit = dfunc;
1947         on_answer_call = acfunc;
1948         on_progress = pgfunc;
1949         on_set_rfc2833_payload = dtmffunc;
1950         on_hangup = hangupfunc;
1951         on_setcapabilities = capabilityfunc;
1952         on_setpeercapabilities = peercapabilityfunc;
1953         on_hold = holdfunc;
1954 }
1955
1956 /**
1957  * Add capability to the capability table of the end point.
1958  */
1959 int h323_set_capabilities(const char *token, int cap, int dtmf_mode, struct ast_codec_pref *prefs, int pref_codec)
1960 {
1961         MyH323Connection *conn;
1962
1963         if (!h323_end_point_exist()) {
1964                 cout << " ERROR: [h323_set_capablities] No Endpoint, this is bad" << endl;
1965                 return 1;
1966         }
1967         if (!token || !*token) {
1968                 cout << " ERROR: [h323_set_capabilities] Invalid call token specified." << endl;
1969                 return 1;
1970         }
1971
1972         PString myToken(token);
1973         conn = (MyH323Connection *)endPoint->FindConnectionWithLock(myToken);
1974         if (!conn) {
1975                 cout << " ERROR: [h323_set_capabilities] Unable to find connection " << token << endl;
1976                 return 1;
1977         }
1978         conn->SetCapabilities((/*conn->bridging ? conn->redir_capabilities :*/ cap), dtmf_mode, prefs, pref_codec);
1979         conn->Unlock();
1980
1981         return 0;
1982 }
1983
1984 /** Start the H.323 listener */
1985 int h323_start_listener(int listenPort, struct sockaddr_in bindaddr)
1986 {
1987
1988         if (!h323_end_point_exist()) {
1989                 cout << "ERROR: [h323_start_listener] No Endpoint, this is bad!" << endl;
1990                 return 1;
1991         }
1992
1993         PIPSocket::Address interfaceAddress(bindaddr.sin_addr);
1994         if (!listenPort) {
1995                 listenPort = 1720;
1996         }
1997         /** H.323 listener */
1998         H323ListenerTCP *tcpListener;
1999         tcpListener = new H323ListenerTCP(*endPoint, interfaceAddress, (WORD)listenPort);
2000         if (!endPoint->StartListener(tcpListener)) {
2001                 cout << "ERROR: Could not open H.323 listener port on " << ((H323ListenerTCP *) tcpListener)->GetListenerPort() << endl;
2002                 delete tcpListener;
2003                 return 1;
2004         }
2005         cout << "  == H.323 listener started" << endl;
2006         return 0;
2007 };
2008
2009 int h323_set_alias(struct oh323_alias *alias)
2010 {
2011         char *p;
2012         char *num;
2013         PString h323id(alias->name);
2014         PString e164(alias->e164);
2015         char *prefix;
2016
2017         if (!h323_end_point_exist()) {
2018                 cout << "ERROR: [h323_set_alias] No Endpoint, this is bad!" << endl;
2019                 return 1;
2020         }
2021
2022         cout << "== Adding alias \"" << h323id << "\" to endpoint" << endl;
2023         endPoint->AddAliasName(h323id);
2024         endPoint->RemoveAliasName(localProcess->GetUserName());
2025
2026         if (!e164.IsEmpty()) {
2027                 cout << "== Adding E.164 \"" << e164 << "\" to endpoint" << endl;
2028                 endPoint->AddAliasName(e164);
2029         }
2030         if (strlen(alias->prefix)) {
2031                 p = prefix = strdup(alias->prefix);
2032                 while((num = strsep(&p, ",")) != (char *)NULL) {
2033                         cout << "== Adding Prefix \"" << num << "\" to endpoint" << endl;
2034                         endPoint->SupportedPrefixes += PString(num);
2035                         endPoint->SetGateway();
2036                 }
2037                 if (prefix)
2038                         free(prefix);
2039         }
2040         return 0;
2041 }
2042
2043 void h323_set_id(char *id)
2044 {
2045         PString h323id(id);
2046
2047         if (h323debug) {
2048                 cout << "  == Using '" << h323id << "' as our H.323ID for this call" << endl;
2049         }
2050         /* EVIL HACK */
2051         endPoint->SetLocalUserName(h323id);
2052 }
2053
2054 void h323_show_tokens(void)
2055 {
2056         cout << "Current call tokens: " << setprecision(2) << endPoint->GetAllConnections() << endl;
2057 }
2058
2059 /** Establish Gatekeeper communiations, if so configured,
2060   *     register aliases for the H.323 endpoint to respond to.
2061   */
2062 int h323_set_gk(int gatekeeper_discover, char *gatekeeper, char *secret)
2063 {
2064         PString gkName = PString(gatekeeper);
2065         PString pass = PString(secret);
2066         H323TransportUDP *rasChannel;
2067
2068         if (!h323_end_point_exist()) {
2069                 cout << "ERROR: [h323_set_gk] No Endpoint, this is bad!" << endl;
2070                 return 1;
2071         }
2072
2073         if (!gatekeeper) {
2074                 cout << "Error: Gatekeeper cannot be NULL" << endl;
2075                 return 1;
2076         }
2077         if (strlen(secret)) {
2078                 endPoint->SetGatekeeperPassword(pass);
2079         }
2080         if (gatekeeper_discover) {
2081                 /* discover the gk using multicast */
2082                 if (endPoint->DiscoverGatekeeper(new MyH323TransportUDP(*endPoint))) {
2083                         cout << "== Using " << (endPoint->GetGatekeeper())->GetName() << " as our Gatekeeper." << endl;
2084                 } else {
2085                         cout << "Warning: Could not find a gatekeeper." << endl;
2086                         return 1;
2087                 }
2088         } else {
2089                 rasChannel = new MyH323TransportUDP(*endPoint);
2090
2091                 if (!rasChannel) {
2092                         cout << "Error: No RAS Channel, this is bad" << endl;
2093                         return 1;
2094                 }
2095                 if (endPoint->SetGatekeeper(gkName, rasChannel)) {
2096                         cout << "== Using " << (endPoint->GetGatekeeper())->GetName() << " as our Gatekeeper." << endl;
2097                 } else {
2098                         cout << "Error registering with gatekeeper \"" << gkName << "\". " << endl;
2099                         /* XXX Maybe we should fire a new thread to attempt to re-register later and not kill asterisk here? */
2100                         return 1;
2101                 }
2102         }
2103         return 0;
2104 }
2105
2106 /** Send a DTMF tone over the H323Connection with the
2107   * specified token.
2108   */
2109 void h323_send_tone(const char *call_token, char tone)
2110 {
2111         if (!h323_end_point_exist()) {
2112                 cout << "ERROR: [h323_send_tone] No Endpoint, this is bad!" << endl;
2113                 return;
2114         }
2115         PString token = PString(call_token);
2116         endPoint->SendUserTone(token, tone);
2117 }
2118
2119 /** Make a call to the remote endpoint.
2120   */
2121 int h323_make_call(char *dest, call_details_t *cd, call_options_t *call_options)
2122 {
2123         int res;
2124         PString token;
2125         PString host(dest);
2126
2127         if (!h323_end_point_exist()) {
2128                 return 1;
2129         }
2130
2131         res = endPoint->MyMakeCall(host, token, &cd->call_reference, call_options);
2132         memcpy((char *)(cd->call_token), (const unsigned char *)token, token.GetLength());
2133         return res;
2134 };
2135
2136 int h323_clear_call(const char *call_token, int cause)
2137 {
2138         H225_ReleaseCompleteReason dummy;
2139         H323Connection::CallEndReason r = H323Connection::EndedByLocalUser;
2140         MyH323Connection *connection;
2141         const PString currentToken(call_token);
2142
2143         if (!h323_end_point_exist()) {
2144                 return 1;
2145         }
2146
2147         if (cause) {
2148                 r = H323TranslateToCallEndReason((Q931::CauseValues)(cause), dummy);
2149         }
2150
2151         connection = (MyH323Connection *)endPoint->FindConnectionWithLock(currentToken);
2152         if (connection) {
2153                 connection->SetCause(cause);
2154                 connection->SetCallEndReason(r);
2155                 connection->Unlock();
2156         }
2157         endPoint->ClearCall(currentToken, r);
2158         return 0;
2159 };
2160
2161 /* Send Alerting PDU to H.323 caller */
2162 int h323_send_alerting(const char *token)
2163 {
2164         const PString currentToken(token);
2165         H323Connection * connection;
2166
2167         if (h323debug) {
2168                 cout << "\tSending alerting" << endl;
2169         }
2170         connection = endPoint->FindConnectionWithLock(currentToken);
2171         if (!connection) {
2172                 cout << "No connection found for " << token << endl;
2173                 return -1;
2174         }
2175         connection->AnsweringCall(H323Connection::AnswerCallPending);
2176         connection->Unlock();
2177         return 0;
2178 }
2179
2180 /* Send Progress PDU to H.323 caller */
2181 int h323_send_progress(const char *token)
2182 {
2183         const PString currentToken(token);
2184         H323Connection * connection;
2185
2186         connection = endPoint->FindConnectionWithLock(currentToken);
2187         if (!connection) {
2188                 cout << "No connection found for " << token << endl;
2189                 return -1;
2190         }
2191 #if 1
2192         ((MyH323Connection *)connection)->MySendProgress();
2193 #else
2194         connection->AnsweringCall(H323Connection::AnswerCallDeferredWithMedia);
2195 #endif
2196         connection->Unlock();
2197         return 0;
2198 }
2199
2200 /** This function tells the h.323 stack to either
2201     answer or deny an incoming call */
2202 int h323_answering_call(const char *token, int busy)
2203 {
2204         const PString currentToken(token);
2205         H323Connection * connection;
2206
2207         connection = endPoint->FindConnectionWithLock(currentToken);
2208
2209         if (!connection) {
2210                 cout << "No connection found for " << token << endl;
2211                 return -1;
2212         }
2213         if (!busy) {
2214                 if (h323debug) {
2215                         cout << "\tAnswering call " << token << endl;
2216                 }
2217                 connection->AnsweringCall(H323Connection::AnswerCallNow);
2218         } else {
2219                 if (h323debug) {
2220                         cout << "\tdenying call " << token << endl;
2221                 }
2222                 connection->AnsweringCall(H323Connection::AnswerCallDenied);
2223         }
2224         connection->Unlock();
2225         return 0;
2226 }
2227
2228 int h323_soft_hangup(const char *data)
2229 {
2230         PString token(data);
2231         BOOL result;
2232         cout << "Soft hangup" << endl;
2233         result = endPoint->ClearCall(token);
2234         return result;
2235 }
2236
2237 /* alas, this doesn't work :( */
2238 void h323_native_bridge(const char *token, const char *them, char *capability)
2239 {
2240         H323Channel *channel;
2241         MyH323Connection *connection = (MyH323Connection *)endPoint->FindConnectionWithLock(token);
2242
2243         if (!connection) {
2244                 cout << "ERROR: No connection found, this is bad" << endl;
2245                 return;
2246         }
2247
2248         cout << "Native Bridge:  them [" << them << "]" << endl;
2249
2250         channel = connection->FindChannel(connection->sessionId, TRUE);
2251         connection->bridging = TRUE;
2252         connection->CloseLogicalChannelNumber(channel->GetNumber());
2253
2254         connection->Unlock();
2255         return;
2256
2257 }
2258
2259 int h323_hold_call(const char *token, int is_hold)
2260 {
2261         MyH323Connection *conn = (MyH323Connection *)endPoint->FindConnectionWithLock(token);
2262         if (!conn) {
2263                 cout << "ERROR: No connection found, this is bad" << endl;
2264                 return -1;
2265         }
2266         conn->MyHoldCall((BOOL)is_hold);
2267         conn->Unlock();
2268         return 0;
2269 }
2270
2271 #undef cout
2272 #undef endl
2273 void h323_end_process(void)
2274 {
2275         if (endPoint) {
2276                 endPoint->ClearAllCalls();
2277                 endPoint->RemoveListener(NULL);
2278                 delete endPoint;
2279                 endPoint = NULL;
2280         }
2281         if (localProcess) {
2282                 delete localProcess;
2283                 localProcess = NULL;
2284                 close(_timerChangePipe[0]);
2285                 close(_timerChangePipe[1]);
2286         }
2287         if (logstream) {
2288                 PTrace::SetLevel(0);
2289                 PTrace::SetStream(&cout);
2290                 delete logstream;
2291                 logstream = NULL;
2292         }
2293 }
2294
2295 } /* extern "C" */
2296