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

IP电话/视频会议

开发平台:

WINDOWS

  1. /*
  2.  * $Revision: 1.19 $
  3.  * $Date: 1999/03/15 22:49:36 $
  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. #if (!defined(WIN32))
  31. #if defined(VXWORKS)
  32. #else
  33. #if (defined(__hpux))
  34. #include <pthread.h>
  35. #else
  36. #include <thread.h>
  37. #endif
  38. #endif
  39. #endif
  40. #include "exchange.h"
  41. #include "call.h"
  42. #include "msg.h"
  43. #include "mq.h"
  44. #include <assert.h>
  45. #if defined(USE_RAS)
  46. extern char *ras_msg_id_str[];
  47. char *ras_msg_id2str[] = 
  48. {
  49.         "INVALID",
  50.         "GRQ",
  51.         "GCF",
  52.         "GRJ",
  53.         "RRQ",
  54.         "RCF",
  55.         "RRJ",
  56.         "URQ",
  57.         "UCF",
  58.         "URJ",
  59.         "ARQ",
  60.         "ACF",
  61.         "ARJ",
  62.         "BRQ",
  63.         "BCF",
  64.         "BRJ",
  65.         "DRQ",
  66.         "DCF",
  67.         "DRJ",
  68.         "LRQ",
  69.         "LCF",
  70.         "LRJ",
  71.         "IRQ",
  72.         "IRR",
  73.         "NSM",
  74.         "XRS"
  75. };
  76. int
  77. find_msg_id(char* msg_str)
  78. {
  79.         for(int i=MSG_INVALID;i<=MSG_XRS;++i)
  80.         {
  81.                 if (!stricmp(msg_str,ras_msg_id2str[i]))
  82.                 {
  83.                         return i;
  84.                 }
  85.         }
  86.         return -1;
  87. }
  88. Exchange::Exchange(H225CSEndpointType& endpoint_type,
  89.         H225CSVendorID& vendor_id, int ras_endpoint,
  90.         ProtReturnCode& result) : 
  91. ConnectionManager(result),
  92. H225RASProtocol(endpoint_type, vendor_id, ras_endpoint, result),
  93. MessageQueue("Exchange",512,0)
  94. #else
  95. Exchange::Exchange(ProtReturnCode &result) : ConnectionManager(result),
  96. MessageQueue("Exchange",512,0)
  97. #endif
  98. {
  99. for (int i = 0; i < NUM_LINES; i++)
  100. {
  101. calls[i] = NULL;
  102. #if defined(USE_RAS)
  103. ras_sess[i].last_seqno = 0; 
  104. ras_sess[i].ARQsent = FALSE;
  105. ras_sess[i].ACFrecd = FALSE;
  106. #endif
  107. }
  108. num_active_calls = 0;
  109. terminal_type = TT_TERMINAL_NO_MC;
  110. // initialize the endpoint_type.
  111. H225CSVendorID vid;
  112. char *desc = "Test audio distribution application";
  113. vid.SetH221NonStd(0xde, 0, 0xad);
  114. vid.SetProductID((unsigned char *)desc, strlen(desc) + 1);
  115. vid.SetVersionID((unsigned char *)desc, strlen(desc) + 1);
  116. endpoint_type.SetVendor(vid);
  117. endpoint_type.SetTerminal(NULL);
  118.     ProtReturnCode ret;
  119. confid_prefix = get_local_ip();
  120. // by default use version 1 procedures.
  121. use_faststart = 0;
  122. use_overlapsend = 0;
  123. use_tunneling = 0;
  124. use_alerting = 0;
  125. use_callproc = 0;
  126. #ifdef USE_RAS
  127. isGKRegistered = FALSE; 
  128. gkdiscovered = FALSE;
  129.     local_ip = get_local_ip(); 
  130. confid_prefix = local_ip;
  131. ((sockaddr_in*)&local_ras)->sin_family = AF_INET;
  132.     ((sockaddr_in*)&local_ras)->sin_port = HTONS(config->localrasport);
  133. #ifdef VXWORKS
  134.     ((sockaddr_in*)&local_ras)->sin_addr.s_addr = htonl(INADDR_ANY);
  135. #else
  136.     ((sockaddr_in*)&local_ras)->sin_addr.s_addr = local_ip;
  137. #endif
  138. ret = SetLocalAddr((sockaddr *) &local_ras);
  139. if (!PROT_IS_SUCCESS(ret)) {
  140. LOG("SetLocalAddr error 0x%xn", ret);
  141. return;
  142. }
  143. // vxworks doesn't like to bind on a named socket, so we bind to 
  144. // INADDR_ANY but we need to communicate the real IP in out RAS messages
  145. #ifdef VXWORKS
  146. ((sockaddr_in*)&local_ras)->sin_addr.s_addr = local_ip;
  147. #endif
  148. ((sockaddr_in*)&local_sig)->sin_family = AF_INET;
  149.     ((sockaddr_in*)&local_sig)->sin_port = HTONS(config->q931port);
  150.     ((sockaddr_in*)&local_sig)->sin_addr.s_addr = local_ip;
  151. SetLastSeqno(1);
  152. #endif
  153. sockaddr_in addr;
  154. addr.sin_family = AF_INET;
  155. addr.sin_port = HTONS(config->q931port);
  156. addr.sin_addr.s_addr = 0;
  157. LOG("Calling ConnectionManager::Listenn");
  158. ret = Listen(ID_H225,(sockaddr*)&addr,LT_MANY);
  159. if (!PROT_IS_SUCCESS(ret))
  160. {
  161. LOG("ConnectionManager::Listen failed, 0x%xn",ret);
  162. return;
  163. }
  164. LOG("Listen succeededn");
  165. }
  166. Exchange::~Exchange()
  167. {
  168. LOG("Exchange::~Exchangen");
  169. }
  170. #ifdef USE_RAS
  171. void
  172. Exchange::DiscoverGK()
  173. {
  174. ProtReturnCode ret = SendGRQ(seqno++,NULL);
  175. if (!PROT_IS_SUCCESS(ret))
  176. {
  177. LOG("H225RASProtocol::SendGRQ failed, 0x%xn",ret);
  178. return;
  179. }
  180. LOG("Discovery request sentn");
  181. }
  182. void
  183. Exchange::RegisterWithGK()
  184. {
  185. struct sockaddr_in gk_address; 
  186. gk_address.sin_family = AF_INET;
  187. gk_address.sin_port =  HTONS(1719);
  188. gk_address.sin_addr.s_addr= inet_addr(config->gkaddrstr);
  189. ChooseGK((sockaddr*) &(gk_address));
  190. ProtReturnCode ret = SendRRQ(seqno++,NULL);
  191. if (!PROT_IS_SUCCESS(ret))
  192. {
  193. LOG("H225RASProtocol::SendRRQ failed, 0x%xn",ret);
  194. return;
  195. }
  196. LOG("Registration request sentn");
  197. }
  198. void
  199. Exchange::UnRegisterWithGK()
  200. {
  201. if(!IsGKRegistered())
  202. return;
  203. ProtReturnCode ret = SendURQ(seqno++,NULL);
  204. if (!PROT_IS_SUCCESS(ret))
  205. {
  206. LOG("H225RASProtocol::SendURQ failed, 0x%xn",ret);
  207. return;
  208. }
  209. LOG("UnRegistration request sentn");
  210. }
  211. #endif
  212. void
  213. Exchange::SendToExchange(int message, unsigned int wparam,
  214. unsigned int lparam)
  215. {
  216. USER_MESSAGE msg;
  217. msg.message = message;
  218. msg.wParam = wparam;
  219. msg.lParam = lparam;
  220. QueueMessage(&msg);
  221. }
  222. int
  223. Exchange::create_call(int outgoing)
  224. {
  225. ProtReturnCode result = 0;
  226. int i;
  227. for(i=0;i<NUM_LINES;++i)
  228. {
  229. if (calls[i] == NULL)
  230. break;
  231. }
  232. if (i == NUM_LINES)
  233. {
  234. assert(num_active_calls == NUM_LINES);
  235. return(-1);
  236. }
  237. char display[20];
  238. sprintf(display, "%s%d", config->h323IDsrc, i);
  239. calls[i] = new H323Call(this,ID_H225 + i, ID_H245 + i,
  240. endpoint_type, terminal_type, display, outgoing, result);
  241. if (!PROT_IS_SUCCESS(result)) 
  242. {
  243. return(result);
  244. }
  245. if (calls[i] == NULL)
  246. {
  247. LOG("Memory allocation for call failedn");
  248. return(-1);
  249. }
  250. #if defined(USE_RAS)
  251. ras_sess[i].ARQsent = ras_sess[i].ACFrecd = FALSE;
  252. if (outgoing)
  253. ras_sess[i].direction = (boolean)DIR_OUTGOING;
  254. else
  255. ras_sess[i].direction = (boolean)DIR_INCOMING;
  256. #endif
  257. calls[i]->SetApplicationPrivate((unsigned long)i);
  258. calls[i]->Start();
  259. ++num_active_calls;
  260. return(i);
  261. }
  262. // Note: connections are closed by the destructor of ConnectionEntity
  263. void
  264. Exchange::destroy_call(int index)
  265. {
  266. assert(calls[index] != NULL);
  267. H245Protocol* h245 = calls[index];
  268. H225CSProtocol* h225 = calls[index];
  269. if (h225)
  270. {
  271. LOG("Closing H.225 connectionn");
  272. CloseConnection(h225);
  273. LOG("Done closing H.225 connectionn");
  274. }
  275. if (h245)
  276. {
  277. LOG("Closing H.245 connectionn");
  278. CloseConnection(h245);
  279. LOG("Done closing H.245 connectionn");
  280. }
  281. calls[index]->Stop();
  282. #ifdef USE_RAS
  283. if (IsGKRegistered() &&
  284. ras_sess[index].ACFrecd )
  285. {
  286. ras_sess[index].last_seqno = seqno++;
  287. SendDRQ(ras_sess[index].last_seqno, NULL, index);
  288.     }
  289. #endif
  290. delete calls[index];
  291. calls[index] = NULL;
  292. --num_active_calls;
  293. }
  294. void
  295. Exchange::ShutDown()
  296. {
  297. StopListening(ID_H225);
  298. SendToExchange(PROT_UI_MSG,UI_CMD_EXIT,0);
  299. while(num_active_calls > 0)
  300. {
  301. #if defined(WIN32)
  302. Sleep(0);
  303. #elif defined(VXWORKS)
  304. taskDelay(1);
  305. #else
  306. #if (defined(__hpux))
  307. pthread_yield();
  308. #else
  309. thr_yield();
  310. #endif
  311. #endif
  312. }
  313. }
  314. void
  315. Exchange::NotifyMessage(USER_MESSAGE& msg)
  316. {
  317. void *data = (void*)msg.lParam;
  318. if (msg.message == PROT_EXCH_MSG)
  319. {
  320. if (msg.wParam == XC_CALL_DROPPED)
  321. {
  322. H323Call *call =(H323Call*)data;
  323. destroy_call((int)call->GetApplicationPrivate());
  324. data = NULL;
  325. }
  326. else if (msg.wParam == CB_NEW_CONNECTION)
  327. {
  328. XchgNewConnection *info = (XchgNewConnection *)data;
  329. if (info->identifier == ID_H225)
  330. {
  331. int index = create_call(0); // incoming call
  332. if (index == -1)
  333. {
  334. RejectConnection(info->conn_ref);
  335. }
  336. else
  337. {
  338. ProtReturnCode ret;
  339. ret = AcceptConnection(info->conn_ref, 
  340. (H225CSProtocol*)calls[index]);
  341. if (!PROT_IS_SUCCESS(ret))
  342. {
  343. LOG("AcceptConnection failed on H.225 portn");
  344. destroy_call(index);
  345. }
  346. }
  347. }
  348. else
  349. {
  350. int index = info->identifier;
  351. assert(index >= ID_H245);
  352. index -= ID_H245;
  353. assert(index < NUM_LINES);
  354. assert(index >= 0);
  355. assert(((H245Protocol*)calls[index])->GetIdentifier()
  356. == info->identifier);
  357. msg.message = PROT_CALL_MSG;
  358. if (calls[index]  == NULL)
  359. {
  360. abort();
  361. }
  362. calls[index]->QueueMessage(&msg);
  363. // We don't have to freeup data.
  364. data = NULL;
  365. }
  366. }
  367. else if (msg.wParam == CB_LISTEN_ERROR)
  368. {
  369. XchgListenError *info = (XchgListenError *)data;
  370. LOG("ERROR: error occurred while accepting on id %dn",
  371. info->identifier);
  372. }
  373. else
  374. {
  375. LOG("ERROR: Unknown PROT_EXCH_MSGn");
  376. }
  377. }
  378. else if (msg.message == PROT_UI_MSG) // this is a command
  379. {
  380. LOG("Message from UIn");
  381. switch(msg.wParam)
  382. {
  383. case UI_CMD_PLACE_CALL: 
  384. {
  385. LOG("UI_CMD_PLACE_CALLn");
  386. int index;
  387. UICmdPlaceCall *info = (UICmdPlaceCall *)data;
  388. // check if any lines are free...
  389. if((index=create_call(1)) == -1) // outgoing call
  390. {
  391. LOG("All lines are busy, try latern");
  392. }
  393. else
  394. {
  395. ProtReturnCode ret;
  396. if (info->dest_addr_length > 0)
  397. {
  398. calls[index]->SetPhoneNumber(info->dest_addr);
  399. }
  400. if (info->transfer_flag == TRUE) // is this a call transfer?
  401. {
  402. calls[index]->SetInvokeID(info->invokeID);
  403. calls[index]->SetTransferFlag(TRUE);
  404. if (info->callID)
  405. calls[index]->SetTransferCallID(info->callID);
  406. calls[index]->SetParentIndex(info->parent_index);
  407. }
  408. #ifdef USE_RAS
  409.     if (IsGKRegistered() != TRUE)
  410.                     {
  411. // Initiate a TCP connection to the remote ends
  412. // Q.931 engine...
  413. ret = Connect((struct sockaddr*)&info->remote_addr, 
  414. (H225CSProtocol*)calls[index]);
  415. if (!PROT_IS_PENDING(ret))
  416. {
  417. // Kinda kludgy... but not too bad..
  418. NotifyConnectionStatus(
  419. (H225CSProtocol*)calls[index],ret);
  420. }
  421. }
  422. else  // we are registered with a gatekeeper; send ARQ
  423. {
  424. SendARQdata *arq_data = new SendARQdata;
  425. // create a src e164 alias in the form YYYXXXX
  426. // where YYY is the prefix and YYYY is the index of the call
  427. // for a gateway app, the app should pass the caller-id
  428. // in the UICmdPlaceCall message
  429. char tmp_phone[256];
  430. sprintf(tmp_phone, "%s%0004d", 
  431. config->e164src, index);
  432. calls[index]->SetSrcPhoneNumber(tmp_phone);
  433. strcpy(arq_data->e164src, tmp_phone);
  434. strcpy(arq_data->e164dst, info->dest_addr);
  435. arq_data->index = index;
  436. LOG("SendARQ for OUTGOING calln");
  437. // info->dest_addr is the outgoing number
  438. ras_sess[index].last_seqno = seqno++;
  439. SendARQ(ras_sess[index].last_seqno,NULL,
  440.                                arq_data );
  441. ras_sess[index].ARQsent = TRUE;
  442. delete arq_data;
  443. }
  444. #else 
  445. ret = Connect((struct sockaddr*)&info->remote_addr, 
  446. (H225CSProtocol*)calls[index]);
  447. if (!PROT_IS_PENDING(ret))
  448. {
  449. // Kinda kludgy... but not too bad..
  450. NotifyConnectionStatus(
  451. (H225CSProtocol*)calls[index],ret);
  452. }
  453. #endif
  454. }
  455. }
  456. break;
  457. case UI_CMD_HANGUP:
  458. {
  459. LOG("UI_CMD_HANGUPn");
  460. UICmdHangup *info = (UICmdHangup *)data;
  461. msg.lParam = 0;
  462. LOG("Hanging up line %dn", info->line_no);
  463. if (calls[info->line_no])
  464. {
  465. calls[info->line_no]->QueueMessage(&msg);
  466. }
  467. }
  468. break;
  469. case UI_CMD_FACILITY:
  470. {
  471. LOG("UI_CMD_FACILITYn");
  472. UICmdFacility *info = (UICmdFacility *)data;
  473. msg.lParam = (unsigned int)info;
  474. LOG("Sending Facility msg on line %dn", info->line_no);
  475. if (calls[info->line_no])
  476. {
  477. calls[info->line_no]->QueueMessage(&msg);
  478. }
  479. // We don't have to freeup data.
  480. data = NULL;
  481. }
  482. break;
  483. case UI_CMD_EXIT:
  484. {
  485. LOG("UI_CMD_EXITn");
  486. msg.lParam = 0;
  487. for (int i = 0; i < NUM_LINES; ++i)
  488. {
  489. if (calls[i] != NULL)
  490. {
  491. calls[i]->QueueMessage(&msg);
  492. }
  493. }
  494. }
  495. break;
  496. case UI_CMD_CTRL: 
  497. {
  498. // Control type command from the user interface.
  499. LOG("UI_CMD_CTRLn");
  500. UICmdCtrl *info = (UICmdCtrl *)data;
  501. for (int i = 0; i < info->num_cmds; i++)
  502. {
  503. switch (info->command[i])
  504. {
  505. case UI_CTRL_CMD_ENABLE_FASTSTART:
  506. use_faststart = 1;
  507. break;
  508. case UI_CTRL_CMD_DISABLE_FASTSTART:
  509. use_faststart = 0;
  510. break;
  511. case UI_CTRL_CMD_ENABLE_TUNNELING:
  512. use_tunneling = 1;
  513. break;
  514. case UI_CTRL_CMD_DISABLE_TUNNELING:
  515. use_tunneling = 0;
  516. break;
  517. case UI_CTRL_CMD_ENABLE_OVERLAP_SEND:
  518. use_overlapsend = 1;
  519. break;
  520. case UI_CTRL_CMD_DISABLE_OVERLAP_SEND:
  521. use_overlapsend = 0;
  522. break;
  523. case UI_CTRL_CMD_ENABLE_ALERTING:
  524. use_alerting = 1;
  525. break;
  526. case UI_CTRL_CMD_DISABLE_ALERTING:
  527. use_alerting = 0;
  528. break;
  529. case UI_CTRL_CMD_ENABLE_CALLPROC:
  530. use_callproc = 1;
  531. break;
  532. case UI_CTRL_CMD_DISABLE_CALLPROC:
  533. use_callproc = 0;
  534. break;
  535. }
  536. }
  537. }
  538. break;
  539. }
  540. }
  541. // code for handling with messages from H323Call 
  542. else if (msg.message == PROT_CALL_MSG)
  543. {
  544. LOG("Message from H323 CALLn");
  545. switch(msg.wParam)
  546. {
  547. #if defined(USE_RAS)
  548. // the following ARQ request message is for an incoming call
  549. case CB_SEND_ARQ:
  550. {
  551. SendARQdata *info = (SendARQdata *)data;
  552. assert(calls[info->index] != NULL);
  553. ras_sess[info->index].last_seqno = seqno++;
  554. SendARQ(ras_sess[info->index].last_seqno, NULL,
  555.                         (SendARQdata*)info );
  556. ras_sess[info->index].ARQsent = TRUE;
  557. }
  558.             break;
  559. #endif
  560. default:
  561. break;
  562. }
  563. }
  564. #if defined(USE_RAS)
  565. else if (msg.message == PROT_RAS_MSG)
  566. {
  567. XchgRASMessage *info = (XchgRASMessage *)data; 
  568. int msg_type = info->ras_message->GetType();
  569. H225RASMessage *ras_message = info->ras_message;
  570. struct sockaddr *origin = info->origin;
  571. LOG("Exchange::NotifyRASMessagen");
  572. LOG("Got message(%d,%s), seqno(%d)n",ras_message->GetType(),
  573.     ((ras_message->GetType() >= MSG_INVALID && 
  574.  ras_message->GetType() <= MSG_XRS) ? 
  575. ras_msg_id2str[ras_message->GetType()] : "UNKNOWN" ),
  576. ras_message->GetSequenceNumber());
  577. int seqno_rcvd = ras_message->GetSequenceNumber();
  578. switch(ras_message->GetType())
  579. {
  580. case MSG_GRQ:
  581. {
  582. struct sockaddr_in host_addr; 
  583. // just snoop and log GRQs received at the multicast address
  584. ((H225RASMsgGCF*)ras_message)->GetRASAddr((sockaddr*)&host_addr);
  585. char *host_addr_str = inet_ntoa(host_addr.sin_addr);
  586. LOG("host %s is looking for a gatekeepern", host_addr_str);
  587. }
  588. break;
  589.             case MSG_GCF:
  590. {
  591. struct sockaddr_in gk_address; 
  592. ((H225RASMsgGCF*)ras_message)->GetRASAddr((sockaddr*)&gk_address);
  593. char *gk_addr_str = inet_ntoa(gk_address.sin_addr);
  594. LOG("%s is offering to become our gatekeepern", gk_addr_str);
  595. // if we have already received a reply from a gatekeeper, ignore this one
  596. // we can selectively filter the replies to find a preferred gatekeeper
  597. if (!gkdiscovered) {
  598. gkdiscovered = TRUE;
  599. strcpy(config->gkaddrstr, gk_addr_str);
  600. RegisterWithGK();
  601. }
  602. }
  603. break;
  604.             case MSG_GRJ:
  605.             case MSG_RRQ:
  606.             break;
  607.             case MSG_RCF:
  608. {
  609. unsigned short *id; 
  610. ((H225RASMsgRCF*)ras_message)->GetEndpointID(id, ep_id_len);
  611. memcpy(&ep_id[0], id, ep_id_len * 2);
  612. LOG("Registration succeeded!n");
  613. SetIsGKRegistered(TRUE);
  614. LOG("Endpoint ID: 0x");
  615. for(int i=0; i<ep_id_len; i++)
  616. LOG("%x", ep_id[i]);
  617. LOG("n");
  618. }
  619. break;
  620.             case MSG_RRJ:
  621. isGKRegistered = FALSE;
  622.             break;
  623.             case MSG_URQ:
  624.             break;
  625.             case MSG_UCF:
  626.    isGKRegistered = FALSE;
  627.             break;
  628.             case MSG_URJ:
  629.             break;
  630.             case MSG_ARQ:
  631.             break;
  632.             case MSG_ACF:
  633. {
  634. ProtReturnCode ret;
  635. struct sockaddr_in addr;
  636. ((H225RASMsgACF*)ras_message)->GetDstCallSigAddr((struct sockaddr*)&addr);
  637. char *rem_addr_str = inet_ntoa(addr.sin_addr);
  638. LOG("gatekeeper offers dest signaling addr <%s>:<%u>n", 
  639. rem_addr_str, ntohs(addr.sin_port));
  640. int index =  -1;
  641. int is_call_valid = 0;
  642. for (int i = 0;i < NUM_LINES; i++)
  643. {
  644. if (seqno_rcvd == ras_sess[i].last_seqno) {
  645. index = i;
  646. if ((void *)calls[index])
  647. {
  648. is_call_valid = 1;
  649. break;
  650. }
  651. }
  652. }
  653. if (is_call_valid) {
  654. ras_sess[index].ACFrecd = TRUE;
  655. if (ras_sess[index].direction == DIR_OUTGOING) {
  656. LOG("valid OUTgoing call  index = %dn",index);
  657. // Initiate a TCP connection to the remote ends
  658. // Q.931 engine...
  659. ret = Connect((struct sockaddr*)&addr,
  660. (H225CSProtocol*)calls[index]);
  661. if (!PROT_IS_PENDING(ret))
  662. {
  663. // Kinda kludgy... but not too bad..
  664. NotifyConnectionStatus(
  665. (H225CSProtocol*)calls[index],ret);
  666. }
  667. }
  668. else if (ras_sess[index].direction == DIR_INCOMING)
  669. {
  670. LOG("valid INcoming call  index = %dn",index);
  671. calls[index]->Q931SendAlerting();
  672. }
  673. else
  674. {
  675. assert(1);
  676. }
  677. }
  678. }
  679. break;
  680.             case MSG_ARJ:
  681.    {
  682. LOG("Received ARJn");
  683. int index =  -1;
  684. int is_call_valid = 0;
  685. for (int i = 0;i < NUM_LINES; i++)
  686. {
  687. if (seqno_rcvd == ras_sess[i].last_seqno) {
  688. index = i;
  689. if ((void *)calls[index])
  690. {
  691. is_call_valid = 1;
  692. break;
  693. }
  694. }
  695. }
  696. if (is_call_valid) {
  697. ras_sess[index].ACFrecd = FALSE;
  698. // this should clean everything
  699. USER_MESSAGE msg;
  700. msg.message = PROT_UI_MSG;
  701. msg.wParam = UI_CMD_HANGUP;
  702. msg.lParam = NULL;
  703. calls[index]->QueueMessage(&msg);
  704. }
  705.    }   
  706. break;
  707. #if 1 // TODO: implement 
  708.             case MSG_BRQ:
  709.             case MSG_BCF:
  710.             case MSG_BRJ:
  711. // DRQ request might come from the GK if the call has to be teared down
  712. // the terminal should tear down the call
  713.             case MSG_DRQ:
  714.             case MSG_DCF:
  715.             case MSG_DRJ:
  716.             case MSG_LRQ:
  717.             case MSG_LCF:
  718.             case MSG_LRJ:
  719.             case MSG_IRQ:
  720.             case MSG_IRR:
  721.             case MSG_NSM:
  722.             case MSG_XRS:
  723. #endif
  724.             break;
  725. default:
  726. break;
  727. }
  728. }
  729. #endif
  730. if (data)
  731. {
  732. delete (CBData*)data;
  733. }
  734. }
  735. void 
  736. Exchange::NotifyListenError(int identifier,
  737. ProtReturnCode status)
  738. {
  739. XchgListenError *msg = new XchgListenError;
  740. msg->identifier = identifier;
  741. msg->status = status;
  742. SendToExchange((unsigned int)PROT_EXCH_MSG,
  743. (unsigned int)CB_LISTEN_ERROR,
  744. (unsigned int)msg);
  745. }
  746. void 
  747. Exchange::NotifyNewConnection(int identifier,
  748. int conn_ref, sockaddr *new_addr)
  749. {
  750. XchgNewConnection *msg = new XchgNewConnection;
  751. msg->identifier = identifier;
  752. msg->conn_ref = conn_ref;
  753. msg->new_addr = *(struct sockaddr_in *)new_addr;
  754. SendToExchange((unsigned int)PROT_EXCH_MSG,
  755. (unsigned int)CB_NEW_CONNECTION,
  756. (unsigned int)msg);
  757. }
  758. void 
  759. Exchange::NotifyConnectionStatus(ConnectionEntity *conn, 
  760. ProtReturnCode connection_status)
  761. {
  762. USER_MESSAGE m;
  763. LOG("NotifyConnectionStatus status = 0x%xn",
  764. connection_status);
  765. int index = conn->GetIdentifier();
  766. if (index < ID_H245)
  767. {
  768. index -= ID_H225;
  769. assert(index >= 0 && index <= NUM_LINES);
  770. }
  771. else
  772. {
  773. index -= ID_H245;
  774. assert(index >= 0 && index <= NUM_LINES);
  775. }
  776. if (calls[index] == NULL)
  777. {
  778. abort();
  779. }
  780. XchgConnectionStatus *msg = new XchgConnectionStatus;
  781. msg->conn = conn;
  782. msg->status = connection_status;
  783. m.message = PROT_CALL_MSG;
  784. m.wParam = CB_CONNECTION_STATUS;
  785. m.lParam = (unsigned int)msg;
  786. calls[index]->QueueMessage(&m);
  787. }
  788. void
  789. Exchange::NotifyConnectionClosed(ConnectionEntity *conn,
  790. ProtReturnCode reason)
  791. {
  792. USER_MESSAGE m;
  793. int index = conn->GetIdentifier();
  794. if (index < ID_H245)
  795. {
  796. index -= ID_H225;
  797. }
  798. else
  799. {
  800. index -= ID_H245;
  801. }
  802. if (calls[index] == NULL)
  803. {
  804. abort();
  805. }
  806. XchgConnectionClosed *msg = new XchgConnectionClosed;
  807. msg->conn = conn;
  808. msg->reason = reason;
  809. m.message = PROT_CALL_MSG;
  810. m.wParam = CB_CONNECTION_CLOSED;
  811. m.lParam = (unsigned int)msg;
  812. calls[index]->QueueMessage(&m);
  813. }
  814. #if defined(__SVR4) && defined(__sun)
  815. extern "C"
  816. {
  817.  int gethostname(char *,int);
  818. };
  819. #endif
  820. unsigned int
  821. Exchange::get_local_ip()
  822. {
  823.     char hostname[256];
  824. unsigned int local_addr;
  825.     gethostname(hostname,sizeof(hostname));
  826. local_addr = inet_addr(hostname);
  827. #if defined(VXWORKS)
  828. // if gethostname() works for your target, you don't need the 
  829. // following line. We use if for our simulator
  830.     sprintf(hostname,"vxworks%d",sysProcNumGet());
  831.     local_addr = hostGetByName(hostname);
  832. LOG("local_addr=0x%xn", local_addr);
  833. return local_addr;
  834. #else
  835.     struct hostent *hent_p;
  836.     hent_p = gethostbyname((const char *)hostname);
  837.     if(hent_p == NULL)
  838.     {
  839. #if defined(WIN32)
  840.      int ret = WSAGetLastError();
  841.         LOG("gethostbyname failed on %s error %dn", hostname,ret);
  842. #else
  843. LOG("gethostbyname failed on %sn", hostname);
  844. #endif
  845.         return 0;
  846. }
  847. int i = 0;
  848. while(hent_p->h_addr_list[i])
  849. {
  850. LOG("Interface %d, ip = 0x%xn",
  851. i,*(unsigned long *)(hent_p->h_addr_list[i]));
  852. ++i;
  853. }
  854.     return *(unsigned int *)(hent_p->h_addr_list[0]);
  855. #endif
  856. }
  857. #if defined(USE_RAS)
  858. void 
  859. Exchange::NotifyRASTimeout(H225RASMessage& ras_message,
  860. struct sockaddr *destination,
  861. H225RASTransmitterInfo& info)
  862. {
  863. LOG("Exchange::NotifyRASMessagen");
  864. LOG("message(%d,%s), seqno(%d) timed-outn",ras_message.GetType(),
  865.     ((ras_message.GetType() >= MSG_INVALID && 
  866.  ras_message.GetType() <= MSG_XRS) ? 
  867. ras_msg_id2str[ras_message.GetType()] : "UNKNOWN" ),
  868. ras_message.GetSequenceNumber());
  869. }
  870. void 
  871. Exchange::NotifyRASMessage(H225RASMessage& ras_message, 
  872. struct sockaddr *origin, struct sockaddr *destination,
  873. struct H225RASTransmitterInfo& info)
  874. {
  875. XchgRASMessage *msg = new XchgRASMessage;
  876. int msg_type = ras_message.GetType();
  877. ProtReturnCode ret = H225RASMessage::Factory(msg->ras_message, msg_type, (H225RASProtocol *)this);
  878.     if (!PROT_IS_SUCCESS(ret) || !msg->ras_message)
  879.     {
  880. LOG("Failed to new ras messagen");
  881.         return;
  882. }
  883. *(msg->ras_message) = ras_message;
  884. msg->origin = origin;
  885. SendToExchange((unsigned int)PROT_RAS_MSG,
  886. (unsigned int)CB_RAS_EVENT,
  887. (unsigned int)msg);
  888. }
  889. sockaddr*
  890. Exchange::GetLocalRASAddr()
  891. {
  892.         return (sockaddr*)&local_ras;
  893. }
  894. void 
  895. Exchange::SetIsGKRegistered(boolean flag)
  896. {
  897. isGKRegistered = flag;
  898. }
  899. boolean 
  900. Exchange::IsGKRegistered()
  901. {
  902. return isGKRegistered;
  903. }
  904. sockaddr*
  905. Exchange::GetLocalSigAddr()
  906. {
  907. return (sockaddr*)&local_sig;
  908. }
  909. int
  910. Exchange::GetLastSeqno()
  911. {
  912.    return seqno;
  913. }
  914. void Exchange::SetLastSeqno(unsigned int seq_no)
  915. {
  916. seqno = seq_no;
  917. }
  918. #endif