ast_h323.cpp 38 KB

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