Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1342 lines
54 KiB

  1. /****************************************************************************/
  2. /* */
  3. /* ERNCGCCC.CPP */
  4. /* */
  5. /* T120 Conference class for the Reference System Node Controller. */
  6. /* */
  7. /* Copyright Data Connection Ltd. 1995 */
  8. /* */
  9. /****************************************************************************/
  10. /* Changes: */
  11. /* */
  12. /* 14Jul95 NFC Created. */
  13. /* 13Sep95 NFC Added handler for GCC_EJECT_USER_INDICATION */
  14. /* 26Sep95 NFC Reset conference state in HandleEjectUser(). */
  15. /* 11Oct95 PM Relax conference termination checks to avoid */
  16. /* "no win" situations. The user wants it down */
  17. /* then bring it down, whatever the state! */
  18. /* */
  19. /****************************************************************************/
  20. #include "precomp.h"
  21. DEBUG_FILEZONE(ZONE_GCC_NC);
  22. #include "ernccons.h"
  23. #include "nccglbl.hpp"
  24. #include "erncvrsn.hpp"
  25. #include "cuserdta.hpp"
  26. #include "ernccm.hpp"
  27. #include "ernctrc.h"
  28. #include <service.h>
  29. static UINT s_nNumericNameCounter = 0;
  30. __inline UINT GetNewNumericNameCounter(void) { return ++s_nNumericNameCounter; }
  31. HRESULT DCRNCConference::
  32. NewT120Conference(void)
  33. {
  34. DebugEntry(DCRNCConference::NewT120Conference);
  35. m_eT120State = T120C_ST_IDLE;
  36. HRESULT hr;
  37. PCONFERENCE pConf;
  38. GCCNumericString pszNewNumericName;
  39. m_ConfName.numeric_string = NULL; // No numeric name yet.
  40. hr = ::GetGCCFromUnicode(m_pwszConfName, &pszNewNumericName, &m_ConfName.text_string);
  41. if (NO_ERROR == hr)
  42. {
  43. if (! ::IsEmptyStringA((LPCSTR) pszNewNumericName))
  44. {
  45. // Conference has a preassigned numeric name.
  46. // Validate that it does not conflict with another
  47. // conferences numeric name.
  48. pConf = g_pNCConfMgr->GetConferenceFromNumber(pszNewNumericName);
  49. if (NULL == pConf)
  50. {
  51. hr = NO_ERROR;
  52. }
  53. else
  54. {
  55. ERROR_OUT(("DCRNCConference::NewT120Conference: conference already exists"));
  56. hr = UI_RC_CONFERENCE_ALREADY_EXISTS;
  57. }
  58. }
  59. else
  60. {
  61. // Conference does not have a numeric name.
  62. // Go get it a unique one.
  63. DBG_SAVE_FILE_LINE
  64. pszNewNumericName = (GCCNumericString)new CHAR[10];
  65. if (NULL != pszNewNumericName)
  66. {
  67. do
  68. {
  69. // Do not allocate a conference number that is the same as
  70. // an existing conference.
  71. // bugbug: T120 should really do this, but it doesn't.
  72. ::wsprintfA((LPSTR) pszNewNumericName, "%u", ::GetNewNumericNameCounter());
  73. pConf = g_pNCConfMgr->GetConferenceFromNumber(pszNewNumericName);
  74. if (NULL == pConf)
  75. {
  76. hr = NO_ERROR; // Name good.
  77. break;
  78. }
  79. }
  80. while (TRUE); // Assumes not a DWORDs worth of conferences active.
  81. }
  82. else
  83. {
  84. ERROR_OUT(("DCRNCConference::NewT120Conference: can't create numeric name"));
  85. hr = UI_RC_OUT_OF_MEMORY;
  86. }
  87. }
  88. }
  89. else
  90. {
  91. ERROR_OUT(("DCRNCConference::NewT120Conference: GetGCCFromUnicode failed, hr=0x%x", (UINT) hr));
  92. }
  93. // Done looking for numeric name, so can now insert into list.
  94. m_ConfName.numeric_string = pszNewNumericName;
  95. // In case of failure, be sure to notify nmcom.
  96. if (NO_ERROR != hr)
  97. {
  98. g_pNCConfMgr->NotifyConferenceComplete(this, m_fIncoming, hr);
  99. }
  100. DebugExitHRESULT(DCRNCConference::NewT120Conference, hr);
  101. return hr;
  102. }
  103. /****************************************************************************/
  104. /* AnnouncePresence() - announce this nodes participation in the */
  105. /* conference. */
  106. /****************************************************************************/
  107. HRESULT DCRNCConference::
  108. AnnouncePresence(void)
  109. {
  110. GCCError GCCrc = GCC_INVALID_CONFERENCE;
  111. HRESULT hr;
  112. GCCNodeType nodeType;
  113. GCCNodeProperties nodeProperties;
  114. BSTR nodeName;
  115. UINT nRecords;
  116. GCCUserData ** ppUserData;
  117. DebugEntry(DCRNCConference::AnnouncePresence);
  118. if (0 != m_nConfID)
  119. {
  120. // bugbug: handle errors that cause failure to announce presence.
  121. /************************************************************************/
  122. /* Load the node type, node properties and node name from the RNC INI */
  123. /* file. */
  124. /************************************************************************/
  125. nodeName = NULL;
  126. ::LoadAnnouncePresenceParameters(
  127. &nodeType,
  128. &nodeProperties,
  129. &nodeName,
  130. NULL); // &siteInfo)) : Not used right now.
  131. /************************************************************************/
  132. /* Announce our presence in the conference. */
  133. /************************************************************************/
  134. hr = m_LocalUserData.GetUserDataList(&nRecords, &ppUserData);
  135. if (NO_ERROR == hr)
  136. {
  137. GCCrc = g_pIT120ControlSap->AnnouncePresenceRequest(
  138. m_nConfID,
  139. nodeType,
  140. nodeProperties,
  141. nodeName,
  142. 0, /* number_of_participants */
  143. NULL, //partNameList, /* participant_name_list */
  144. NULL, /* pwszSiteInfo */
  145. 0, /* number_of_network_addresses */
  146. NULL, /* network_address_list */
  147. NULL, //pAltID, /* alternative_node_id */
  148. nRecords,/* number_of_user_data_members */
  149. ppUserData /* user_data_list */
  150. );
  151. hr = ::GetGCCRCDetails(GCCrc);
  152. }
  153. SysFreeString(nodeName);
  154. }
  155. if (GCC_NO_ERROR != GCCrc)
  156. {
  157. if (GCC_CONFERENCE_NOT_ESTABLISHED == GCCrc ||
  158. GCC_INVALID_CONFERENCE == GCCrc)
  159. {
  160. TRACE_OUT(("DCRNCConference::AnnouncePresence: conf is gone."));
  161. }
  162. else
  163. {
  164. ERROR_OUT(("DCRNCConference::AnnouncePresence: failed, gcc_rc=%u", GCCrc));
  165. }
  166. }
  167. DebugExitHRESULT(DCRNCConference::AnnouncePresence, hr);
  168. return hr;
  169. }
  170. /****************************************************************************/
  171. /* HandleGCCCallback() - see erncgccc.hpp */
  172. /****************************************************************************/
  173. void DCRNCConference::
  174. HandleGCCCallback ( GCCMessage *pGCCMessage )
  175. {
  176. DebugEntry(DCRNCConference::HandleGCCCallback);
  177. TRACE_OUT(("DCRNCConference::HandleGCCCallback: msg id=%u", pGCCMessage->message_type));
  178. /************************************************************************/
  179. /* Note that GCC_CREATE_IND and GCC_INVITE_IND callbacks are handled */
  180. /* higher up the stack by the conference manager and are not passed */
  181. /* onto us. */
  182. /************************************************************************/
  183. switch (pGCCMessage->message_type)
  184. {
  185. case GCC_CREATE_CONFIRM:
  186. HandleCreateConfirm(&(pGCCMessage->u.create_confirm));
  187. break;
  188. case GCC_INVITE_CONFIRM:
  189. HandleInviteConfirm(&(pGCCMessage->u.invite_confirm));
  190. break;
  191. case GCC_ADD_CONFIRM:
  192. HandleAddConfirm(&(pGCCMessage->u.add_confirm));
  193. break;
  194. case GCC_DISCONNECT_INDICATION:
  195. HandleDisconnectInd(&(pGCCMessage->u.disconnect_indication));
  196. break;
  197. case GCC_DISCONNECT_CONFIRM:
  198. HandleDisconnectConfirm(
  199. &(pGCCMessage->u.disconnect_confirm));
  200. break;
  201. case GCC_TERMINATE_INDICATION:
  202. HandleTerminateInd(&(pGCCMessage->u.terminate_indication));
  203. break;
  204. case GCC_TERMINATE_CONFIRM:
  205. HandleTerminateConfirm(&(pGCCMessage->u.terminate_confirm));
  206. break;
  207. case GCC_ANNOUNCE_PRESENCE_CONFIRM:
  208. HandleAnnounceConfirm(&(pGCCMessage->u.announce_presence_confirm));
  209. break;
  210. case GCC_ROSTER_REPORT_INDICATION:
  211. HandleRosterReport(pGCCMessage->u.conf_roster_report_indication.conference_roster);
  212. break;
  213. case GCC_ROSTER_INQUIRE_CONFIRM:
  214. HandleRosterReport(pGCCMessage->u.conf_roster_inquire_confirm.conference_roster);
  215. break;
  216. case GCC_PERMIT_TO_ANNOUNCE_PRESENCE:
  217. HandlePermitToAnnounce(&(pGCCMessage->u.permit_to_announce_presence));
  218. break;
  219. case GCC_EJECT_USER_INDICATION:
  220. HandleEjectUser(&(pGCCMessage->u.eject_user_indication));
  221. break;
  222. case GCC_CONNECTION_BROKEN_INDICATION:
  223. HandleConnectionBrokenIndication(&(pGCCMessage->u.connection_broken_indication));
  224. break;
  225. default :
  226. WARNING_OUT(("Unrecognised event %d", pGCCMessage->message_type));
  227. break;
  228. }
  229. DebugExitVOID(DCRNCConference::HandleGCCCallback);
  230. }
  231. void DCRNCConference::
  232. HandleConnectionBrokenIndication ( ConnectionBrokenIndicationMessage * pConnDownMsg )
  233. {
  234. DebugEntry(DCRNCConference::HandleConnectionBrokenIndication);
  235. // A logical connection in a conference has gone away.
  236. // Find the associated logical connection (if it is still around)
  237. // and Delete() it.
  238. // This function is what causes a modem line to drop when someone
  239. // invited into a conference over a modem leaves the conference.
  240. CLogicalConnection *pConEntry = GetConEntry(pConnDownMsg->connection_handle);
  241. if (NULL != pConEntry)
  242. {
  243. pConEntry->Delete(UI_RC_USER_DISCONNECTED);
  244. }
  245. DebugExitVOID(DCRNCConference::HandleConnectionBrokenIndication);
  246. }
  247. /****************************************************************************/
  248. /* HandleAddConfirm - handle a GCC_ADD_CONFIRM message */
  249. /****************************************************************************/
  250. /****************************************************************************/
  251. /* HandleAnnounceConfirm - handle a GCC_ANNOUNCE_PRESENCE_CONFIRM message */
  252. /****************************************************************************/
  253. void DCRNCConference::
  254. HandleAnnounceConfirm ( AnnouncePresenceConfirmMessage * pAnnounceConf )
  255. {
  256. DebugEntry(DCRNCConference::HandleAnnounceConfirm);
  257. /************************************************************************/
  258. /* Map the return code to a conference return code. */
  259. /************************************************************************/
  260. HRESULT hr = ::GetGCCResultDetails(pAnnounceConf->result);
  261. TRACE_OUT(("GCC event: GCC_ANNOUNCE_PRESENCE_CONFIRM"));
  262. TRACE_OUT(("Result=%u", pAnnounceConf->result));
  263. /************************************************************************/
  264. /* If this failed, tell the base conference that we failed to start. */
  265. /************************************************************************/
  266. if (NO_ERROR != hr)
  267. {
  268. ERROR_OUT(("Failed to announce presence in conference"));
  269. NotifyConferenceComplete(hr);
  270. // bugbug: ??? Should we leave the conference here???
  271. }
  272. /************************************************************************/
  273. /* Now sit and wait for our entry to appear in the conference roster. */
  274. /************************************************************************/
  275. DebugExitHRESULT(DCRNCConference::HandleAnnounceConfirm, hr);
  276. }
  277. /****************************************************************************/
  278. /* HandleCreateConfirm - handle a GCC_CREATE_CONFIRM message. */
  279. /****************************************************************************/
  280. void DCRNCConference::
  281. HandleCreateConfirm ( CreateConfirmMessage * pCreateConfirm )
  282. {
  283. DebugEntry(DCRNCConference::HandleCreateConfirm);
  284. /************************************************************************/
  285. /* Map the GCC result onto CONF_RC_ return code. */
  286. /************************************************************************/
  287. HRESULT hr = ::GetGCCResultDetails(pCreateConfirm->result);
  288. TRACE_OUT(("GCC event: GCC_CREATE_CONFIRM"));
  289. TRACE_OUT(("Result=%u", pCreateConfirm->result));
  290. TRACE_OUT(("Conference ID %ld", pCreateConfirm->conference_id));
  291. /************************************************************************/
  292. /* Result of our attempt to start a new conference */
  293. /************************************************************************/
  294. if (NO_ERROR == hr)
  295. {
  296. /************************************************************************/
  297. /* Store the conference ID. */
  298. /************************************************************************/
  299. m_nConfID = pCreateConfirm->conference_id;
  300. }
  301. else
  302. {
  303. ERROR_OUT(("Error %d creating new conference", hr));
  304. /************************************************************************/
  305. /* Pass any failure result onto the base conference. */
  306. /************************************************************************/
  307. NotifyConferenceComplete(hr);
  308. }
  309. DebugExitVOID(DCRNCConference::HandleCreateConfirm);
  310. }
  311. /****************************************************************************/
  312. /* HandleDisconnectConfirm - handle a GCC_DISCONNECT_CONFIRM message. */
  313. /****************************************************************************/
  314. void DCRNCConference::
  315. HandleDisconnectConfirm ( DisconnectConfirmMessage * pDiscConf )
  316. {
  317. DebugEntry(DCRNCConference::HandleDisconnectConfirm);
  318. /************************************************************************/
  319. /* Check the state. */
  320. /************************************************************************/
  321. if (m_eT120State != T120C_ST_PENDING_DISCONNECT)
  322. {
  323. WARNING_OUT(("Bad state %d, expecting %d",
  324. T120C_ST_PENDING_DISCONNECT,
  325. m_eT120State));
  326. }
  327. /************************************************************************/
  328. /* Map the GCC result onto CONF_RC_ return code. */
  329. /************************************************************************/
  330. TRACE_OUT(("GCC event: GCC_DISCONNECT_CONFIRM"));
  331. TRACE_OUT(("Result=%u", pDiscConf->result));
  332. TRACE_OUT(("Conference ID %ld", pDiscConf->conference_id));
  333. /************************************************************************/
  334. /* We have successsfully left the conference, so tell the base */
  335. /* conference about it. */
  336. /************************************************************************/
  337. g_pNCConfMgr->RemoveConference(this);
  338. DebugExitVOID(DCRNCConference::HandleDisconnectConfirm);
  339. }
  340. /****************************************************************************/
  341. /* HandleDisconnectInd - handle a GCC_DISCONNECT_INDICATION message. */
  342. /****************************************************************************/
  343. void DCRNCConference::
  344. HandleDisconnectInd ( DisconnectIndicationMessage * pDiscInd )
  345. {
  346. DebugEntry(DCRNCConference::HandleDisconnectInd);
  347. /************************************************************************/
  348. /* Check the state. */
  349. /************************************************************************/
  350. TRACE_OUT(("GCC event: GCC_DISCONNECT_INDICATION"));
  351. TRACE_OUT(("Conference ID %d", pDiscInd->conference_id));
  352. TRACE_OUT(("Reason=%u", pDiscInd->reason));
  353. TRACE_OUT(("Disconnected Node ID %d", pDiscInd->disconnected_node_id));
  354. /************************************************************************/
  355. /* If this is our node ID, we have left the conference, tell the CM we */
  356. /* are dead. */
  357. /************************************************************************/
  358. if (pDiscInd->disconnected_node_id == m_nidMyself)
  359. {
  360. WARNING_OUT(("We have been disconnected from conference"));
  361. // m_eT120State = T120C_ST_IDLE;
  362. g_pNCConfMgr->RemoveConference(this);
  363. }
  364. DebugExitVOID(DCRNCConference::HandleDisconnectInd);
  365. }
  366. /****************************************************************************/
  367. /* HandleEjectUser - handle a GCC_EJECT_USER_INDICATION message. */
  368. /****************************************************************************/
  369. void DCRNCConference::
  370. HandleEjectUser ( EjectUserIndicationMessage * pEjectInd )
  371. {
  372. DebugEntry(DCRNCConference::HandleEjectUser);
  373. TRACE_OUT(("GCC_EJECT_USER_INDICATION"));
  374. TRACE_OUT(("Conference ID %ld", pEjectInd->conference_id));
  375. TRACE_OUT(("Ejected node ID %d", pEjectInd->ejected_node_id));
  376. TRACE_OUT(("Reason=%u", pEjectInd->reason));
  377. /************************************************************************/
  378. /* If the ejected node ID is ours, we have been tossed out of the */
  379. /* conference, so tell CM about it. */
  380. /************************************************************************/
  381. if (pEjectInd->ejected_node_id == m_nidMyself)
  382. {
  383. /********************************************************************/
  384. /* Reset the conference state first. */
  385. /********************************************************************/
  386. m_eT120State = T120C_ST_IDLE;
  387. WARNING_OUT(("We have been thrown out of the conference"));
  388. g_pNCConfMgr->RemoveConference(this);
  389. }
  390. DebugExitVOID(DCRNCConference::HandleEjectUser);
  391. }
  392. /****************************************************************************/
  393. /* HandleInviteConfirm - handle a GCC_INVITE_CONFIRM message. */
  394. /****************************************************************************/
  395. void DCRNCConference::
  396. HandleInviteConfirm ( InviteConfirmMessage * pInviteConf )
  397. {
  398. DebugEntry(DCRNCConference::HandleInviteConfirm);
  399. /************************************************************************/
  400. /* Map the GCC result onto CONF_RC_ return code. */
  401. /************************************************************************/
  402. TRACE_OUT(("GCC event: GCC_INVITE_CONFIRM"));
  403. TRACE_OUT(("Result=%u", pInviteConf->result));
  404. if (pInviteConf->result == GCC_RESULT_SUCCESSFUL)
  405. {
  406. TRACE_OUT(("New node successfully invited into conference"));
  407. ASSERT((ConnectionHandle)pInviteConf->connection_handle);
  408. }
  409. else
  410. {
  411. TRACE_OUT(("Error %d inviting new node into conference", pInviteConf->result));
  412. }
  413. InviteComplete(pInviteConf->connection_handle,
  414. ::GetGCCResultDetails(pInviteConf->result));
  415. DebugExitVOID(DCRNCConference::HandleInviteConfirm);
  416. }
  417. /****************************************************************************/
  418. /* HandleJoinConfirm - handle a GCC_JOIN_CONFIRM message. */
  419. /****************************************************************************/
  420. void DCRNCConference::
  421. HandleJoinConfirm ( JoinConfirmMessage * pJoinConf )
  422. {
  423. DebugEntry(DCRNCConference::HandleJoinConfirm);
  424. m_nConfID = pJoinConf->conference_id;
  425. HRESULT hr;
  426. CLogicalConnection *pConEntry;
  427. hr = ::GetGCCResultDetails(pJoinConf->result);
  428. TRACE_OUT(("GCC event: GCC_JOIN_CONFIRM"));
  429. TRACE_OUT(("Result=%u", pJoinConf->result));
  430. TRACE_OUT(("Conference ID %ld", pJoinConf->conference_id));
  431. TRACE_OUT(("Locked %d", pJoinConf->conference_is_locked));
  432. TRACE_OUT(("Listed %d", pJoinConf->conference_is_listed));
  433. TRACE_OUT(("Conductible %d", pJoinConf->conference_is_conductible));
  434. TRACE_OUT(("Connection Handle %d", pJoinConf->connection_handle));
  435. TRACE_OUT(("Termination method %d", pJoinConf->termination_method));
  436. // Check the state.
  437. // If we are not expecting a join confirm at this point, then
  438. // it is most likely that the connection went down whilst we
  439. // were waiting for a join confirmation and we are in the middle of
  440. // telling the user. In this case, just ignore the event.
  441. if (m_eT120State != T120C_ST_PENDING_JOIN_CONFIRM)
  442. {
  443. WARNING_OUT(("Bad state %d, expecting %d",
  444. T120C_ST_PENDING_JOIN_CONFIRM,
  445. m_eT120State));
  446. return;
  447. }
  448. if (NULL == m_ConnList.PeekHead())
  449. {
  450. WARNING_OUT(("Join confirm without a connection"));
  451. return;
  452. }
  453. pConEntry = m_ConnList.PeekHead();
  454. if ((pConEntry->GetState() != CONF_CON_PENDING_JOIN) &&
  455. (pConEntry->GetState() != CONF_CON_PENDING_PASSWORD))
  456. {
  457. if (pConEntry->GetState() != CONF_CON_ERROR)
  458. {
  459. TRACE_OUT(("Join confirm indication ignored"));
  460. }
  461. return;
  462. }
  463. pConEntry->Grab(); // Grab the pending result to the user.
  464. pConEntry->SetConnectionHandle(pJoinConf->connection_handle);
  465. /************************************************************************/
  466. /* Expected result of our attempt to join a conference. */
  467. /* */
  468. /* If it worked, save the conference ID, otherwise tell the base */
  469. /* conference that our attempt to join has failed. */
  470. /************************************************************************/
  471. // There will always be a pConEntry when a JoinConfirm fires,
  472. // even if a physical disconnect is racing the JoinConfirm
  473. // because the physical disconnect handler will cause this code
  474. // to be entered before the physical connection is destroyed,
  475. // as this gives the most accurate return codes.
  476. if (NO_ERROR == hr)
  477. {
  478. TRACE_OUT(("Join worked"));
  479. pConEntry->SetState(CONF_CON_CONNECTED);
  480. m_nConfID = pJoinConf->conference_id;
  481. }
  482. // If the result is an invalid password, then tell the UI
  483. // so that it can put up an invalid password dialog.
  484. // The UI is then supposed to either reissue the join request
  485. // with a new password or end the conference.
  486. // It is done this way to keep the connection up whilst the
  487. // user is entering the password, and not re-connect.
  488. if (UI_RC_INVALID_PASSWORD == hr)
  489. {
  490. // Put the conference in the correct state for allowing
  491. // a second join attempt.
  492. pConEntry->SetState(CONF_CON_PENDING_PASSWORD);
  493. m_eT120State = T120C_ST_IDLE;
  494. m_pbCred = pJoinConf->pb_remote_cred;
  495. m_cbCred = pJoinConf->cb_remote_cred;
  496. // Now tell the user about the result.
  497. g_pCallbackInterface->OnConferenceStarted(this, hr);
  498. }
  499. else
  500. // If the result is an error, then end the conference.
  501. if (NO_ERROR != hr)
  502. {
  503. NotifyConferenceComplete(hr);
  504. }
  505. DebugExitVOID(DCRNCConference::HandleJoinConfirm);
  506. }
  507. /****************************************************************************/
  508. /* HandlePermitToAnnounce - handle a GCC_PERMIT_TO_ANNOUNCE_PRESENCE */
  509. /* message. */
  510. /****************************************************************************/
  511. void DCRNCConference::
  512. HandlePermitToAnnounce ( PermitToAnnouncePresenceMessage * pAnnounce )
  513. {
  514. DebugEntry(DCRNCConference::HandlePermitToAnnounce);
  515. TRACE_OUT(("GCC event: GCC_PERMIT_TO_ANNOUNCE_PRESENCE"));
  516. TRACE_OUT(("Conference ID %ld", pAnnounce->conference_id));
  517. TRACE_OUT(("Node ID %d", pAnnounce->node_id));
  518. /************************************************************************/
  519. /* Store the node ID. */
  520. /************************************************************************/
  521. m_nidMyself = pAnnounce->node_id;
  522. // See if there is a new local connection that needs publishing in the roster.
  523. if (! m_ConnList.IsEmpty())
  524. {
  525. m_ConnList.PeekHead()->NewLocalAddress();
  526. }
  527. /************************************************************************/
  528. /* Announce our presence in the conference. */
  529. /************************************************************************/
  530. HRESULT hr = AnnouncePresence();
  531. if (NO_ERROR == hr)
  532. {
  533. m_eT120State = T120C_ST_PENDING_ROSTER_ENTRY;
  534. }
  535. else
  536. {
  537. ERROR_OUT(("Failed to announce presence in conference, error %d", hr));
  538. // bugbug: end conference?
  539. }
  540. DebugExitVOID(DCRNCConference::HandlePermitToAnnounce);
  541. }
  542. /****************************************************************************/
  543. /* HandleRosterReportInd - handle a GCC_ROSTER_REPORT_INDICATION message. */
  544. /****************************************************************************/
  545. void DCRNCConference::
  546. HandleRosterReport ( GCCConferenceRoster * pConferenceRoster )
  547. {
  548. PNC_ROSTER pRoster;
  549. UINT i;
  550. UINT numRecords = pConferenceRoster->number_of_records;
  551. DebugEntry(DCRNCConference::HandleRosterReport);
  552. TRACE_OUT(("GCC event: GCC_ROSTER_REPORT_INDICATION"));
  553. TRACE_OUT(("Nodes added ? %d", pConferenceRoster->nodes_were_added));
  554. TRACE_OUT(("Nodes removed ? %d", pConferenceRoster->nodes_were_removed));
  555. TRACE_OUT(("Number of records %d", numRecords));
  556. /************************************************************************/
  557. /* If we are still setting up the conference, see whether we have */
  558. /* appeared in the conference roster. */
  559. /************************************************************************/
  560. if (m_eT120State == T120C_ST_PENDING_ROSTER_ENTRY)
  561. {
  562. for (i = 0; i < numRecords ; i++)
  563. {
  564. if (pConferenceRoster->node_record_list[i]->node_id == m_nidMyself)
  565. {
  566. TRACE_OUT(("Found our entry in the roster"));
  567. // We are in the roster! The conference has been
  568. // successfully started so set the state and post
  569. // a message to continue processing.
  570. // This is so that callbacks can be made without getting
  571. // blocked in T120.
  572. m_eT120State = T120C_ST_PENDING_ROSTER_MESSAGE;
  573. g_pNCConfMgr->PostWndMsg(NCMSG_FIRST_ROSTER_RECVD, (LPARAM) this);
  574. }
  575. }
  576. }
  577. /************************************************************************/
  578. /* If we have successfully started, build an RNC roster from the */
  579. /* conference roster and pass it up to the CM. */
  580. /************************************************************************/
  581. if (m_eT120State == T120C_ST_CONF_STARTED)
  582. {
  583. /********************************************************************/
  584. /* Allocate memory for a roster large enough to hold all the */
  585. /* entries. */
  586. /********************************************************************/
  587. DBG_SAVE_FILE_LINE
  588. pRoster = (PNC_ROSTER) new BYTE[(sizeof(NC_ROSTER) +
  589. ((numRecords - 1) * sizeof(NC_ROSTER_NODE_ENTRY)))];
  590. if (pRoster == NULL)
  591. {
  592. ERROR_OUT(("Failed to create new conference roster."));
  593. }
  594. else
  595. {
  596. pRoster->uNumNodes = numRecords;
  597. pRoster->uLocalNodeID = m_nidMyself;
  598. // Add the node details to the roster.
  599. for (i = 0; i < numRecords ; i++)
  600. {
  601. pRoster->nodes[i].uNodeID = pConferenceRoster->node_record_list[i]->node_id;
  602. pRoster->nodes[i].uSuperiorNodeID = pConferenceRoster->node_record_list[i]->superior_node_id;
  603. pRoster->nodes[i].fMCU = (pConferenceRoster->node_record_list[i]->node_type == GCC_MCU);
  604. pRoster->nodes[i].pwszNodeName = pConferenceRoster->node_record_list[i]->node_name;
  605. pRoster->nodes[i].hUserData = pConferenceRoster->node_record_list[i];
  606. // If we have been invited into the conference, then the CLogicalConnection
  607. // list maintained by the conference will not have our superior node's UserID,
  608. // so we need to fill that in here.
  609. if (pRoster->nodes[i].uNodeID == pRoster->uLocalNodeID &&
  610. pRoster->nodes[i].uSuperiorNodeID != 0)
  611. {
  612. // We do have a superior node, so find its CLogicalConnection and fill in the
  613. // UserID. It turns out that the UserIDs of subordinate nodes are filled in
  614. // by another mechanism, so the superior node should be the only entry with
  615. // zero for a UserID.
  616. #ifdef DEBUG
  617. int nSuperiorNode = 0;
  618. #endif
  619. CLogicalConnection * pConEntry;
  620. m_ConnList.Reset();
  621. while (NULL != (pConEntry = m_ConnList.Iterate()))
  622. {
  623. if (pConEntry->GetConnectionNodeID() == 0)
  624. {
  625. pConEntry->SetConnectionNodeID((GCCNodeID)pRoster->nodes[i].uSuperiorNodeID);
  626. #ifdef DEBUG
  627. nSuperiorNode++;
  628. #else
  629. break;
  630. #endif
  631. }
  632. }
  633. ASSERT (nSuperiorNode <= 1);
  634. }
  635. }
  636. NotifyRosterChanged(pRoster);
  637. delete pRoster;
  638. }
  639. }
  640. DebugExitVOID(DCRNCConference::HandleRosterReport);
  641. }
  642. /****************************************************************************/
  643. /* HandleTerminateConfirm - handle a GCC_TERMINATE_CONFIRM message. */
  644. /****************************************************************************/
  645. void DCRNCConference::
  646. HandleTerminateConfirm ( TerminateConfirmMessage * pTermConf )
  647. {
  648. DebugEntry(DCRNCConference::HandleTerminateConfirm);
  649. /************************************************************************/
  650. /* Check the state */
  651. /************************************************************************/
  652. if (m_eT120State != T120C_ST_PENDING_TERMINATE)
  653. {
  654. WARNING_OUT(("Bad state: unexpected terminate confirm")); // Go ahead anyway
  655. }
  656. /************************************************************************/
  657. /* Map the GCC result onto CONF_RC_ return code. */
  658. /************************************************************************/
  659. TRACE_OUT(("GCC event: GCC_TERMINATE_CONFIRM"));
  660. TRACE_OUT(("Result=%u", pTermConf->result));
  661. TRACE_OUT(("Conference ID %d", pTermConf->conference_id));
  662. /************************************************************************/
  663. /* If the request failed, reset our state and tell the FE? */
  664. /************************************************************************/
  665. if (pTermConf->result != GCC_RESULT_SUCCESSFUL)
  666. {
  667. ERROR_OUT(("Error %d attempting to terminate conference", pTermConf->result));
  668. m_eT120State = T120C_ST_CONF_STARTED;
  669. }
  670. /************************************************************************/
  671. /* Our request to end the conference has worked - wait for the */
  672. /* termination indication before telling the FE that we have died. */
  673. /************************************************************************/
  674. DebugExitVOID(DCRNCConference::HandleTerminateConfirm);
  675. }
  676. /****************************************************************************/
  677. /* HandleTerminateInd - handle a GCC_TERMINATE_INDICATION message. */
  678. /****************************************************************************/
  679. void DCRNCConference::
  680. HandleTerminateInd ( TerminateIndicationMessage * pTermInd )
  681. {
  682. DebugEntry(DCRNCConference::HandleTerminateInd);
  683. TRACE_OUT(("GCC event: GCC_TERMINATE_INDICATION"));
  684. TRACE_OUT(("Conference ID %d", pTermInd->conference_id));
  685. TRACE_OUT(("Requesting node ID %d", pTermInd->requesting_node_id));
  686. TRACE_OUT(("Reason=%u", pTermInd->reason));
  687. /************************************************************************/
  688. /* The conference has ended beneath us. Reset our internal state and */
  689. /* tell the base conference about it. */
  690. /************************************************************************/
  691. m_eT120State = T120C_ST_IDLE;
  692. g_pNCConfMgr->RemoveConference(this);
  693. DebugExitVOID(DCRNCConference::HandleTerminateInd);
  694. }
  695. HRESULT DCRNCConference::
  696. RefreshRoster(void)
  697. {
  698. DebugEntry(DCRNCConference::RefreshRoster);
  699. // Check the state.
  700. if (m_eT120State != T120C_ST_CONF_STARTED)
  701. {
  702. ERROR_OUT(("Bad state: refresh roster requested before conference up"));
  703. return(UI_RC_CONFERENCE_NOT_READY);
  704. }
  705. // Issue the request
  706. GCCError GCCrc = g_pIT120ControlSap->ConfRosterInqRequest(m_nConfID); // Conference ID
  707. // Handle the result
  708. HRESULT hr = ::GetGCCRCDetails(GCCrc);
  709. TRACE_OUT(("GCC call: g_pIT120ControlSap->ConfRosterInqRequest, rc=%d", GCCrc));
  710. DebugExitHRESULT(DCRNCConference::RefreshRoster, hr);
  711. return hr;
  712. }
  713. /****************************************************************************/
  714. /* Invite() - see erncgccc.hpp */
  715. /****************************************************************************/
  716. HRESULT DCRNCConference::
  717. T120Invite
  718. (
  719. LPSTR pszNodeAddress,
  720. BOOL fSecure,
  721. CNCUserDataList *pUserDataInfoList,
  722. ConnectionHandle *phInviteReqConn
  723. )
  724. {
  725. GCCError GCCrc = GCC_NO_ERROR;
  726. HRESULT hr;
  727. UINT nData;
  728. PVOID pData;
  729. char szAddress[RNC_MAX_NODE_STRING_LEN];
  730. DebugEntry(DCRNCConference::T120Invite);
  731. ASSERT(phInviteReqConn != NULL);
  732. /************************************************************************/
  733. /* Check the state. */
  734. /************************************************************************/
  735. if (m_eT120State != T120C_ST_CONF_STARTED)
  736. {
  737. ERROR_OUT(("Bad state: refresh roster requested before conference up"));
  738. return(UI_RC_CONFERENCE_NOT_READY);
  739. }
  740. /************************************************************************/
  741. /* Build the address from the node details. */
  742. /************************************************************************/
  743. ::BuildAddressFromNodeDetails(pszNodeAddress, &szAddress[0]);
  744. /************************************************************************/
  745. /* Invite the specified node into the conference. */
  746. /************************************************************************/
  747. BSTR szLocalName;
  748. if (NULL != (szLocalName = ::GetNodeName()))
  749. {
  750. GCCrc = g_pIT120ControlSap->ConfInviteRequest(
  751. m_nConfID,
  752. szLocalName, // caller_identifier
  753. NULL, // calling_address
  754. &szAddress[0], // called_address
  755. fSecure, // secure connection?
  756. 0,
  757. NULL,
  758. phInviteReqConn // returned connection_handle
  759. );
  760. hr = ::GetGCCRCDetails(GCCrc);
  761. TRACE_OUT(("GCC call: g_pIT120ControlSap->ConfInviteRequest, rc=%d", GCCrc));
  762. TRACE_OUT(("Transport handle %d", (UINT) *phInviteReqConn));
  763. TRACE_OUT(("Called address '%s'", &szAddress[0]));
  764. SysFreeString(szLocalName);
  765. }
  766. else
  767. {
  768. hr = UI_RC_OUT_OF_MEMORY;
  769. }
  770. DebugExitHRESULT(DCRNCConference::T120Invite, hr);
  771. return hr;
  772. }
  773. /****************************************************************************/
  774. /* Terminate() - see erncgccc.hpp */
  775. /****************************************************************************/
  776. #if 0 // LONCHANC
  777. HRESULT DCRNCConference::
  778. Terminate(void)
  779. {
  780. DebugEntry(DCRNCConference::Terminate);
  781. /************************************************************************/
  782. /* Request to terminate the conference. */
  783. /************************************************************************/
  784. GCCError GCCrc = ::GCCConferenceTerminateRequest(m_nConfID, GCC_REASON_USER_INITIATED);
  785. HRESULT hr = ::GetGCCRCDetails(GCCrc);
  786. TRACE_OUT(("GCC call: GCCConferenceTerminateRequest, rc=%d", GCCrc));
  787. if (NO_ERROR == hr)
  788. {
  789. // Set the state to show we are about to die.
  790. m_eT120State = T120C_ST_PENDING_TERMINATE;
  791. }
  792. else
  793. {
  794. ERROR_OUT(("Failed to terminate conference, GCC error %d", GCCrc));
  795. }
  796. DebugExitHRESULT(DCRNCConference::Terminate, hr);
  797. return hr;
  798. }
  799. #endif // 0
  800. /****************************************************************************/
  801. /* SendText() - see erncgccc.hpp */
  802. /****************************************************************************/
  803. #if 0 // LONCHANC: not used
  804. HRESULT DCRNCConference::
  805. SendText
  806. (
  807. LPWSTR pwszTextMsg,
  808. GCCNodeID node_id
  809. )
  810. {
  811. DebugEntry(DCRNCConference::SendText);
  812. /************************************************************************/
  813. /* Request to send text to node in the conference. */
  814. /************************************************************************/
  815. GCCError GCCrc = ::GCCTextMessageRequest(m_nConfID, pwszTextMsg, node_id);
  816. HRESULT hr = ::GetGCCRCDetails(GCCrc);
  817. TRACE_OUT(("GCC call: GCCTextMessageRequest, rc=%d", GCCrc));
  818. if (NO_ERROR != hr)
  819. {
  820. ERROR_OUT(("Failed to send text to user, GCC error %d", GCCrc));
  821. }
  822. DebugExitHRESULT(DCRNCConference::SendText, hr);
  823. return hr;
  824. }
  825. #endif // 0
  826. #if 0 // LONCHANC: not used
  827. HRESULT DCRNCConference::
  828. TimeRemaining
  829. (
  830. UINT nTimeRemaining,
  831. GCCNodeID nidDestination
  832. )
  833. {
  834. DebugEntry(DCRNCConference::TimeRemaining);
  835. /************************************************************************/
  836. /* Request remaining time of the conference */
  837. /************************************************************************/
  838. GCCError GCCrc = g_pIT120ControlSap->ConfTimeRemainingRequest(m_nConfID, nTimeRemaining, nidDestination);
  839. HRESULT hr = ::GetGCCRCDetails(GCCrc);
  840. TRACE_OUT(("GCC call: g_pIT120ControlSap->ConfTimeRemainingRequest, rc=%d", GCCrc));
  841. if (NO_ERROR != hr)
  842. {
  843. ERROR_OUT(("Failed to send the time remaining to user, GCC error %d", GCCrc));
  844. }
  845. DebugExitHRESULT(DCRNCConference::TimeRemaining, hr);
  846. return hr;
  847. }
  848. #endif // 0
  849. /****************************************************************************/
  850. /* Join() - see erncgccc.hpp */
  851. /****************************************************************************/
  852. HRESULT DCRNCConference::
  853. T120Join
  854. (
  855. LPSTR pszNodeAddress,
  856. BOOL fSecure,
  857. LPCWSTR conferenceName,
  858. CNCUserDataList *pUserDataInfoList,
  859. LPCWSTR wszPassword
  860. // REQUEST_HANDLE *phRequest
  861. )
  862. {
  863. GCCError GCCrc = GCC_NO_ERROR;
  864. HRESULT hr = NO_ERROR;
  865. ConnectionHandle connectionHandle = 0;
  866. GCCChallengeRequestResponse Password_Challenge;
  867. GCCChallengeRequestResponse *pPassword_Challenge = NULL;
  868. Password_Challenge.u.password_in_the_clear.numeric_string = NULL;
  869. UINT nUserDataRecords = 0;
  870. GCCUserData **ppInfoUserData = NULL;
  871. UINT nData;
  872. LPVOID pData;
  873. char szAddress[RNC_MAX_NODE_STRING_LEN];
  874. DebugEntry(DCRNCConference::T120Join);
  875. /************************************************************************/
  876. /* Check the state */
  877. /************************************************************************/
  878. ASSERT(m_eT120State == T120C_ST_IDLE);
  879. /************************************************************************/
  880. /* Build the address from the node details. */
  881. /************************************************************************/
  882. ::BuildAddressFromNodeDetails(pszNodeAddress, &szAddress[0]);
  883. // Set up password rubbish
  884. if (! ::IsEmptyStringW(wszPassword))
  885. {
  886. pPassword_Challenge = & Password_Challenge;
  887. Password_Challenge.password_challenge_type = GCC_PASSWORD_IN_THE_CLEAR;
  888. hr = ::GetGCCFromUnicode(wszPassword,
  889. &Password_Challenge.u.password_in_the_clear.numeric_string,
  890. &Password_Challenge.u.password_in_the_clear.text_string);
  891. }
  892. if (NO_ERROR == hr)
  893. {
  894. BSTR szLocalName;
  895. if (NULL != (szLocalName = ::GetNodeName()))
  896. {
  897. // Do not specify a numeric and text name when trying
  898. // to join a conference because if a numeric name was
  899. // autogenerated, rather than specified by the user,
  900. // then it will not be correct on the node being joined.
  901. // Consequently, remove the numeric name from the request
  902. // and rediscover it, if needed, from the GCC_JOIN_CONFIRM indication
  903. // (this is not currently done).
  904. if ((m_ConfName.numeric_string != NULL) && (m_ConfName.text_string != NULL))
  905. {
  906. delete m_ConfName.numeric_string;
  907. m_ConfName.numeric_string = NULL;
  908. }
  909. GCCrc = g_pIT120ControlSap->ConfJoinRequest(&m_ConfName,
  910. NULL, // called_node_modifier
  911. NULL, // calling_node_modifier
  912. NULL, // convener_password
  913. pPassword_Challenge, // password_challenge
  914. szLocalName, // caller_identifier
  915. NULL, // calling_address
  916. &szAddress[0], // called_address
  917. fSecure,
  918. NULL, // domain_parameters
  919. 0, // number_of_network_addresses
  920. NULL, // local_network_address_list
  921. nUserDataRecords, // number_of_user_data_members
  922. ppInfoUserData, // user_data_list
  923. &connectionHandle, // connection_handle
  924. &m_nConfID
  925. );
  926. SysFreeString(szLocalName);
  927. hr = ::GetGCCRCDetails(GCCrc);
  928. TRACE_OUT(("GCC call: g_pIT120ControlSap->ConfJoinRequest, rc=%d", GCCrc));
  929. TRACE_OUT(("Called address '%s'", &szAddress[0]));
  930. if (NO_ERROR == hr)
  931. {
  932. m_eT120State = T120C_ST_PENDING_JOIN_CONFIRM;
  933. }
  934. }
  935. else
  936. {
  937. hr = UI_RC_OUT_OF_MEMORY;
  938. }
  939. }
  940. delete Password_Challenge.u.password_in_the_clear.numeric_string;
  941. DebugExitHRESULT(DCRNCConference::T120Join, hr);
  942. return hr;
  943. }
  944. /****************************************************************************/
  945. /* StartLocal() - see erncgccc.hpp */
  946. /****************************************************************************/
  947. HRESULT DCRNCConference::
  948. T120StartLocal(BOOL fSecure)
  949. {
  950. GCCError GCCrc;
  951. HRESULT hr;
  952. ConnectionHandle hConnection = 0;
  953. GCCConferencePrivileges priv = {1,1,1,1,1};
  954. WCHAR pwszRDS[] = RDS_CONFERENCE_DESCRIPTOR;
  955. DebugEntry(DCRNCConference::T120StartLocal);
  956. /************************************************************************/
  957. /* Call GCC_Conference_Create_Request and wait for the confirmation */
  958. /* event. */
  959. /************************************************************************/
  960. GCCConfCreateRequest ccr;
  961. ::ZeroMemory(&ccr, sizeof(ccr));
  962. ccr.Core.conference_name = &m_ConfName;
  963. // ccr.Core.conference_modifier = NULL;
  964. // ccr.Core.use_password_in_the_clear = 0;
  965. // ccr.Core.conference_is_locked = 0;
  966. ccr.Core.conference_is_listed = 1;
  967. // ccr.Core.conference_is_conductible = 0;
  968. ccr.Core.termination_method = GCC_MANUAL_TERMINATION_METHOD;
  969. ccr.Core.conduct_privilege_list = &priv; // Conductor priveleges
  970. ccr.Core.conduct_mode_privilege_list = &priv; // Member priveleges in conducted conference
  971. ccr.Core.non_conduct_privilege_list = &priv; // Member priveleges in non-conducted conference
  972. // ccr.Core.pwszConfDescriptor = NULL;
  973. OSVERSIONINFO osvi;
  974. osvi.dwOSVersionInfoSize = sizeof(osvi);
  975. if (FALSE == ::GetVersionEx (&osvi))
  976. {
  977. ERROR_OUT(("GetVersionEx() failed!"));
  978. }
  979. if ( VER_PLATFORM_WIN32_NT == osvi.dwPlatformId && g_bRDS)
  980. {
  981. ccr.Core.pwszConfDescriptor = pwszRDS;
  982. }
  983. // ccr.Core.pwszCallerID = NULL;
  984. // ccr.Core.calling_address = NULL;
  985. // ccr.Core.called_address = NULL;
  986. // ccr.Core.domain_parameters = NULL;
  987. // ccr.Core.number_of_network_addresses = 0;
  988. // ccr.Core.network_address_list = NULL;
  989. ccr.Core.connection_handle = &hConnection;
  990. // ccr.convener_password = NULL;
  991. // ccr.password = NULL;
  992. // ccr.number_of_user_data_members = 0;
  993. // ccr.user_data_list = NULL;
  994. ccr.fSecure = fSecure;
  995. GCCrc = g_pIT120ControlSap->ConfCreateRequest(&ccr, &m_nConfID);
  996. hr = ::GetGCCRCDetails(GCCrc);
  997. TRACE_OUT(("GCC call: g_pIT120ControlSap->ConfCreateRequest"));
  998. TRACE_OUT(("LOCAL CONFERENCE"));
  999. TRACE_OUT(("Connection handle %d", (UINT) hConnection));
  1000. /************************************************************************/
  1001. /* Map the GCC return code to a conference return code. */
  1002. /************************************************************************/
  1003. if (NO_ERROR == hr)
  1004. {
  1005. // Set the state.
  1006. m_eT120State = T120C_ST_PENDING_START_CONFIRM;
  1007. }
  1008. else
  1009. {
  1010. ERROR_OUT(("GCC Error %d starting local conference", GCCrc));
  1011. }
  1012. DebugExitHRESULT(DCRNCConference::T120StartLocal, hr);
  1013. return hr;
  1014. }
  1015. // LONCHANC: please do not remove this chunk of code.
  1016. #ifdef ENABLE_START_REMOTE
  1017. /****************************************************************************/
  1018. /* StartRemote() - see erncgccc.hpp */
  1019. /****************************************************************************/
  1020. HRESULT DCRNCConference::
  1021. T120StartRemote ( LPSTR pszNodeAddress )
  1022. {
  1023. // Do not allow attempts to create T120 conferences on remote nodes.
  1024. // The code that was written to do this is left here in case someone
  1025. // wants to resurrect this functionality in the future.
  1026. GCCError GCCrc;
  1027. HRESULT hr;
  1028. ConnectionHandle connectionHandle = 0;
  1029. GCCConferencePrivileges priv = {1,1,1,1,1};
  1030. char szAddress[RNC_MAX_NODE_STRING_LEN];
  1031. DebugEntry(DCRNCConference::T120StartRemote);
  1032. /************************************************************************/
  1033. /* Build the address from the node details. */
  1034. /************************************************************************/
  1035. ::BuildAddressFromNodeDetails(pszNodeAddress, &szAddress[0]);
  1036. /************************************************************************/
  1037. /* Call GCC_Conference_Create_Request and wait for the confirmation */
  1038. /* event. */
  1039. /************************************************************************/
  1040. TRACE_OUT(("Starting New Remote Conference..."));
  1041. /************************************************************************/
  1042. /* Call GCC_Conference_Create_Request and wait for the confirmation */
  1043. /* event. */
  1044. /************************************************************************/
  1045. GCCConfCreateRequest ccr;
  1046. ::ZeroMemory(&ccr, sizeof(ccr));
  1047. ccr.Core.conference_name = &m_ConfName;
  1048. ccr.Core.conference_modifier = NULL;
  1049. // ccr.Core.use_password_in_the_clear = 0;
  1050. // ccr.Core.conference_is_locked = 0;
  1051. ccr.Core.conference_is_listed = 1;
  1052. ccr.Core.conference_is_conductible = 1;
  1053. ccr.Core.termination_method = GCC_AUTOMATIC_TERMINATION_METHOD;
  1054. ccr.Core.conduct_privilege_list = &priv; // Conductor priveleges
  1055. ccr.Core.conduct_mode_privilege_list = &priv; // Member priveleges in conducted conference
  1056. ccr.Core.non_conduct_privilege_list = &priv; // Member priveleges in non-conducted conference
  1057. // ccr.Core.pwszConfDescriptor = NULL;
  1058. // ccr.Core.pwszCallerID = NULL;
  1059. // ccr.Core.calling_address = NULL;
  1060. ccr.Core.called_address = &szAddress[0];
  1061. // ccr.Core.domain_parameters = NULL;
  1062. // ccr.Core.number_of_network_addresses = 0;
  1063. // ccr.Core.network_address_list = NULL;
  1064. ccr.Core.connection_handle = &connectionHandle;
  1065. // ccr.convener_password = NULL;
  1066. // ccr.password = NULL;
  1067. // ccr.number_of_user_data_members = 0;
  1068. // ccr.user_data_list = NULL;
  1069. GCCrc = g_pIT120ControlSap->ConfCreateRequest(&ccr, &m_nConfID);
  1070. hr = ::GetGCCRCDetails(GCCrc);
  1071. TRACE_OUT(("GCC call: g_pIT120ControlSap->ConfCreateRequest"));
  1072. TRACE_OUT(("Called address '%s'", &szAddress[0]));
  1073. TRACE_OUT(("Connection handle %d", connectionHandle));
  1074. /************************************************************************/
  1075. /* Map the GCC return code to a conference return code. */
  1076. /************************************************************************/
  1077. if (NO_ERROR != hr)
  1078. {
  1079. ERROR_OUT(("GCC Error %d starting local conference", GCCrc));
  1080. }
  1081. else
  1082. {
  1083. // Set the state.
  1084. m_eT120State = T120C_ST_PENDING_START_CONFIRM;
  1085. }
  1086. DebugExitHRESULT(DCRNCConference::T120StartRemote, hr);
  1087. return hr;
  1088. }
  1089. #endif // ENABLE_START_REMOTE
  1090. void LoadAnnouncePresenceParameters
  1091. (
  1092. GCCNodeType *nodeType,
  1093. GCCNodeProperties *nodeProperties,
  1094. BSTR *ppwszNodeName,
  1095. LPWSTR *ppwszSiteInformation
  1096. )
  1097. {
  1098. DebugEntry(LoadAnnouncePresenceParameters);
  1099. // Get the type of node controller.
  1100. if (nodeType)
  1101. {
  1102. *nodeType = GCC_MULTIPORT_TERMINAL;
  1103. }
  1104. // Load the node properties.
  1105. if (nodeProperties)
  1106. {
  1107. *nodeProperties = GCC_NEITHER_PERIPHERAL_NOR_MANAGEMENT;
  1108. }
  1109. if (ppwszNodeName)
  1110. {
  1111. // Rely upon GetNodeName returning NULL pointer if error.
  1112. // Note that successful if got this, so no need to free on error.
  1113. *ppwszNodeName = GetNodeName();
  1114. }
  1115. DebugExitVOID(LoadAnnouncePresenceParameters);
  1116. }
  1117. /****************************************************************************/
  1118. /* Build the address from the node details. */
  1119. /****************************************************************************/
  1120. void BuildAddressFromNodeDetails
  1121. (
  1122. LPSTR pszNodeAddress,
  1123. LPSTR pszDstAddress
  1124. )
  1125. {
  1126. DebugEntry(BuildAddressFromNodeDetails);
  1127. /************************************************************************/
  1128. /* GCC address take the form <transport type>:address. */
  1129. /************************************************************************/
  1130. TRACE_OUT(("BuildAddressFromNodeDetails:: TCP address '%s'", pszNodeAddress));
  1131. /************************************************************************/
  1132. /* Add the prefix for this transport type. */
  1133. /************************************************************************/
  1134. /************************************************************************/
  1135. /* Add the separator followed by the actual address. */
  1136. /************************************************************************/
  1137. ::lstrcpyA(pszDstAddress, RNC_GCC_TRANSPORT_AND_SEPARATOR);
  1138. ::lstrcatA(pszDstAddress, pszNodeAddress);
  1139. DebugExitVOID(BuildAddressFromNodeDetails);
  1140. }
  1141.