call.cpp
上传用户:hnnddl
上传日期:2007-01-06
资源大小:3580k
文件大小:56k
源码类别:

IP电话/视频会议

开发平台:

WINDOWS

  1. /*
  2.  * $Revision: 1.26 $
  3.  * $Date: 1999/03/17 18:05:31 $
  4.  */
  5. ////////////////////////////////////////////////////////////////
  6. //               Copyright (c) 1996-98 Lucent Technologies    //
  7. //                       All Rights Reserved                  //
  8. //                                                            //
  9. //                       THIS IS UNPUBLISHED                  //
  10. //                       PROPRIETARY SOURCE                   //
  11. //                   CODE OF Lucent Technologies              //
  12. // AND elemedia   //
  13. //                                                            //
  14. ////////////////////////////////////////////////////////////////
  15. //
  16. ////////////////////////////////////////////////////////////////
  17. // Example programs are provided soley to demonstrate one     //
  18. // possible use of the stack libraries and are included for   //
  19. // instructional purposes only.  You are free to use, modify  //
  20. // and/or redistribute any portion of code in the example     //
  21. // programs.  However, such examples are not intended to      //
  22. // represent production quality code.                         //
  23. //                                                            //
  24. // THE COPYRIGHT HOLDERS PROVIDE THESE EXAMPLE PROGRAMS       //
  25. // "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED     //
  26. // OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     //
  27. // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A            //
  28. // PARTICULAR PURPOSE.                                        //
  29. ////////////////////////////////////////////////////////////////
  30. #include "exchange.h"
  31. #include "call.h"
  32. #include "msg.h"
  33. #include "api/h225ie.h"
  34. #include <assert.h>
  35. #if (defined(WIN32))
  36. #include <winsock.h>
  37. #elif defined(VXWORKS)
  38. #else
  39. // Include the following line in uw2.1.0
  40. #if defined(sun)
  41. extern "C" int gethostname(char *name, int len);
  42. #endif
  43. #if defined(__hpux)
  44. #include <wchar.h>
  45. #else
  46. #include <wctype.h>
  47. #endif
  48. #endif
  49. #if (defined(ENABLE_BENCHMARKS))
  50. #include "perf.h"
  51. #endif
  52. #ifdef USE_RAS
  53. extern int seqno;    
  54. #endif
  55. /*ARGSUSED*/
  56. H323Call::H323Call(Exchange* ex,int h225_id, int h245_id, 
  57. H225CSEndpointType& ep, int tt, char *display, int outgoing_call,
  58. ProtReturnCode& result) :
  59. H225CSProtocol(h225_id,ep,result,display),
  60. H245Protocol(h245_id,tt,result),
  61. MessageQueue(0,0,0)
  62. {
  63. LOG("H323Call::H323Calln");
  64. LOG("terminal_type = %dn",tt);
  65. if (!PROT_IS_SUCCESS(result))
  66. {
  67. LOG("Constructor failed result = 0x%xn", result);
  68. return;
  69. }
  70. cap_done = 0;
  71. olc_done = 0;
  72. msd_done = 0;
  73. audio_session = NULL;
  74. exchange = ex;
  75. endsession_sent = 0;
  76. call_dropped = 0;
  77. faststart_state  = FAST_START_STATE_DISABLED;
  78. do_faststart = ex->use_faststart;
  79. do_tunneling = ex->use_tunneling;
  80. do_overlapsend = ex->use_overlapsend;
  81. do_alerting = ex->use_alerting;
  82. do_proceeding = ex->use_callproc;
  83. remote_name[0] = '';
  84. phone[0] = '';
  85. src_phone[0] = '';
  86. // transfer related
  87. transfer_flag = FALSE;
  88. transfer_invoke_id = -1;
  89. transfer_call_id[0] = '';
  90. transfer_parent_index = -1;
  91. #if !defined(VXWORKS)
  92. char hostname[256];
  93. struct hostent *hent_p;
  94. gethostname(hostname,sizeof(hostname));
  95. hent_p = gethostbyname(hostname);
  96. if(hent_p == NULL)
  97. {
  98. LOG("gethostbyname failed on %s error %dn", hostname,errno);
  99. return;
  100. }
  101. #endif
  102. if (strlen(display))
  103. {
  104. display_str = new char[strlen(display) + 1];
  105. strcpy(display_str, display);
  106. }
  107. else
  108. {
  109. display_str = NULL;
  110. }
  111. #if defined(VXWORKS)
  112. {
  113. char hostname[256];
  114. sprintf(hostname,"vxworks%d",sysProcNumGet());
  115. if_ip_addr = hostGetByName(hostname);
  116. //if_ip_addr = inet_addr("127.0.1.2");
  117. }
  118. #else
  119. int i = 0;
  120. while(hent_p->h_addr_list[i])
  121. {
  122. LOG("Interface %d, ip = 0x%xn",
  123. i,*(unsigned long *)(hent_p->h_addr_list[i]));
  124. ++i;
  125. }
  126. if_ip_addr = *(unsigned long *)(hent_p->h_addr_list[0]);
  127. #endif
  128. is_outgoing_call = outgoing_call;
  129. if (outgoing_call)
  130. {
  131. // Set the conference ID and the Call ID. 
  132. // IP and index just for demonstration purposes.
  133. sprintf(confid, "%00000008x%0004d", 
  134. exchange->confid_prefix, h225_id);
  135. callid.SetCallID((unsigned char *)confid,16);
  136. H225CSProtocol::SetCallID(callid);
  137. H225CSProtocol::SetConfID((unsigned char *)confid,16);
  138. }
  139. #if defined(ENABLE_BENCHMARKS)
  140. get_current_time(st_sec,st_msec);
  141. end_sec = end_msec = 0;
  142. max_stack_size = cur_stack_size = 0;
  143. #endif
  144. audio_session_flag = 0;
  145. memset(&remote_lc0_addr, 0, sizeof(remote_lc0_addr));
  146. memset(&local_lc0_addr, 0, sizeof(local_lc0_addr));
  147. LOG("Defaulting to interface ip address 0x%xn", if_ip_addr);
  148. if (do_faststart)
  149. {
  150. if (CreateRtpSession())
  151. {
  152. result = (unsigned int)-1;
  153. }
  154. }
  155. }
  156. H323Call::~H323Call()
  157. {
  158. LOG("H323Call::~H323Calln");
  159. if (audio_session)
  160. {
  161. delete audio_session;
  162. }
  163. delete display_str;
  164. }
  165. void
  166. H323Call::NotifyMessage(USER_MESSAGE& msg)
  167. {
  168. LOG("H323Call::NotifyMessagen");
  169. ProtReturnCode ret;
  170. void *data = (void*)(msg.lParam);
  171. if (call_dropped)
  172. {
  173. if (data)
  174. {
  175. delete (CBData*)data;
  176. }
  177. return;
  178. }
  179. int myindex = ((H225CSProtocol *)this)->GetIdentifier() - ID_H225;
  180. if (msg.message == PROT_CALL_MSG)
  181. {
  182. switch(msg.wParam)
  183. {
  184. case CB_Q931_EVENT:
  185. {
  186. Q931Evt *info = (Q931Evt *)data;
  187. LOG("CB_Q931_EVENT, event type = %dn", info->event_type);
  188. Q931Message *q931msg = NULL;
  189. int type = 0;
  190. if (info->event_type == Q931EVENT_ERROR)
  191. {
  192. LOG("Got Error from Q931Engine, STATE_NULL,"
  193. " error = 0x%xn",
  194. info->err->GetError());
  195. // Check if the H.245 is listening
  196. if(GetCallDirection() == DIR_INCOMING &&
  197. (!((H245Protocol *)this)->IsConnectionReady()))
  198. {
  199. exchange->StopListening(
  200. ((H245Protocol *)this)->GetIdentifier());
  201. DropQ931(RCR_UNDEFINED);
  202. goto end_call;
  203. }
  204. if (info->event_type == Q931EVENT_MESSAGE)
  205. {
  206. q931msg = info->message;
  207. if (q931msg)
  208. {
  209. q931msg->GetType(type);
  210. LOG("Q931msg = 0x%xn", type);
  211. }
  212. }
  213. if (info->event_type == Q931EVENT_MESSAGE && 
  214. q931msg && type == MESSAGE_Q932_FACILITY)
  215. {
  216. H225CSFacilityUUIE *f = (H225CSFacilityUUIE*)info->ie;
  217. LOG("In call.cpp received FACILITYn");
  218. // Now check for supp services
  219. H4501SuppService *ss;
  220. // ProtReturnCode ret;
  221. int sscount;
  222. ret = f->GetNumH450SupplementaryServices(sscount);
  223. if(!PROT_IS_SUCCESS(ret))
  224. {
  225. LOG("Failed in GetNumH450SupplementaryServices - " 
  226. "getting num supp services ret=%dn", ret);
  227. }
  228. if(sscount != 0)
  229. {
  230. ss = new H4501SuppService[sscount];
  231. ret = f->GetH450SupplementaryServices(ss, sscount);
  232. if(!PROT_IS_SUCCESS(ret))
  233. {
  234. printf("Failed in GetH450SupplementaryServices - " 
  235. "getting supplementary services ret=0x%xn", ret);
  236. //return
  237. else 
  238. {
  239. int isII;
  240. unsigned int ip_addr;
  241. isII = isInitiateInvoke(ss, transfer_invoke_id,
  242. transfer_call_id, ip_addr, phone);
  243. if(isII == 1) {
  244. LOG("Placing a call to transferredTon");
  245. exchange->PlaceTransferedToCall(myindex, ip_addr, 
  246. phone, transfer_invoke_id, transfer_call_id);
  247. } else if(isII == -1) {
  248. break;
  249. }
  250. }
  251. delete [] ss;
  252. }
  253. }
  254. switch(info->new_state)
  255. {
  256. // TODO: FASTSTART FALLBACK incase we recv a facility message
  257. case STATE_NULL:
  258. {
  259. LOG("Got ReleaseComplete,STATE_NULLn");
  260. if (((H245Protocol *)this)->IsConnectionReady())
  261. if ( endsession_sent == 0)
  262. {
  263. LOG("ERROR..Deleting call before "
  264. " end sessionn");
  265. }
  266. }
  267. else
  268. {
  269. // Check if the H.245 is listening
  270. if(GetCallDirection() == DIR_INCOMING &&
  271. (!((H245Protocol *)this)->IsConnectionReady()))
  272. {
  273. exchange->StopListening(
  274. ((H245Protocol *)this)->GetIdentifier());
  275. }
  276. goto end_call;
  277. /*NOTREACHED*/
  278. }
  279. break;
  280. case STATE_CALL_PRESENT:
  281. {
  282. assert(info->event_type == Q931EVENT_MESSAGE);
  283. assert(q931msg != NULL);
  284. if (q931msg && type == MESSAGE_SETUP)
  285. {
  286. LOG("Line <%d> STATE_CALL_PRESENTn", myindex);
  287. LOG("MESSAGE_SETUPn");
  288. H225CSSetupUUIE *s = (H225CSSetupUUIE*)info->ie;
  289. struct sockaddr_in saddr;
  290. int alias_count = 0;
  291. if (s->GetH245Transport((struct sockaddr *)&saddr)
  292. == H225CS_SUCCESS)
  293. {
  294. LOG("H245Transport Address 0x%x, %dn",
  295. saddr.sin_addr.s_addr, 
  296. ntohs(saddr.sin_port));
  297. }
  298. // V2
  299. // Set the call id if the remote end is version 1.
  300. int remote_version = H225_VERSION_INVALID;
  301. s->GetProtocolID(remote_version);
  302. LOG("remote end is a Version %d endpointn", 
  303. remote_version);
  304. #if defined(GK19980320) // this is internal test, do not define it
  305. // Set the Call ID.
  306. char tmp[80];
  307. sprintf(tmp, "%00000008x%00000008d", 
  308.  exchange->confid_prefix, myindex);
  309. callid.SetCallID((unsigned char *)tmp,16);
  310. // Set the callid in the protocol object..
  311. // This dummy callid will be used for all
  312. // q931 messages we send out.
  313. SetCallID(callid);
  314. #else
  315. if (remote_version == H225_VERSION_1)
  316. {
  317. // Set the Call ID.
  318. char tmp[80];
  319. sprintf(tmp, "%00000008x%00000008d", 
  320.  exchange->confid_prefix, myindex);
  321. callid.SetCallID((unsigned char *)tmp,16);
  322. // Set the callid in the protocol object..
  323. // This dummy callid will be used for all
  324. // q931 messages we send out.
  325. SetCallID(callid);
  326. }
  327. else
  328. {
  329. // Get the call id from setup message and 
  330. // fill it in.
  331. if (!PROT_IS_SUCCESS(s->GetCallID(callid)))
  332. {
  333. LOG("Unable to retrieve call id n");
  334. LocalHangup();
  335. goto end_call;
  336. }
  337. }
  338. #endif
  339. // Get and print the Display information element.
  340. Q931IE *ie_display;
  341. if (PROT_IS_SUCCESS(q931msg->GetIE(IE_DISPLAY,
  342.  ie_display)))
  343. {
  344. int len = sizeof(remote_name);
  345. if (PROT_IS_SUCCESS(((Q931DisplayIE *)ie_display)->
  346. GetDisplayString(remote_name, len)))
  347. {
  348. remote_name[len] = 0;
  349. }
  350. }
  351. LOG("Remote Ends DISPLAY is %s.n", remote_name);
  352. // Get and print the Bearer capability element.
  353. Q931IE *ie_bc;
  354. if (PROT_IS_SUCCESS(q931msg->GetIE(IE_BEARER_CAPABILITY, 
  355. ie_bc)))
  356. {
  357. H225CSBearerCapabilityIE *_ie_bc = 
  358. (H225CSBearerCapabilityIE *)ie_bc;
  359. int cap = 0, rate = 0, value = 0;
  360. LOG("Got bearer capsn");
  361. _ie_bc->GetInfoTransferCap(cap);
  362. LOG("tinfo transfer cap = %dn", cap);
  363. _ie_bc->GetInfoTransferRate(rate);
  364. LOG("tinfo transfer rate = %dn", rate);
  365. if (rate == BC_ITR_MULTIRATE)
  366. {
  367. _ie_bc->GetRateMultiplier(value);
  368. LOG("trate multiplier = %dn", value);
  369. }
  370. _ie_bc->GetLayer1Prot(value);
  371. LOG("tlayer 1 protocol = %dn", value);
  372. _ie_bc->GetCodingStd(value);
  373. LOG("tCoding Standard = %dn", value);
  374. }
  375. else
  376. {
  377. LOG("Bearer capability not set !!!n");
  378. }
  379. // Get and print the remote endpoint type
  380. H225CSEndpointType ep;
  381. if (PROT_IS_SUCCESS(s->GetSrcInfo(ep)))
  382. {
  383. if (PROT_IS_SUCCESS(ep.IsGatekeeperSet()))
  384. {
  385. LOG("Remote end is a Gatekeepern");
  386. }
  387. if (PROT_IS_SUCCESS(ep.IsTerminalSet()))
  388. {
  389. LOG("Remote end is a Terminaln");
  390. }
  391. if (PROT_IS_SUCCESS(ep.IsGatewaySet()))
  392. {
  393. LOG("Remote end is a Gatewayn");
  394. }
  395. if (PROT_IS_SUCCESS(ep.IsMCUSet()))
  396. {
  397. LOG("Remote end is an MCUn");
  398. }
  399. }
  400. // get and print the source aliases
  401. if (PROT_IS_SUCCESS(s->GetNumSrcAddrs(alias_count)) &&
  402. alias_count > 0)
  403. {
  404. LOG("Got %d source alias addressesn", alias_count);
  405. int count = alias_count;
  406. H225CSAliasAddress *a = 
  407. new  H225CSAliasAddress[count];
  408. ret = s->GetSrcAddrs(a, count);
  409. assert(count == alias_count);
  410. if (!PROT_IS_SUCCESS(ret))
  411. {
  412. LOG("Unable to extract source address"
  413. " 0x%xn", ret);
  414. }
  415. else
  416. {
  417. unsigned short *id;
  418. unsigned short len;
  419. int j = 0;
  420. while (j < alias_count)
  421. {
  422. ProtReturnCode ret;
  423. if (a[j].GetType() == AAT_H323_ID)
  424. {
  425. if ((ret = a[j].GetH323ID(id, len)) != 
  426. H225CS_SUCCESS)
  427. {
  428. LOG("Unable to extract the H323ID"
  429.  " 0x%xn", ret);
  430. }
  431. else
  432. {
  433. char string[512];
  434. int string_length = 512;
  435. char q = '?';
  436. int ret_length;
  437. #if (defined(WIN32))
  438. if ((ret_length = WideCharToMultiByte(
  439. CP_ACP,
  440. 0,
  441. id,
  442. len,
  443. string,
  444. string_length,
  445. &q,
  446. NULL)) == FALSE)
  447. {
  448. LOG("WideChartoMultiByte"
  449. " conversion failed %dn", 
  450. GetLastError());
  451. }
  452. else
  453. {
  454. string[ret_length] = '';
  455. LOG("source H323ID = %sn",
  456. string);
  457. printf("%sn",string);
  458. strncpy(remote_name, string, 
  459. sizeof(remote_name) -1);
  460. }
  461. #elif defined(VXWORKS)
  462. #else
  463. int i;
  464. for (i = 0; i < len; i++)
  465. {
  466. #if defined(__hpux)
  467. if (iswalnum(id[i]))
  468. #else
  469. if (iswascii(id[i]))
  470. #endif
  471. {
  472. string[i] = (char) id[i];
  473. }
  474. else
  475. {
  476. break;
  477. }
  478. }
  479. string[i] = '';
  480. LOG("source H323ID = %sn", string);
  481. printf("%sn",string);
  482. strncpy(remote_name, string, 
  483. sizeof(remote_name) -1);
  484. #endif
  485. }
  486. }
  487. else if (a[j].GetType() == AAT_E164)
  488. {
  489. char *tmp_phone; 
  490. if ((ret = a[j].GetE164(tmp_phone, len)) != 
  491. H225CS_SUCCESS)
  492. {
  493. LOG("Unable to extract the E164 alias"
  494.  " 0x%xn", ret);
  495. }
  496. else
  497. {
  498. tmp_phone[len] = '';
  499. SetSrcPhoneNumber(tmp_phone);
  500. LOG("src phone = %sn",
  501. src_phone);
  502. }
  503. }
  504. ++j;
  505. }
  506. }
  507. delete [] a;
  508. }
  509. // get and print the destination aliases
  510. if (PROT_IS_SUCCESS(s->GetNumDstAddrs(alias_count)) &&
  511. alias_count > 0)
  512. {
  513. LOG("Got %d dest alias addressesn", alias_count);
  514. int count = alias_count;
  515. H225CSAliasAddress *a = 
  516. new  H225CSAliasAddress[count];
  517. ret = s->GetDstAddrs(a, count);
  518. assert(count == alias_count);
  519. if (!PROT_IS_SUCCESS(ret))
  520. {
  521. LOG("Unable to extract destination address"
  522. " 0x%xn", ret);
  523. }
  524. else
  525. {
  526. unsigned short *id;
  527. unsigned short len;
  528. int j = 0;
  529. while (j < alias_count)
  530. {
  531. ProtReturnCode ret;
  532. if (a[j].GetType() == AAT_H323_ID)
  533. {
  534. if ((ret = a[j].GetH323ID(id, len)) != 
  535. H225CS_SUCCESS)
  536. {
  537. LOG("Unable to extract the destination H323ID"
  538.  " 0x%xn", ret);
  539. }
  540. else
  541. {
  542. char string[512];
  543. int string_length = 512;
  544. char q = '?';
  545. int ret_length;
  546. #if (defined(WIN32))
  547. if ((ret_length = WideCharToMultiByte(
  548. CP_ACP,
  549. 0,
  550. id,
  551. len,
  552. string,
  553. string_length,
  554. &q,
  555. NULL)) == FALSE)
  556. {
  557. LOG("WideChartoMultiByte"
  558. " conversion failed %dn", 
  559. GetLastError());
  560. }
  561. else
  562. {
  563. string[ret_length] = '';
  564. LOG("destination end H323ID = %sn",
  565. string);
  566. printf("%sn",string);
  567. //strncpy(remote_name, string, 
  568. // sizeof(remote_name) -1);
  569. }
  570. #elif defined(VXWORKS)
  571. #else
  572. int i;
  573. for (i = 0; i < len; i++)
  574. {
  575. #if defined(__hpux)
  576. if (iswalnum(id[i]))
  577. #else
  578. if (iswascii(id[i]))
  579. #endif
  580. {
  581. string[i] = (char) id[i];
  582. }
  583. else
  584. {
  585. break;
  586. }
  587. }
  588. string[i] = '';
  589. LOG("destination end H323ID = %sn", string);
  590. //strncpy(remote_name, string, 
  591. // sizeof(remote_name) -1);
  592. #endif
  593. }
  594. }
  595. else if (a[j].GetType() == AAT_E164)
  596. {
  597. char *tmp_phone; 
  598. if ((ret = a[j].GetE164(tmp_phone, len)) != 
  599. H225CS_SUCCESS)
  600. {
  601. LOG("Unable to extract the E164 destination alias"
  602.  " 0x%xn", ret);
  603. }
  604. else
  605. {
  606. tmp_phone[len] = '';
  607. SetPhoneNumber(tmp_phone);
  608. LOG("dest phone = %sn",
  609. phone);
  610. }
  611. }
  612. ++j;
  613. }
  614. }
  615. delete [] a;
  616. }
  617. // Set the conference identifier to be
  618. // the same as the incoming call's cid.
  619. unsigned char *cid_p;
  620. int cid_len;
  621. s->GetConfID(cid_p, cid_len);
  622. SetConfID(cid_p, cid_len);
  623. // check if this a call coming from transferred (B endpoint)
  624. H4501SuppService *ss;
  625. ProtReturnCode ret;
  626. int sscount;
  627. ret = s->GetNumH450SupplementaryServices(sscount);
  628. if(!PROT_IS_SUCCESS(ret))
  629. {
  630. printf("Failed in GetH450SupplementaryServices - " 
  631. "getting supplementary services ret=0x%xn", ret);
  632. }
  633. else if(sscount != 0)
  634. {
  635. ss = new H4501SuppService[sscount];
  636. ret = s->GetH450SupplementaryServices(ss, sscount);
  637. if(!PROT_IS_SUCCESS(ret))
  638. {
  639. printf("Failed in GetH450SupplementaryServices - " 
  640. "getting supplementary services ret=0x%xn", ret);
  641. printf("%s: line %dn",__FILE__,__LINE__);
  642. else 
  643. {
  644. LOG("Got %d Supplementary Servicesn",sscount);
  645. LOG("=============================n");
  646. LOG("Extract Supplementary Services msgn");
  647. extractedSS *extSS = new extractedSS;
  648. extSS->tH4501SuppService(&ss[0]);
  649. if (extSS->ssNumROSs > 0)
  650. {
  651. if (extSS->ssROS[0].type == ROS_INVOKE)
  652. {
  653. if (extSS->ssROS[0].code == CTOT_SETUP) 
  654. {
  655. transfer_invoke_id = extSS->ssROS[0].InvokeId;
  656. strncpy(transfer_call_id, extSS->ssROS[0].Arg.CallID, 5);
  657. SetTransferFlag(TRUE);
  658. }
  659. }
  660. }
  661. delete extSS;
  662. }
  663. delete [] ss;
  664. }
  665. else
  666. {
  667. LOG("There are no Supplementary Services in this SETUPn"); 
  668. }
  669. #if defined(USE_RAS)
  670. if (exchange->IsGKRegistered())
  671. {
  672. SendARQdata *arq_data = new SendARQdata;
  673. if (src_phone[0])
  674. strcpy(arq_data->e164src, src_phone);
  675. else // ARQ needs the srcInfo field anyway, so fill it up 
  676. strcpy(arq_data->e164src, "999999");
  677. strcpy(arq_data->e164dst, phone);
  678. arq_data->index = GetApplicationPrivate();
  679. // ask the RAS protocol handler to send ARQ for this call
  680. exchange->SendToExchange(PROT_CALL_MSG, CB_SEND_ARQ,
  681. (unsigned long)arq_data);
  682. // not registered, sent ALERTING
  683. else if (do_alerting && (Q931SendAlerting() < 0))
  684. goto end_call;
  685. else 
  686. {
  687. if (Q931SendConnect() < 0)
  688. goto end_call;
  689. else
  690. printf("Connected to %sn", remote_name);
  691. }
  692. #else // defined(USE_RAS)
  693. if (do_overlapsend)
  694. {
  695. // We have to send back a setupack.
  696. if (Q931SendSetupAck() < 0)
  697. goto end_call;
  698. }
  699. else
  700. {
  701. if (do_alerting)
  702. {
  703. if (Q931SendAlerting() < 0)
  704. goto end_call;
  705. }
  706. else 
  707. {
  708. if (Q931SendConnect() < 0)
  709. goto end_call;
  710. else
  711. printf("Connected to %sn", remote_name);
  712. }
  713. }
  714. #endif //defined(USE_RAS)
  715. }
  716. }
  717. break;
  718. case STATE_INCOMING_CALL_PROCEEDING:
  719. {
  720. LOG("Line <%d> STATE_INCOMING_CALL_PROCEEDINGn", myindex);
  721. }
  722. break;
  723. case STATE_OUTGOING_CALL_PROCEEDING:
  724. {
  725. LOG("Line <%d> STATE_OUTGOING_CALL_PROCEEDINGn", myindex);
  726. }
  727. break;
  728. case STATE_CALL_RECEIVED:
  729. {
  730. #if 1
  731. LOG("Line <%d> STATE_CALL_RECEIVEDn", myindex);
  732. if (Q931SendConnect() < 0)
  733. goto end_call;
  734. else
  735. printf("Connected to %sn", remote_name);
  736. #endif
  737. }
  738. break;
  739. case STATE_CALL_INITIATED:
  740. {
  741. LOG("Line <%d> STATE_CALL_INITIATEDn", myindex);
  742. }
  743. break;
  744.  case STATE_OVERLAP_SENDING:
  745. {
  746. LOG("Line <%d> STATE_OVERLAP_SENDINGn", myindex);
  747. if (Q931SendInformation("12345#") < 0)
  748. goto end_call;
  749. }
  750. break;
  751.  case STATE_OVERLAP_RECEIVING:
  752. {
  753. LOG("Line <%d> STATE_OVERLAP_RECEIVINGn", myindex);
  754. if (q931msg && type == MESSAGE_INFORMATION)
  755. {
  756. LOG("Got Information messagen");
  757. // Fetch the keypad facility ie.
  758. LOG("Fetching keytpad facility ien");
  759. Q931IE *ie_keypad_fac;
  760. if (PROT_IS_SUCCESS(q931msg->GetIE(
  761. IE_KEYPAD_FACILITY,ie_keypad_fac)))
  762. {
  763. Q931KeypadFacilityIE *ie_kp = 
  764. (Q931KeypadFacilityIE*)ie_keypad_fac;
  765. char info[256];
  766. int length = sizeof(info) - 1;
  767. if (PROT_IS_SUCCESS(ie_kp->GetKeypadInfo(
  768. info,length)))
  769. {
  770. info[length] = 0;
  771. LOG("Keypad fac[%s]n",info);
  772. }
  773. }
  774. else
  775. {
  776. LOG("keytpad facility ie fetch failedn");
  777. }
  778. Q931IE *ie_snd_comp;
  779. if (PROT_IS_SUCCESS(q931msg->GetIE(
  780. IE_SENDING_COMPLETE,ie_snd_comp)))
  781. {
  782. printf("Got sending_complete...!n");
  783. if (Q931SendConnect() < 0)
  784. goto end_call;
  785. }
  786. }
  787. }
  788. break;
  789. case STATE_CALL_DELIVERED:
  790. {
  791. LOG("Line <%d> STATE_CALL_DELIVEREDn", myindex);
  792. }
  793. break;
  794. case STATE_CALL_ACTIVE:
  795. {
  796. LOG("Line <%d> STATE_CALL_ACTIVEn", myindex);
  797. // Q.931 negotiations succeeded.
  798. // Q.931 Call is active, but faststart is still
  799. // pending.. disable it, something went wrong..
  800. if (do_faststart && 
  801. faststart_state == FAST_START_STATE_PENDING)
  802. {
  803. faststart_state = FAST_START_STATE_DISABLED;
  804. }
  805. if (GetCallDirection() == DIR_OUTGOING &&
  806. info->new_state != info->old_state)
  807. {
  808. assert (type == MESSAGE_CONNECT);
  809. assert(q931msg != NULL);
  810. // Connect message from the remote end...
  811. // Get the H245 address and open a logical channel.
  812. H225CSConnectUUIE *c = 
  813. (H225CSConnectUUIE*)info->ie;
  814. assert(c != NULL);
  815. struct sockaddr_in saddr;
  816. if (c->GetH245Transport(
  817. (struct sockaddr *)&saddr) == H225CS_SUCCESS)
  818. {
  819. LOG("H245Transport Address 0x%x, %dn",
  820. saddr.sin_addr.s_addr, 
  821. ntohs(saddr.sin_port));
  822. remote_lc0_addr = saddr;
  823. // Connect only if no faststart or faststart
  824. // failed.
  825. if (!do_faststart ||
  826. (do_faststart && faststart_state == 
  827. FAST_START_STATE_DISABLED))
  828. {
  829. ret = exchange->Connect(
  830. (sockaddr *)&remote_lc0_addr, 
  831. (H245Protocol *)this);
  832. if (!PROT_IS_PENDING(ret))
  833. {
  834. exchange->NotifyConnectionStatus(
  835. (H245Protocol*)this,ret);
  836. }
  837. }
  838. }
  839. // Get the Display Information element..
  840. Q931IE *ie_display;
  841. if (PROT_IS_SUCCESS(q931msg->GetIE(IE_DISPLAY, 
  842. ie_display)))
  843. {
  844. int len = sizeof(remote_name);
  845. if (PROT_IS_SUCCESS(ie_display->
  846. GetContent(remote_name, len)))
  847. {
  848. remote_name[len] = 0;
  849. }
  850. }
  851. LOG("Remote Ends DISPLAY is %s.n", remote_name);
  852. printf("Connected to %sn",remote_name);
  853. // now check if this is a call that was transferred successfully
  854. if (transfer_flag)
  855. {
  856. H4501SuppService *ss;
  857. ProtReturnCode ret;
  858. int sscount;
  859. ret = c->GetNumH450SupplementaryServices(sscount);
  860. if(!PROT_IS_SUCCESS(ret))
  861. {
  862. LOG("Failed in GetNumH450SupplementaryServices - "
  863. "getting num supp services ret=%dn", ret);
  864. break;
  865. }
  866. if(sscount != 0)
  867. {
  868. ss = new H4501SuppService[sscount];
  869. ret = c->GetH450SupplementaryServices(ss, sscount);
  870. if(!PROT_IS_SUCCESS(ret))
  871. {
  872. printf("Failed in GetH450SupplementaryServices - "
  873. "getting supplementary services ret=0x%xn", ret);
  874. //return
  875. else 
  876. {
  877. LOG("Got %d Supplementary Servicesn",sscount);
  878. LOG("=============================n");
  879. LOG("Extract Supplementary Services msgn");
  880. extractedSS *extSS = new extractedSS;
  881. extSS->tH4501SuppService(&ss[0]);
  882. if (extSS->ssNumROSs > 0)
  883. {
  884. if (extSS->ssROS[0].type == ROS_RETURN_RESULT)
  885. {
  886. if (extSS->ssROS[0].code == CTOT_SETUP) 
  887. {
  888. // transfer_invoke_id = extSS->ssROS[0].InvokeId;
  889. // strncpy(transfer_call_id, extSS->ssROS[0].Arg.CallID, 5);
  890. // LOG("Dropping the transferring calln");
  891. exchange->DropTranferringCall(transfer_parent_index);
  892. }
  893. }
  894. }
  895. delete extSS;
  896. }
  897. delete [] ss;
  898. }
  899. else
  900. {
  901. LOG("There are no Supplementary Services in this SETUPn"); 
  902. }
  903. }
  904. }
  905. }
  906. break;
  907. }
  908. }
  909. break;
  910. case CB_CONNECTION_CLOSED:
  911. {
  912. LOG("CB_CONNECTION_CLOSEDn");
  913. XchgConnectionClosed *info = (XchgConnectionClosed *)data;
  914. if (info->conn->GetIdentifier() == 
  915. ((H225CSProtocol *)this)->GetIdentifier())
  916. {
  917. // check for the h.245 connection closure here...
  918. if (((H245Protocol *)this)->IsConnectionReady())
  919. {
  920. if (endsession_sent != 0)
  921. {
  922. H245SigCommand *cmd ; 
  923. H245SigCommand::Factory(cmd, CMDT_END_SESSION);
  924. ((H245SigEndSessionCommand *)cmd)->SetType(ESTY_DISCONNECT);
  925. SendCommand(*cmd);
  926. delete cmd;
  927. endsession_sent = 1;
  928. }
  929. }
  930. else
  931. {
  932. // Check if the H.245 is listening
  933. if(GetCallDirection() == DIR_INCOMING &&
  934. (!((H245Protocol *)this)->IsConnectionReady()))
  935. {
  936. exchange->StopListening(
  937. ((H245Protocol *)this)->GetIdentifier());
  938. }
  939. LOG("H.225 Connection closedn");
  940. goto end_call;
  941. }
  942. else
  943. {
  944. assert(info->conn->GetIdentifier() == 
  945. ((H245Protocol *)this)->GetIdentifier());
  946. LOG("H.245 Connection closedn");
  947. }
  948. }
  949. break;
  950. // Exchange indicates the state of the H.245 logical channel 0
  951. // tcp connection.
  952. case CB_CONNECTION_STATUS:
  953. {
  954. LOG("CB_CONNECTION_STATUSn");
  955. XchgConnectionStatus *info = (XchgConnectionStatus *)data;
  956. if (info->conn->GetIdentifier() ==  // is this a H.225 connection?
  957. ((H225CSProtocol *)this)->GetIdentifier())
  958. {
  959. // either something went wrong with the connection
  960. if (PROT_IS_ERROR(info->status))
  961. {
  962. LOG("H225 Connect Failedn");
  963. goto end_call;
  964. }
  965. else // or the nonblocking connection succeeded.
  966. {
  967. LOG("H225 Connect Succeededn");
  968. // Create the bearer capability information element..
  969. Q931Message q931msg(MESSAGE_SETUP);
  970. H225CSBearerCapabilityIE bc;
  971. bc.SetInfoTransferCap(BC_ITC_SPEECH);
  972. bc.SetInfoTransferRate(BC_ITR_PACKET);
  973. bc.SetLayer1Prot(BC_L1P_ULAW);
  974. bc.SetCodingStd(BC_CS_ISO);
  975. q931msg.SetIE(bc);
  976. H225CSSetupUUIE setup_uuie(*(H225CSProtocol *)this);
  977. // Plug in the destination Address in the setup uuie.
  978. // If the phone number field is set.. then set
  979. // the destinationAddress.
  980. if (phone[0] != '')
  981. {
  982. Q931CalledPartyNumberIE cpn;
  983. cpn.SetNumberParams(NUMBERTYPE_UNKNOWN, 
  984. NUMBERINGPLAN_ISDN);
  985. cpn.SetDigits((char *)phone, strlen(phone));
  986. q931msg.SetIE(cpn);
  987. H225CSAliasAddress e164;
  988. LOG("Phone number set in Setup message(%s)n",
  989. phone);
  990. e164.SetE164(phone,(unsigned short)strlen(phone));
  991. setup_uuie.AddDstAddr(e164);
  992. }
  993. if (config->e164src[0] != '')
  994. {
  995. Q931CallingPartyNumberIE cpn;
  996. // here we generate the originator phone number
  997. // in real life you should get that from the callerID (e.g. PSTN)
  998. // and pass it here
  999. char tmp_phone[256];
  1000. sprintf(tmp_phone, "%s%0004d", config->e164src,
  1001. GetApplicationPrivate());
  1002. SetSrcPhoneNumber(tmp_phone);
  1003. cpn.SetNumberParams(NUMBERTYPE_UNKNOWN, 
  1004. NUMBERINGPLAN_ISDN);
  1005. cpn.SetDigits((char *)src_phone, strlen(src_phone));
  1006. q931msg.SetIE(cpn);
  1007. H225CSAliasAddress e164;
  1008.   LOG("Originator Phone number set in Setup message(%s)n",
  1009. src_phone);
  1010. e164.SetE164(src_phone,(unsigned short)strlen(src_phone));
  1011. setup_uuie.AddSrcAddr(e164);
  1012. }
  1013. struct sockaddr_in dst_ip_addr;
  1014. struct sockaddr_in src_ip_addr;
  1015. // Warning! Unixware libnsl is buggy, the following call
  1016. // can block indefinitely.
  1017. ((H225CSProtocol *)this)->GetConnectionAddrs(
  1018. (struct sockaddr*)&src_ip_addr,
  1019. (struct sockaddr*)&dst_ip_addr);
  1020. char *src_addr_str = inet_ntoa(src_ip_addr.sin_addr);
  1021. LOG("source IP set in Setup mesg <%s>:<%u>n", 
  1022. src_addr_str, ntohs(src_ip_addr.sin_port));
  1023. char *rem_addr_str = inet_ntoa(dst_ip_addr.sin_addr);
  1024. LOG("dest IP set in Setup msg <%s>:<%u>n", 
  1025. rem_addr_str, ntohs(dst_ip_addr.sin_port));
  1026. // d.sin_family = AF_INET;
  1027. // d.sin_port = htons(1720);
  1028. #if (!defined(BUGGY_NSL)) // returns 0 in remote address...
  1029. setup_uuie.SetDstCallSig((sockaddr*)&dst_ip_addr);
  1030. #endif
  1031. setup_uuie.SetSrcCallSig((sockaddr*)&src_ip_addr);
  1032. if (transfer_flag)
  1033. {
  1034. // Set the H4501 Supplimentary Services in setup_uuie
  1035. H4501SuppService *pss;
  1036. pss = ctSetupInvoke(transfer_invoke_id, &transfer_call_id[0]);
  1037. //pss = ctSetupInvoke(transfer_invoke_id, &transfer_call_id[0]);
  1038. ret = setup_uuie.AddH450SupplementaryService(*pss);
  1039. if (!PROT_IS_SUCCESS(ret))
  1040. {
  1041. LOG("Failed to set setup request ");
  1042. LOG("AddH450SupplementaryService, error = 0x%xn", ret);
  1043. }
  1044. delete pss;
  1045. }
  1046. // Check if we are to attempt fast start. If so,
  1047. // then create the list of OLCs and send it in 
  1048. // the setup message.
  1049. if (do_faststart)
  1050. {
  1051. if (InitFastStartProposal(&setup_uuie) == 0)
  1052. {
  1053. faststart_state = FAST_START_STATE_PENDING;
  1054. }
  1055. }
  1056. // Send the setup request..
  1057. ret = InvokeCCPrim(CCP_SETUP_REQUEST, &q931msg, 
  1058. setup_uuie);
  1059. if (!PROT_IS_SUCCESS(ret))
  1060. {
  1061. LOG("Failed to send setup messagen");
  1062. goto end_call;
  1063. }
  1064. }
  1065. }
  1066. else  // it is not a H.225 TCP connection. It must be H.245 TCP connection
  1067. {
  1068. assert(info->conn->GetIdentifier() == 
  1069. ((H245Protocol *)this)->GetIdentifier());
  1070. // either something went wrong with the previous
  1071. // outgoing H.245 LC0 connection
  1072. if (PROT_IS_ERROR(info->status))
  1073. {
  1074. LOG("H245 Connect Failedn");
  1075. if (((H225CSProtocol *)this)->IsConnectionReady())
  1076. {
  1077. DropQ931(RCR_UNDEFINED);
  1078. goto end_call;
  1079. }
  1080. }
  1081. else // or the connection succeeded.
  1082. {
  1083. LOG("H245 Connect succeeded (LC0 Connected)n");
  1084. // TODO: FASTSTART FALLBACK....
  1085. // pick interface ip address.
  1086. sockaddr_in local_addr;
  1087. #if (!defined(BUGGY_NSL)) // unixware nsl is buggy, alas! no multihomed hosts...
  1088. if (PROT_IS_SUCCESS(
  1089. ((H245Protocol *)this)->GetConnectionAddrs
  1090. ((sockaddr*)&local_addr,NULL)))
  1091. {
  1092. if_ip_addr = local_addr.sin_addr.s_addr;
  1093. LOG("Using i/f 0x%x for this calln", if_ip_addr);
  1094. }
  1095. #endif
  1096. // Initiate capability exchange proceedures.
  1097. H245SigH225Cap mc;
  1098. H245SigCapTable ct;
  1099. H245SigCapDescs cd;
  1100. InitCapTable(ct);
  1101. InitCapDescs(cd);
  1102. InitMuxCap(mc);
  1103. ret =  SendTermCaps(&mc, &ct, &cd);
  1104. if (!PROT_IS_SUCCESS(ret))
  1105. {
  1106. LOG("SendTermCaps failed..n");
  1107. LocalHangup();
  1108. goto end_call;
  1109. }
  1110. }
  1111. }
  1112. }
  1113. break;
  1114. case CB_NEW_CONNECTION:
  1115. {
  1116. LOG("LC0_CONNECTEDn");
  1117. XchgNewConnection *info = (XchgNewConnection *)data;
  1118. // We will get only H.245 new connections here...
  1119. remote_lc0_addr = info->new_addr;
  1120. // First accept the connection from the remote end.
  1121. ret = exchange->AcceptConnection(
  1122. info->conn_ref,(H245Protocol *)this);
  1123. if (!PROT_IS_SUCCESS(ret))
  1124. {
  1125. LOG("H245 accept connection failed..n");
  1126. LocalHangup();
  1127. goto end_call;
  1128. }
  1129. // Initiate capability exchange proceedures.
  1130. H245SigH225Cap mc;
  1131. H245SigCapTable ct;
  1132. H245SigCapDescs cd;
  1133. InitCapTable(ct);
  1134. InitCapDescs(cd);
  1135. InitMuxCap(mc);
  1136. ret =  SendTermCaps(&mc, &ct, &cd);
  1137. if (!PROT_IS_SUCCESS(ret))
  1138. {
  1139. LOG("SendTermCaps failed.. after H245Accept connn");
  1140. LocalHangup();
  1141. goto end_call;
  1142. }
  1143. }
  1144. break;
  1145. case CB_REMOTE_TERM_CAPS:
  1146. {
  1147. LOG("CB_REMOTE_TERM_CAPSn");
  1148. // Just acknowledge the remote terminals capabilities.
  1149. // TODO: parse them and see if they are acceptable.
  1150. RemoteTermCaps *info = (RemoteTermCaps *)data;
  1151. PrintCaps(*info->cap_table);
  1152. ret = AckTermCaps();
  1153. if (!PROT_IS_SUCCESS(ret))
  1154. {
  1155. LOG("Failed to ack remote caps, error = 0x%xn",
  1156. ret);
  1157. LocalHangup();
  1158. goto end_call;
  1159. }
  1160. // both ends have exchanged caps successfully.
  1161. if (++cap_done == 2)
  1162. {
  1163. ret = DetermineMS();
  1164. if (!PROT_IS_SUCCESS(ret))
  1165. {
  1166. LOG("Failed to ack remote caps,"
  1167. " error = 0x%xn", ret);
  1168. LocalHangup();
  1169. goto end_call;
  1170. }
  1171. }
  1172. }
  1173. break;
  1174. case CB_TERM_CAPS_ACK:
  1175. {
  1176. LOG("CB_TERM_CAPS_ACKn");
  1177. // Remote end has accepted our terminal capabilities.
  1178. // both ends have exchanged caps successfully.
  1179. if (++cap_done == 2)
  1180. {
  1181. ret = DetermineMS();
  1182. if (!PROT_IS_SUCCESS(ret) && !PROT_IS_PENDING(ret))
  1183. {
  1184. LOG("Failure in DetermineMS,"
  1185. " error = 0x%xn", ret);
  1186. LocalHangup();
  1187. goto end_call;
  1188. }
  1189. }
  1190. }
  1191. break;
  1192. case CB_TERM_CAPS_REJECT:
  1193. {
  1194. LOG("CB_TERM_CAPS_REJECTn");
  1195. TermCapsReject *info = (TermCapsReject *)data;
  1196. LOG("Remote end rejected our terminal capabilities"
  1197. " cause = %d, direction = %dn", info->cause, info->direction);
  1198. LocalHangup();
  1199. goto end_call;
  1200. }
  1201. /*NOTREACHED*/
  1202. break;
  1203. case CB_OUT_LC_ERROR:
  1204. {
  1205. LOG("CB_OUT_LC_ERRORn");
  1206. }
  1207. break;
  1208. case CB_MSD_ERROR:
  1209. {
  1210. LOG("CB_MSD_ERRORn");
  1211. MSDError *info = (MSDError *)data;
  1212. LOG("Master slave determination failed," 
  1213. "error = 0x%lxn", info->error);
  1214. LocalHangup();
  1215. goto end_call;
  1216. }
  1217. /*NOTREACHED*/
  1218. break;
  1219. case CB_MSD_CONFIRM:
  1220. {
  1221. LOG("CB_MSD_CONFIRMn");
  1222. MSDConfirm *info = (MSDConfirm *)data;
  1223. if(msd_done)
  1224. {
  1225. break;
  1226. }
  1227. msd_done++;
  1228. LOG("Master slave determine succeeded,"
  1229. "decision = %sn",
  1230. (info->decision == MSDRES_MASTER) ?
  1231. "MASTER" : "SLAVE");
  1232. // Open a logical channel with the remote end 
  1233. // do to G.723 audio.
  1234. // First get the capability table entry corresponding
  1235. // to G723.1 from the capability table.
  1236. H245SigCapTable *ct= new H245SigCapTable;
  1237. ret = GetCapTable(*ct);
  1238. if (!PROT_IS_SUCCESS(ret))
  1239. {
  1240. LOG("Could not retrieve the cap table"
  1241. ", error = 0x%lxn", ret);
  1242. LocalHangup();
  1243. goto end_call;
  1244. }
  1245. H245SigCap *c = NULL;
  1246. H245SigCap::Factory(c,CAP_AUDIO,AUD_G7231);
  1247. assert(c != NULL);
  1248. ret = ct->GetCap(*c, G7231_INDEX);
  1249. if (!PROT_IS_SUCCESS(ret))
  1250. {
  1251. LOG("Could not get G.723 audio capability"
  1252. "from cap table, error = 0x%lxn", ret);
  1253. delete c;
  1254. LocalHangup();
  1255. goto end_call;
  1256. }
  1257. // Prepare the Data type to use with the out_lc_num
  1258. H245SigAudDataType *d = new H245SigAudDataType;
  1259. ret = d->Set(*(H245SigAudCap *)c);
  1260. if (!PROT_IS_SUCCESS(ret))
  1261. {
  1262. LOG("Could not set G.723 audio capability"
  1263. "in audio data type, error = 0x%lxn", ret);
  1264. delete c;
  1265. LocalHangup();
  1266. goto end_call;
  1267. }
  1268. delete c;
  1269. delete ct;
  1270. // Prepare the mux params to use with the out_lc_num.
  1271. H245SigH225Params m;
  1272. // Create an audio session if not already created
  1273. // and generate the local ends RTP/RTCP addresses.
  1274. if (!audio_session)
  1275. {
  1276. int status;
  1277. audio_session = new H245RTPSession("RTP:ELEMEDIA", 
  1278. G7231_RTP_PAYLOAD_TYPE,G7231_AUDIO_SAMPLING_RATE,status);
  1279. if (status)
  1280. {
  1281. LOG("new H245RTPSession failedd. status = 0x%xn",
  1282. status);
  1283. delete d;
  1284. LocalHangup();
  1285. goto end_call;
  1286. }
  1287. unsigned short rtp_port = 0, rtcp_port = 0;
  1288. audio_session->SetLocalPorts(if_ip_addr, 
  1289. rtp_port, rtcp_port);
  1290. rtcp_addr.sin_family = AF_INET;
  1291. rtcp_addr.sin_addr.s_addr = if_ip_addr;
  1292. rtcp_addr.sin_port = rtcp_port;
  1293. rtp_addr.sin_family = AF_INET;
  1294. rtp_addr.sin_addr.s_addr = if_ip_addr;
  1295. rtp_addr.sin_port = rtp_port;
  1296. audio_session->SetLocalPayloadType(
  1297. G7231_RTP_PAYLOAD_TYPE);
  1298. }
  1299. m.SetSessionID(PRI_SSID_AUDIO);
  1300. m.SetDynamicRTPPayloadType(G7231_RTP_PAYLOAD_TYPE);
  1301. m.SetSilenceSupp(FALSE);
  1302. m.SetMediaCtrlChan((struct sockaddr *)&rtcp_addr);
  1303. out_lc_num = 1;
  1304. ret = OpenLC(out_lc_num, 0, *d, m);
  1305. if (!PROT_IS_PENDING(ret) && PROT_IS_ERROR(ret))
  1306. {
  1307. LOG("Open LC failed, lcnum = %d"
  1308. " error = 0x%lxn", out_lc_num,ret);
  1309. }
  1310. delete d;
  1311. }
  1312. break;
  1313. case CB_IN_LC_ERROR:
  1314. {
  1315. LOG("CB_IN_LC_ERRORn");
  1316. LCError *info = (LCError *)data;
  1317. LOG("Error in ILCSE signalling entity,"
  1318. " lc = %d, error = %dn", info->lc_num, info->error);
  1319. LocalHangup();
  1320. goto end_call;
  1321. }
  1322. /*NOTREACHED*/
  1323. break;
  1324. case CB_OLC_REQUEST:
  1325. {
  1326. OLCReq *info = (OLCReq *)data;
  1327. int dtype;
  1328. int cap_type;
  1329. int cap_sub_type;
  1330. H245SigH225Params *mux;
  1331. int dynamic_rtp_pt = 0;
  1332. sockaddr_in remote_rtcp_addr;
  1333. H245SigG7231Cap *g7231;
  1334. H245SigCap *gen_cap;
  1335. LOG("CB_OLC_REQUESTn");
  1336. in_lc_num = info->lc_num;
  1337. assert(info->mux_params);
  1338. assert(info->data_type);
  1339. info->data_type->GetType(dtype,cap_type,cap_sub_type);
  1340. if ((dtype != DT_AUDIO) || (cap_type != CAP_AUDIO) ||
  1341.  cap_sub_type != AUD_G7231)
  1342. {
  1343. LOG("Remote end request data type that we don't supportn");
  1344. // Send OLC reject here...
  1345. RejectOpenLCReq(info->lc_num,
  1346. OLCRR_DATATYPE_NOT_SUPPORTED);
  1347. LocalHangup();
  1348. goto end_call;
  1349. }
  1350. H245SigCap::Factory(gen_cap,cap_type, cap_sub_type);
  1351. g7231 = (H245SigG7231Cap*)gen_cap;
  1352. assert(g7231 != NULL);
  1353. ((H245SigAudDataType *)info->data_type)->Get(*g7231);
  1354. mux = (H245SigH225Params*)info->mux_params;
  1355. ret = mux->GetDynamicRTPPayloadType(dynamic_rtp_pt);
  1356. if (mux->GetMediaCtrlChan((sockaddr*)&remote_rtcp_addr) !=
  1357. H245SIG_SUCCESS)
  1358. {
  1359. LOG("Remote has not supplied RTCP address");
  1360. RejectOpenLCReq(info->lc_num,OLCRR_UNSPECIFIED);
  1361. delete g7231;
  1362. LocalHangup();
  1363. goto end_call;
  1364. }
  1365. // Create an audio session if not already created
  1366. // and generate the local ends RTP/RTCP addresses.
  1367. if (!audio_session)
  1368. {
  1369. unsigned short rtp_port = 0, rtcp_port = 0;
  1370. int status;
  1371. audio_session = new H245RTPSession("RTP:ELEMEDIA", 
  1372. G7231_RTP_PAYLOAD_TYPE,G7231_AUDIO_SAMPLING_RATE,status);
  1373. if (status)
  1374. {
  1375. LOG("new H245RTPSession failedd. status = 0x%xn",
  1376. status);
  1377. delete g7231;
  1378. LocalHangup();
  1379. goto end_call;
  1380. }
  1381. audio_session->SetLocalPorts(if_ip_addr, 
  1382. rtp_port, rtcp_port);
  1383. rtcp_addr.sin_family = AF_INET;
  1384. rtcp_addr.sin_addr.s_addr = if_ip_addr;
  1385. rtcp_addr.sin_port = rtcp_port;
  1386. rtp_addr.sin_family = AF_INET;
  1387. rtp_addr.sin_addr.s_addr = if_ip_addr;
  1388. rtp_addr.sin_port = rtp_port;
  1389. }
  1390. audio_session->SetRemotePayloadType(dynamic_rtp_pt);
  1391. audio_session->SetRemotePorts(
  1392. remote_rtcp_addr.sin_addr.s_addr,
  1393. 0,remote_rtcp_addr.sin_port);
  1394. H245SigH225AckParams ack;
  1395. ack.SetSessionID(PRI_SSID_AUDIO);
  1396. ack.SetMediaChan((sockaddr*)&rtp_addr);
  1397. ack.SetMediaCtrlChan((sockaddr*)&rtcp_addr);
  1398. LOG("calling AckOpenLCReqn");
  1399. AckOpenLCReq(in_lc_num, &ack);
  1400. if (++olc_done == 2)
  1401. {
  1402. audio_session_flag = 1;
  1403. #if defined (ENABLE_BENCHMARKS)
  1404. get_current_time(end_sec,end_msec);
  1405. #endif
  1406. StartAudio();
  1407. }
  1408. delete g7231;
  1409. }
  1410. break;
  1411. case CB_OLC_REJECT:
  1412. {
  1413. LOG("CB_OLC_REJECTn");
  1414. OLCReject *info = (OLCReject *)data;
  1415. LOG("Remote end rejected our open channel request"
  1416. " lc = %d, reason = %dn", info->lc_num, info->reason);
  1417. LocalHangup();
  1418. goto end_call;
  1419. }
  1420. /*NOTREACHED*/
  1421. break;
  1422. case CB_OLC_ACK:
  1423. {
  1424. LOG("CB_OLC_ACKn");
  1425. OLCAck *info = (OLCAck *)data;
  1426. LOG("Open logical channel ack, lc = %dn", 
  1427. info->lc_num);
  1428. H245SigH225AckParams *ap = info->ack_params;
  1429. struct sockaddr_in rrtp_addr;
  1430. struct sockaddr_in rrtcp_addr;
  1431. ret = ap->GetMediaChan((sockaddr*)&rrtp_addr);
  1432. ret = ap->GetMediaCtrlChan((sockaddr*)&rrtcp_addr);
  1433. assert(audio_session != NULL);
  1434. audio_session->SetRemotePorts(rrtp_addr.sin_addr.s_addr,
  1435. rrtp_addr.sin_port,rrtcp_addr.sin_port);
  1436. if (++olc_done == 2)
  1437. {
  1438. audio_session_flag = 1;
  1439. #if defined (ENABLE_BENCHMARKS)
  1440. get_current_time(end_sec,end_msec);
  1441. #endif
  1442. StartAudio();
  1443. }
  1444. }
  1445. break;
  1446. case CB_CLOSE_OUT_LC_REQUEST:
  1447. {
  1448. LOG("CB_CLOSE_OUT_LC_REQUESTn");
  1449. }
  1450. break;
  1451. case CB_CLOSE_OUT_LC_ACK:
  1452. {
  1453. LOG("CB_CLOSE_OUT_LC_ACKn");
  1454. CloseXXX *info = (CloseXXX *)data;
  1455. LOG("Remote end acked close lc, lc = %dn",
  1456. info->lc_num);
  1457. }
  1458. break;
  1459. case CB_CLOSE_IN_LC:
  1460. {
  1461. LOG("CB_CLOSE_IN_LCn");
  1462. // remote end decided to close its lc, 
  1463. // we will close ours too...
  1464. CloseOutLC(out_lc_num);
  1465. }
  1466. break;
  1467. case CB_CLOSE_IN_LC_ACK:
  1468. {
  1469. LOG("CB_CLOSE_IN_LC_ACKn");
  1470. }
  1471. break;
  1472. case CB_CLOSE_IN_LC_REJECT:
  1473. {
  1474. LOG("CB_CLOSE_IN_LC_REJECTn");
  1475. }
  1476. break;
  1477. case CB_NOTIFY_CMD:
  1478. {
  1479. LOG("CB_NOTIFY_CMDn");
  1480. // check if an end session was generated from the remote end.
  1481. H245CMD *info = (H245CMD *)data;
  1482. int type = 0;
  1483. info->cmd->GetCommandType(type);
  1484. LOG("command type = %dn", type);
  1485. if (type == CMDT_END_SESSION) 
  1486. {
  1487. LOG("CMDT_END_SESSIONn");
  1488. // send an end session.
  1489. H245SigCommand *cmd ; 
  1490. H245SigCommand::Factory(cmd, CMDT_END_SESSION);
  1491. ((H245SigEndSessionCommand *)cmd)->SetType(
  1492. ESTY_DISCONNECT);
  1493. SendCommand(*cmd);
  1494. delete cmd;
  1495. endsession_sent = 1;
  1496. }
  1497. }
  1498. break;
  1499. case CB_NOTIFY_IND:
  1500. {
  1501. LOG("CB_NOTIFY_INDn");
  1502. }
  1503. break;
  1504. }
  1505. }
  1506. else if (msg.message == PROT_UI_MSG)
  1507. {
  1508. if ((msg.wParam == UI_CMD_EXIT) || 
  1509. (msg.wParam == UI_CMD_HANGUP))
  1510. {
  1511. if (msg.wParam == UI_CMD_HANGUP)
  1512. {
  1513. LocalHangup();
  1514. }
  1515. goto end_call;
  1516. } else if (msg.wParam == UI_CMD_FACILITY) {
  1517. UICmdFacility *info = (UICmdFacility *)data;
  1518. SendFacility(info->suppsvcs);
  1519. }
  1520. else if (msg.wParam == UI_CMD_CTRL)
  1521. {
  1522. }
  1523. }
  1524. if (data)
  1525. {
  1526. delete (CBData*)data;
  1527. }
  1528. return;
  1529. end_call:
  1530. call_dropped = 1;
  1531. exchange->SendToExchange(PROT_EXCH_MSG, XC_CALL_DROPPED,
  1532. (unsigned long)this);
  1533. if (data)
  1534. {
  1535. delete (CBData*)data;
  1536. }
  1537. return;
  1538. }
  1539. int
  1540. H323Call::LocalHangup()
  1541. {
  1542. // Request from the user to drop the call. 
  1543. if (((H245Protocol *)this)->IsConnectionReady())
  1544. {
  1545. H245SigCommand *cmd ; 
  1546. H245SigCommand::Factory(cmd, CMDT_END_SESSION);
  1547. ((H245SigEndSessionCommand *)cmd)->SetType(ESTY_DISCONNECT);
  1548. LOG("Sending END_SESSIONn");
  1549. SendCommand(*cmd);
  1550. delete cmd;
  1551. endsession_sent = 1;
  1552. }
  1553. else
  1554. {
  1555. if(GetCallDirection() == DIR_INCOMING)
  1556. {
  1557. exchange->StopListening(
  1558. ((H245Protocol *)this)->GetIdentifier());
  1559. }
  1560. if(((H225CSProtocol *)this)->IsConnectionReady()) 
  1561. {
  1562. LOG("Sending Release completen");
  1563. DropQ931(RCR_UNDEFINED);
  1564. return(-1);
  1565. }
  1566. return -1;
  1567. }
  1568. void
  1569. H323Call::DropQ931(int rc_reason)
  1570. {
  1571. LOG("H323Call::DropQ931n");
  1572. LOG("rc_reason = %dn", rc_reason);
  1573. ProtReturnCode ret;
  1574. H225CSReleaseCompleteUUIE ie(*this);
  1575. ret = ie.SetReason(rc_reason);
  1576. if (!PROT_IS_SUCCESS(ret))
  1577. {
  1578. LOG("Failed to set release complete reason, error = 0x%xn", 
  1579. ret);
  1580. }
  1581. if (transfer_flag)
  1582. {
  1583. // Set the H4501 Supplimentary Services in setup_uuie
  1584. H4501SuppService *pss;
  1585. // invokeID is 0 for now until OSS fixes the bug
  1586. pss = ctInitiateReturnResult(transfer_invoke_id);
  1587. ret = ie.AddH450SupplementaryService(*pss);
  1588. if (!PROT_IS_SUCCESS(ret))
  1589. {
  1590. LOG("Failed to set setup request ");
  1591. LOG("AddH450SupplementaryService, error = 0x%xn", ret);
  1592. }
  1593. delete pss;
  1594. }
  1595. ret = InvokeCCPrim(CCP_RELEASE_REQUEST, NULL, ie);
  1596. if (!PROT_IS_SUCCESS(ret))
  1597. {
  1598. LOG("Failed to send release complete, error = 0x%xn", ret);
  1599. }
  1600. }
  1601. int
  1602. H323Call::Q931SendAlerting()
  1603. {
  1604. ProtReturnCode ret;
  1605. // send connect
  1606. assert(GetCallDirection() == DIR_INCOMING);
  1607. LOG("DIR_INCOMING, sending alertingn");
  1608. // Send the alerting message.
  1609. H225CSAlertingUUIE ie(*this);
  1610. if (do_faststart && faststart_state == FAST_START_STATE_PENDING)
  1611. {
  1612. if ((ie.AddOLC(fs_channels[FS_CHANNEL_OUTGOING]) != H245SIG_SUCCESS) ||
  1613. (ie.AddOLC(fs_channels[FS_CHANNEL_INCOMING]) != H245SIG_SUCCESS))
  1614. {
  1615. LOG("ERROR: Failed to add the fast start OLCs.n"); 
  1616. faststart_state = FAST_START_STATE_DISABLED;
  1617. return LocalHangup();
  1618. }
  1619. faststart_state = FAST_START_STATE_ENABLED;
  1620. }
  1621. ret = InvokeCCPrim(CCP_ALERTING_REQUEST, NULL, ie);
  1622. if (!PROT_IS_SUCCESS(ret))
  1623. {
  1624. LOG("Failed to send alerting, error = 0x%xn", ret);
  1625. return LocalHangup();
  1626. }
  1627. else
  1628. {
  1629. if (do_faststart && audio_session_flag == 0 && 
  1630. faststart_state == FAST_START_STATE_ENABLED)
  1631. {
  1632. audio_session_flag = 1;
  1633. #if defined (ENABLE_BENCHMARKS)
  1634. get_current_time(end_sec,end_msec);
  1635. #endif
  1636. StartAudio();
  1637. }
  1638. }
  1639. return 1;
  1640. }
  1641. int
  1642. H323Call::Q931SendSetupAck()
  1643. {
  1644. ProtReturnCode ret;
  1645. assert(GetCallDirection() == DIR_INCOMING);
  1646. LOG("DIR_INCOMING, sending setup_ackn");
  1647. ret = InvokeCCPrim(CCP_MORE_INFO_REQUEST, NULL);
  1648. if (!PROT_IS_SUCCESS(ret))
  1649. {
  1650. LOG("Failed to send setup_ack, error = 0x%xn", ret);
  1651. return LocalHangup();
  1652. }
  1653. return 1;
  1654. }
  1655. int
  1656. H323Call::Q931SendInformation(char *info)
  1657. {
  1658. ProtReturnCode ret;
  1659. Q931Message q931msg(MESSAGE_INFORMATION);
  1660. Q931KeypadFacilityIE ie_kp;
  1661. Q931IE snd_comp;
  1662. H225CSInformationUUIE info_uuie(*(H225CSProtocol *)this);
  1663. ie_kp.SetKeypadInfo(info,strlen(info));
  1664. // Sending Complete is a fixed length ie.
  1665. snd_comp.SetContent(IE_SENDING_COMPLETE,NULL,0);
  1666. if (!PROT_IS_SUCCESS(q931msg.SetIE(ie_kp)))
  1667. {
  1668. LOG("Error inserting keypad facility ie!n");
  1669. }
  1670. if (!PROT_IS_SUCCESS(q931msg.SetIE(snd_comp)))
  1671. {
  1672. LOG("Error inserting sending complete ie!n");
  1673. }
  1674. ret = InvokeCCPrim(CCP_INFO_REQUEST, &q931msg,info_uuie);
  1675. if (!PROT_IS_SUCCESS(ret))
  1676. {
  1677. LOG("Failed to send information, error = 0x%xn", ret);
  1678. return LocalHangup();
  1679. }
  1680. return 1;
  1681. }
  1682. int
  1683. H323Call::Q931SendProceeding()
  1684. {
  1685. ProtReturnCode ret;
  1686. // send proceeding
  1687. assert(GetCallDirection() == DIR_INCOMING);
  1688. LOG("DIR_INCOMING, sending proceedingn");
  1689. // Send the proceeding message.
  1690. H225CSCallProceedingUUIE ie(*this);
  1691. if (do_faststart && faststart_state == FAST_START_STATE_PENDING)
  1692. {
  1693. if ((ie.AddOLC(fs_channels[FS_CHANNEL_OUTGOING]) != H245SIG_SUCCESS) ||
  1694. (ie.AddOLC(fs_channels[FS_CHANNEL_INCOMING]) != H245SIG_SUCCESS))
  1695. {
  1696. LOG("ERROR: Failed to add the fast start OLCs.n"); 
  1697. faststart_state = FAST_START_STATE_DISABLED;
  1698. return LocalHangup();
  1699. }
  1700. faststart_state = FAST_START_STATE_ENABLED;
  1701. }
  1702. ret = InvokeCCPrim(CCP_PROCEEDING_REQUEST, NULL, ie);
  1703. if (!PROT_IS_SUCCESS(ret))
  1704. {
  1705. LOG("Failed to send proceeding,"
  1706. " error = 0x%xn", ret);
  1707. return LocalHangup();
  1708. }
  1709. else
  1710. {
  1711. if (do_faststart && audio_session_flag == 0 && 
  1712. faststart_state == FAST_START_STATE_ENABLED)
  1713. {
  1714. audio_session_flag = 1;
  1715. #if defined (ENABLE_BENCHMARKS)
  1716. get_current_time(end_sec,end_msec);
  1717. #endif
  1718. StartAudio();
  1719. }
  1720. }
  1721. return 1;
  1722. }
  1723. int 
  1724. H323Call::Q931SendConnect()
  1725. {
  1726. ProtReturnCode ret;
  1727. assert(GetCallDirection() == DIR_INCOMING);
  1728. LOG("DIR_INCOMING, sending connectn");
  1729. // Send the connect message.
  1730. H225CSConnectUUIE ie(*this);
  1731. if (do_faststart && faststart_state == FAST_START_STATE_PENDING)
  1732. {
  1733. if ((ie.AddOLC(fs_channels[FS_CHANNEL_OUTGOING]) != H245SIG_SUCCESS) ||
  1734. (ie.AddOLC(fs_channels[FS_CHANNEL_INCOMING]) != H245SIG_SUCCESS))
  1735. {
  1736. LOG("ERROR: Failed to add the fast start OLCs.n"); 
  1737. faststart_state = FAST_START_STATE_DISABLED;
  1738. return LocalHangup();
  1739. }
  1740. faststart_state = FAST_START_STATE_ENABLED;
  1741. }
  1742. //send the H.245 address if either, faststart is disabled, or
  1743. //if we refused the faststart the remote side sent us.
  1744. if (!do_faststart ||
  1745. do_faststart && faststart_state == FAST_START_STATE_DISABLED)
  1746. {
  1747. // First insert the H245address into the connect
  1748. // user to user information element.
  1749. memset(&local_lc0_addr, 0, sizeof(local_lc0_addr));
  1750. local_lc0_addr.sin_family = AF_INET;
  1751. // 07/01/97 Added support for multi-homed hosts..
  1752. #if (defined(BUGGY_NSL)) // Needed for unixware, alas! no multihomed hosts...
  1753. local_lc0_addr.sin_addr.s_addr = if_ip_addr;
  1754. #else
  1755. if (!PROT_IS_SUCCESS(
  1756. ((H225CSProtocol *)this)->GetConnectionAddrs(
  1757. (struct sockaddr*)&local_lc0_addr,
  1758. NULL)))
  1759. {
  1760. LOG("Can't get i/f ip addressn");
  1761. local_lc0_addr.sin_addr.s_addr = if_ip_addr;
  1762. }
  1763. else
  1764. {
  1765. LOG("Got i/f ip address, 0x%xn",
  1766. local_lc0_addr.sin_addr.s_addr);
  1767. if_ip_addr = local_lc0_addr.sin_addr.s_addr;
  1768. }
  1769. #endif
  1770. // Make the connection manager pick a port for
  1771. // us.
  1772. local_lc0_addr.sin_port = 0;
  1773. ret = exchange->Listen(
  1774. ((H245Protocol *)this)->GetIdentifier(),
  1775. (struct sockaddr *)&local_lc0_addr, 
  1776. LT_ONCE);
  1777. if (!PROT_IS_SUCCESS(ret))
  1778. {
  1779. LOG("Failed to create H.245 address error = 0x%xn",ret);
  1780. return LocalHangup();
  1781. }
  1782. ret = ie.SetH245Transport(
  1783. (struct sockaddr *)&local_lc0_addr);
  1784. if (!PROT_IS_SUCCESS(ret))
  1785. {
  1786. LOG("Failed to set H.245 address"
  1787. " in connectUUIE error = 0x%xn",ret);
  1788. return LocalHangup();
  1789. }
  1790. }
  1791. if (transfer_flag)
  1792. {
  1793. // Set the H4501 Supplimentary Services in setup_uuie
  1794. H4501SuppService *pss;
  1795. // invokeID is 0 for now until OSS fixes the bug
  1796. pss = ctSetupReturnResult(transfer_invoke_id);
  1797. ret = ie.AddH450SupplementaryService(*pss);
  1798. if (!PROT_IS_SUCCESS(ret))
  1799. {
  1800. LOG("Failed to set setup response ");
  1801. LOG("AddH450SupplementaryService, error = 0x%xn", ret);
  1802. }
  1803. delete pss;
  1804. }
  1805. ret = InvokeCCPrim(CCP_SETUP_RESPONSE, NULL, ie);
  1806. if (!PROT_IS_SUCCESS(ret))
  1807. {
  1808. LOG("Failed to send connect, error = 0x%xn", ret);
  1809. return LocalHangup();
  1810. }
  1811. else
  1812. {
  1813. if (do_faststart && audio_session_flag == 0 && 
  1814. faststart_state == FAST_START_STATE_ENABLED)
  1815. {
  1816. audio_session_flag = 1;
  1817. #if defined (ENABLE_BENCHMARKS)
  1818. get_current_time(end_sec,end_msec);
  1819. #endif
  1820. StartAudio();
  1821. }
  1822. }
  1823. return 1;
  1824. }
  1825. int
  1826. H323Call::SendFacility(H450SSseq *ssSeq)
  1827. {
  1828. // Request from the user to send Facility message. 
  1829. if(((H225CSProtocol *)this)->IsConnectionReady()) 
  1830. {
  1831. LOG("H323Call::SendFacility() sending (ssSeq=0x%x)t",ssSeq);
  1832. SendQ932Facility(FYR_UNDEFINED, ssSeq);
  1833. return(-1);
  1834. }
  1835. return -1;
  1836. }
  1837. void
  1838. H323Call::SendQ932Facility(int reason, H450SSseq *ssSeq)
  1839. {
  1840. LOG("H323Call::SendQ932Facilityn");
  1841. LOG("Facility reason = %dn", reason);
  1842. ProtReturnCode ret;
  1843. H225CSFacilityUUIE ie(*this);
  1844. Q931Message fmsg(MESSAGE_Q932_FACILITY);
  1845. // Set Reason in H225CSFacilityUUIE
  1846. ret = ie.SetReason(reason);
  1847. if (!PROT_IS_SUCCESS(ret))
  1848. {
  1849. LOG("Failed to set facility reason, error = 0x%xn", ret);
  1850. }
  1851. #ifdef NOTNEEDED
  1852. // {
  1853. // Set AlternativeAliasAddress in H225CSFacilityUUIE
  1854. H225CSAliasAddress e164;
  1855. char dummy[15];
  1856. strcpy(dummy,"12345678901");
  1857. e164.SetE164(dummy,(unsigned short)strlen(dummy));
  1858. ret = ie.AddAlternativeAliasAddr(e164);
  1859. if (!PROT_IS_SUCCESS(ret))
  1860. {
  1861. LOG("Failed to set facility AddAlternativeAliasAddr, error = 0x%xn", ret);
  1862. }
  1863. // Set AlternativeAddress in H225CSFacilityUUIE
  1864. struct sockaddr_in addr;
  1865. addr.sin_family = AF_INET;
  1866. addr.sin_addr.s_addr = inet_addr("123.45.67.89");
  1867. addr.sin_port = htons(1122);
  1868. ret = ie.SetAlternativeAddr((sockaddr *)&addr);
  1869. if (!PROT_IS_SUCCESS(ret))
  1870. {
  1871. LOG("Failed to set facility SetAlternativeAddr, error = 0x%xn", ret);
  1872. }
  1873. // }
  1874. #endif
  1875. // Set the H4501 Supplimentary Services
  1876. H4501SuppService *pss;
  1877. H450SSseq *p;
  1878. int i = 0;
  1879. p = ssSeq;
  1880. while(p != NULL)
  1881. {
  1882. pss = p->value;
  1883. if(pss != NULL) {
  1884. ret = ie.AddH450SupplementaryService(*pss);
  1885. if (!PROT_IS_SUCCESS(ret))
  1886. {
  1887. LOG("Failed to set facility AddH450SupplementaryService, error = 0x%xn", ret);
  1888. }
  1889. }
  1890. p = p->next;
  1891. i++;
  1892. }
  1893. LOG("Added %d SuppServices to FACILITY_REQUESTn",i);
  1894. ret = InvokeCCPrim(CCP_FACILITY_REQUEST, &fmsg, ie);
  1895. if (!PROT_IS_SUCCESS(ret))
  1896. {
  1897. LOG("Failed to send facility, error = 0x%xn", ret);
  1898. }
  1899. // deleteSSlist(ssSeq);
  1900. }
  1901. // return 0 on success
  1902. int
  1903. H323Call::CreateRtpSession()
  1904. {
  1905. unsigned short rtp_port = 0, rtcp_port = 0;
  1906. int status;
  1907. audio_session = 
  1908. new H245RTPSession("RTP:ELEMEDIA", 
  1909. G7231_RTP_PAYLOAD_TYPE,
  1910. G7231_AUDIO_SAMPLING_RATE,status);
  1911. if (status)
  1912. {
  1913. LOG("new H245RTPSession failed. "
  1914. "status = 0x%xn", status);
  1915. return status;
  1916. }
  1917. audio_session->SetLocalPorts(if_ip_addr, 
  1918. rtp_port, rtcp_port);
  1919. rtcp_addr.sin_family = AF_INET;
  1920. rtcp_addr.sin_addr.s_addr = if_ip_addr;
  1921. rtcp_addr.sin_port = rtcp_port;
  1922. rtp_addr.sin_family = AF_INET;
  1923. rtp_addr.sin_addr.s_addr = if_ip_addr;
  1924. rtp_addr.sin_port = rtp_port;
  1925. return 0;
  1926. }
  1927. // return 0 on success
  1928. int
  1929. H323Call::SwitchToRegularH245()
  1930. {
  1931. // Switch to Regular H.245 proceedures.
  1932. ProtReturnCode ret;
  1933. assert(do_faststart == 1);
  1934. // Check if we already have the remote endpoints H.245 address.
  1935. // If not obtain it by sending out a facility message.
  1936. if (remote_lc0_addr.sin_addr.s_addr != 0)
  1937. {
  1938. // we already have the remote ends H.245 address. Just connect to it.
  1939. ret = exchange->Connect( (sockaddr *)&remote_lc0_addr, 
  1940. (H245Protocol *)this);
  1941. faststart_state = H245_FAST_START_STATE_SWITCH_OUT_BEGIN; 
  1942. if (!PROT_IS_PENDING(ret))
  1943. {
  1944. exchange->NotifyConnectionStatus(
  1945. (H245Protocol*)this,ret);
  1946. faststart_state = H245_FAST_START_STATE_SWITCHED_OUT; 
  1947. }
  1948. }
  1949. else
  1950. {
  1951. // Try to get the remote end to switch to regular H.245 
  1952. // procedure by providing our lc0 address.
  1953. H225CSFacilityUUIE ie(*this);
  1954. // Insert our H245address 
  1955. local_lc0_addr.sin_family = AF_INET;
  1956. #if (defined(BUGGY_NSL)) // Needed for unixware, alas! no multihomed hosts...
  1957. local_lc0_addr.sin_addr.s_addr = if_ip_addr;
  1958. #else
  1959. if (!PROT_IS_SUCCESS(
  1960. ((H225CSProtocol *)this)->GetConnectionAddrs(
  1961. (struct sockaddr*)&local_lc0_addr,
  1962. NULL)))
  1963. {
  1964. LOG("Can't get i/f ip addressn");
  1965. local_lc0_addr.sin_addr.s_addr = if_ip_addr;
  1966. }
  1967. else
  1968. {
  1969. LOG("Got i/f ip address, 0x%xn",
  1970. local_lc0_addr.sin_addr.s_addr);
  1971. if_ip_addr = local_lc0_addr.sin_addr.s_addr;
  1972. }
  1973. #endif
  1974. // Make the connection manager pick the port.
  1975. local_lc0_addr.sin_port = 0;
  1976. ret = exchange->Listen(
  1977. ((H245Protocol *)this)->GetIdentifier(),
  1978. (struct sockaddr *)&local_lc0_addr, 
  1979. LT_ONCE);
  1980. if (!PROT_IS_SUCCESS(ret))
  1981. {
  1982. LOG("Failed to create H.245 address" " error = 0x%xn",ret);
  1983. return -1;
  1984. }
  1985. ret = ie.SetH245Transport((struct sockaddr *)&local_lc0_addr);
  1986. if (!PROT_IS_SUCCESS(ret))
  1987. {
  1988. LOG("Failed to set H.245 address in facilityUUIE error = 0x%xn",
  1989. ret);
  1990. return -1;
  1991. }
  1992. ret = InvokeCCPrim(CCP_FACILITY_REQUEST, NULL, ie);
  1993. if (!PROT_IS_SUCCESS(ret))
  1994. {
  1995. LOG("Failed to send facility, error = 0x%xn", ret);
  1996. return -1;
  1997. }
  1998. faststart_state = H245_FAST_START_STATE_SWITCH_OUT_BEGIN; 
  1999. }
  2000. return 0;
  2001. }