Leaked source code of windows server 2003
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.

6623 lines
183 KiB

  1. #include "precomp.h"
  2. DEBUG_FILEZONE(ZONE_T120_GCCNC);
  3. /*
  4. * mcsuser.cpp
  5. *
  6. * Copyright (c) 1995 by DataBeam Corporation, Lexington, KY
  7. *
  8. * Abstract:
  9. * This is the implemntation file for the MCSUser class. It implements
  10. * functions responsible for encoding out bound indirect conference
  11. * join request and response PDUs, and also Send user ID Requests. All
  12. * these PDUs are encapsulated in user data field of MCSSendDataRequest.
  13. * Also this file implements functions that are responsible for decoding
  14. * incoming indications and confirm PDUs which are encapsulated in the
  15. * user data field of MCSSendDataIndication. Functions responsible for
  16. * joining different channels are also implemented in this module.
  17. *
  18. * SEE THE INTERFACE FILE FOR A MORE DETAILED DESCRIPTION OF THIS CLASS.
  19. *
  20. * Private Instance Variables
  21. * m_pMCSSap
  22. * This is the MCS User handle handed back from the MCS Attache User
  23. * Request.
  24. * m_nidMyself
  25. * The is the MCS User ID returned in the Attach User Confirm. This
  26. * is also refered to as the Node ID with in GCC.
  27. * m_nidTopProvider
  28. * This holds the MCS User ID (or Node ID) for the top Provider.
  29. * m_nidParent
  30. * This holds the MCS User ID (or Node ID) for this nodes parent node.
  31. * m_fEjectionPending
  32. * This flag indicates if an ejection of this node is pending.
  33. * m_eEjectReason
  34. * This variable holds the reason for ejection until the eject
  35. * indication can be delivered after all child nodes have disconnected.
  36. * m_pOwnerConf
  37. * Pointer to the object that will receive all the owner callbacks
  38. * from the user object (typically the conference object).
  39. * m_ChannelJoinedFlags
  40. * A structure of flags used to keep up with creation state machine.
  41. * Basically, it keeps up with which channels have been joined and
  42. * which ones have not.
  43. * m_ChildUidConnHdlList2
  44. * Keeps mapping of child Node IDs to child logical connection
  45. * handles.
  46. * m_OutgoingPDUQueue
  47. * This is a rogue wave list used to queue up all outgoing PDUs.
  48. * m_ConfJoinResponseList2
  49. * This rogue wave list holds information needed to send back in a join
  50. * response after the local node controller responds.
  51. * m_EjectedNodeAlarmList2
  52. * This list holds alarm objects for all the nodes that have been
  53. * ejected and are directly connected to this node. The alarm is
  54. * used to disconnect any misbehaving nodes that do not disconnect
  55. * after the EJECTED_NODE_TIMER_DURATION.
  56. * m_EjectedNodeList
  57. * This list keeps up with nodes that have been ejected but are NOT
  58. * directly connected to this node. We save these nodes so that
  59. * a correct reason for disconnecting (user ejected) can be issued
  60. * when the detch user indication comes in.
  61. *
  62. * Author:
  63. * blp
  64. */
  65. #include "mcsuser.h"
  66. #include "mcsdllif.h"
  67. #include "ogcccode.h"
  68. #include "conf.h"
  69. #include "translat.h"
  70. #include "gcontrol.h"
  71. // Static Channel and Token ID definitions used by the MCS user object.
  72. #define BROADCAST_CHANNEL_ID 1
  73. #define CONVENER_CHANNEL_ID 2
  74. #define CONDUCTOR_TOKEN_ID 1
  75. // Time given to allow an ejected node to disconnect before it is disconnected
  76. #define EJECTED_NODE_TIMER_DURATION 10000 // Duration in milliseconds
  77. extern MCSDLLInterface *g_pMCSIntf;
  78. /*
  79. * This is a global variable that has a pointer to the one GCC coder that
  80. * is instantiated by the GCC Controller. Most objects know in advance
  81. * whether they need to use the MCS or the GCC coder, so, they do not need
  82. * this pointer in their constructors.
  83. */
  84. extern CGCCCoder *g_GCCCoder;
  85. /*
  86. * MCSUser ()
  87. *
  88. * Public Function Description
  89. * This is the MCSUser object constructor. It is responsible for
  90. * initializing all the instance variables used by this class. The
  91. * constructor is responsible for establishing the user attachment to
  92. * the MCS domain defined by the conference ID. It also kicks off the
  93. * process of joining all the appropriate channels.
  94. */
  95. MCSUser::
  96. MCSUser(CConf *pConf,
  97. GCCNodeID nidTopProvider,
  98. GCCNodeID nidParent,
  99. PGCCError return_value)
  100. :
  101. CRefCount(MAKE_STAMP_ID('M','U','s','r')),
  102. m_ChildUidConnHdlList2(),
  103. m_EjectedNodeAlarmList2(),
  104. m_EjectedNodeList(),
  105. m_pConf(pConf),
  106. m_nidTopProvider(nidTopProvider),
  107. m_nidParent(nidParent),
  108. m_nidMyself(NULL),
  109. m_fEjectionPending(FALSE)
  110. {
  111. MCSError mcs_rc;
  112. GCCConfID nConfID = pConf->GetConfID();
  113. // No channels are joined initially
  114. m_ChannelJoinedFlags.user_channel_joined = FALSE;
  115. m_ChannelJoinedFlags.broadcast_channel_joined = FALSE;
  116. m_ChannelJoinedFlags.convener_channel_joined = FALSE;
  117. m_ChannelJoinedFlags.channel_join_error = FALSE;
  118. mcs_rc = g_pMCSIntf->AttachUserRequest(&nConfID, &m_pMCSSap, this);
  119. if (MCS_NO_ERROR != mcs_rc)
  120. {
  121. WARNING_OUT(("MCSUser::MCSUser: Failure in attach user req, "));
  122. *return_value = GCC_FAILURE_ATTACHING_TO_MCS;
  123. }
  124. else
  125. {
  126. *return_value = GCC_NO_ERROR;
  127. }
  128. }
  129. /*
  130. * ~MCSUser ()
  131. *
  132. * Public Function Description
  133. * This is the user destructor. It takes care of leaving channels
  134. * joined by the user object. Also it detaches the user attachment
  135. * with MCS by issuing a detach user request.
  136. */
  137. MCSUser::~MCSUser(void)
  138. {
  139. // Clean up the Ejected Node Alarm List
  140. PAlarm lpAlarm;
  141. while (NULL != (lpAlarm = m_EjectedNodeAlarmList2.Get()))
  142. {
  143. delete lpAlarm;
  144. }
  145. if(m_ChannelJoinedFlags.user_channel_joined)
  146. {
  147. g_pMCSIntf->ChannelLeaveRequest(m_nidMyself, m_pMCSSap);
  148. }
  149. if(m_ChannelJoinedFlags.broadcast_channel_joined)
  150. {
  151. g_pMCSIntf->ChannelLeaveRequest(BROADCAST_CHANNEL_ID, m_pMCSSap);
  152. }
  153. if(m_ChannelJoinedFlags.convener_channel_joined)
  154. {
  155. g_pMCSIntf->ChannelLeaveRequest(CONVENER_CHANNEL_ID, m_pMCSSap);
  156. }
  157. // Empty the queue of all PDUs
  158. SEND_DATA_REQ_INFO *pReqInfo;
  159. m_OutgoingPDUQueue.Reset();
  160. while (NULL != (pReqInfo = m_OutgoingPDUQueue.Iterate()))
  161. {
  162. pReqInfo->packet->Unlock();
  163. delete pReqInfo;
  164. }
  165. g_pMCSIntf->DetachUserRequest(m_pMCSSap, this);
  166. }
  167. /*
  168. * UINT ProcessAttachUserConfirm ()
  169. *
  170. * Private Function Description
  171. * This function is called when the user object gets an attach user
  172. * confirm from MCS in response to an attach user request made by the
  173. * user object in it's constructor. The function checks the result
  174. * indicated in the confirm. If the result is a successful attachment, then
  175. * different channels depending upon the type of the provider, are joined.
  176. * Also this function reports failures in attach user (as indicated by
  177. * result in attach user confirm) and channel joins, to the conference
  178. * through an owner callback.
  179. *
  180. * Formal Parameters:
  181. * result - (i) Result of the attach user request.
  182. * user_id - (i) This nodes user or Node ID if successful result.
  183. *
  184. * Return Value
  185. * MCS_NO_ERROR - No error is always returned.
  186. *
  187. * Side Effects
  188. * None.
  189. *
  190. * Caveats
  191. * None.
  192. */
  193. UINT MCSUser::ProcessAttachUserConfirm(Result result, UserID user_id)
  194. {
  195. UINT rc;
  196. if (result == RESULT_SUCCESSFUL)
  197. {
  198. m_nidMyself = user_id;
  199. /*
  200. ** After the attach confirm is received we go ahead and join the
  201. ** appropriate channel based on the conf node type. If this
  202. ** node is the yop provider we also set up the top provider user id,
  203. ** otherwise this gets set up in the constructor.
  204. */
  205. switch (m_pConf->GetConfNodeType())
  206. {
  207. case TOP_PROVIDER_NODE:
  208. m_nidTopProvider = m_nidMyself;
  209. rc = JoinUserAndBroadCastChannels();
  210. break;
  211. case JOINED_CONVENER_NODE:
  212. case CONVENER_NODE:
  213. rc = JoinUserAndBroadCastChannels();
  214. if(rc == MCS_NO_ERROR)
  215. {
  216. rc = JoinConvenerChannel();
  217. }
  218. break;
  219. case TOP_PROVIDER_AND_CONVENER_NODE:
  220. m_nidTopProvider = m_nidMyself;
  221. rc = JoinUserAndBroadCastChannels();
  222. if(rc == MCS_NO_ERROR)
  223. {
  224. rc = JoinConvenerChannel();
  225. }
  226. break;
  227. case JOINED_NODE:
  228. case INVITED_NODE:
  229. rc = JoinUserAndBroadCastChannels();
  230. break;
  231. default:
  232. ERROR_OUT(("User::ProcessAttachUserConfirm: Bad Node Type, %u", (UINT) m_pConf->GetConfNodeType()));
  233. break;
  234. }
  235. if (rc != MCS_NO_ERROR)
  236. {
  237. /*
  238. * ChannelJoinRequestFailed at some level in MCS
  239. * So this message tells the conferenceabout this
  240. * failure. Conference will delete the user object
  241. * as a result of this
  242. */
  243. m_pConf->ProcessUserCreateConfirm(USER_CHANNEL_JOIN_FAILURE, m_nidMyself);
  244. }
  245. }
  246. else
  247. {
  248. /*
  249. * Attach user request failed as indicated by the result field in the
  250. * confirm message, because of any of the following causes:
  251. * congested, domain disconnected, no such domain, too many channels,
  252. * too many users, unspecified failure. In this case the user object
  253. * just sends the conference a GCC_USER_ATTACH_FAILURE ( to be defined
  254. * in command target.h) , which causes
  255. * the conference object to delete the user attachment.
  256. * UserCreateConfirm message is not corresponding exectly to a single
  257. * primitive.
  258. */
  259. WARNING_OUT(("MCSUser::ProcessAttachUserConfirm: ATTACH FAILED"));
  260. m_pConf->ProcessUserCreateConfirm(USER_ATTACH_FAILURE, m_nidMyself);
  261. }
  262. return (MCS_NO_ERROR);
  263. }
  264. /*
  265. * MCSError JoinUserAndBroadCastChannels()
  266. *
  267. * Private Function Description
  268. * This function is called by user object when it gets a successful
  269. * attach user confrim, to join user id and broadcast channels.
  270. * If the channel join requests fail, it returns the appropriate MCS
  271. * Error.
  272. *
  273. * Formal Parameters:
  274. * None.
  275. *
  276. * Return Value
  277. * See return values for mcs channel jon request.
  278. *
  279. * Side Effects
  280. * None.
  281. *
  282. * Caveats
  283. * None.
  284. */
  285. MCSError MCSUser::JoinUserAndBroadCastChannels()
  286. {
  287. MCSError rc;
  288. rc = g_pMCSIntf->ChannelJoinRequest(m_nidMyself, m_pMCSSap);
  289. if(rc == MCS_NO_ERROR)
  290. {
  291. rc = g_pMCSIntf->ChannelJoinRequest(BROADCAST_CHANNEL_ID, m_pMCSSap);
  292. }
  293. return (rc);
  294. }
  295. /*
  296. * MCSError JoinUserAndBroadCastChannels()
  297. *
  298. * Private Function Description
  299. * This function is called by user object of a convener gcc provider
  300. * when it gets a successful attach user confrim, to join convener
  301. * channel. If the channel join requests fail, it returns the appropriate
  302. * MCS Error.
  303. *
  304. * Formal Parameters:
  305. * None.
  306. *
  307. * Return Value
  308. * See return values for mcs channel jon request.
  309. *
  310. * Side Effects
  311. * None.
  312. *
  313. * Caveats
  314. * None.
  315. */
  316. MCSError MCSUser::JoinConvenerChannel()
  317. {
  318. return g_pMCSIntf->ChannelJoinRequest(CONVENER_CHANNEL_ID, m_pMCSSap);
  319. }
  320. /*
  321. * UINT ProcessChannelJoinConfirm()
  322. *
  323. * Private Function Description
  324. * This function is called when the user object gets an channel join
  325. * confirm from MCS in response to channel join requests made by the
  326. * user object. If a channel is joined successfully as indicated by
  327. * the result in the confirm, a channel joined flag corresponding to
  328. * that channel id is set. This flag indicates as to which channels a
  329. * user object is joined at any given time. Also after setting this
  330. * flag the functions checks to see if all tke required channels based
  331. * on the type of gcc provider, are joined. If all required channels are
  332. * joined the conference object is informaed about it via an owner call-
  333. * back (USER_CREATE_CONFIRM).
  334. *
  335. * Formal Parameters:
  336. * result - (i) Result of the channel join request.
  337. * channel_id - (i) Channel ID that this confirm pertains to.
  338. *
  339. * Return Value
  340. * MCS_NO_ERROR is always returned.
  341. *
  342. * Side Effects
  343. * None.
  344. *
  345. * Caveats
  346. * None.
  347. */
  348. UINT MCSUser::ProcessChannelJoinConfirm(Result result, ChannelID channel_id)
  349. {
  350. if (m_ChannelJoinedFlags.channel_join_error == FALSE)
  351. {
  352. if (result == RESULT_SUCCESSFUL)
  353. {
  354. if( channel_id == m_nidMyself)
  355. {
  356. m_ChannelJoinedFlags.user_channel_joined = TRUE;
  357. }
  358. else
  359. {
  360. switch (channel_id)
  361. {
  362. case CONVENER_CHANNEL_ID:
  363. m_ChannelJoinedFlags.convener_channel_joined = TRUE;
  364. break;
  365. case BROADCAST_CHANNEL_ID:
  366. m_ChannelJoinedFlags.broadcast_channel_joined = TRUE;
  367. break;
  368. }
  369. }
  370. /*
  371. ** If all the channels are joined we inform the owner object that
  372. ** the user object was successfully created.
  373. */
  374. if (AreAllChannelsJoined())
  375. {
  376. m_pConf->ProcessUserCreateConfirm(USER_RESULT_SUCCESSFUL, m_nidMyself);
  377. }
  378. }
  379. else
  380. {
  381. WARNING_OUT(("MCSUser::ProcessChannelJoinConfirm: Error joining channel, result=%u", (UINT) result));
  382. m_ChannelJoinedFlags.channel_join_error = TRUE ;
  383. m_pConf->ProcessUserCreateConfirm(USER_CHANNEL_JOIN_FAILURE, m_nidMyself);
  384. }
  385. }
  386. return (MCS_NO_ERROR);
  387. }
  388. /*
  389. * BOOL AreAllChannelsJoined()
  390. *
  391. * Public Function Description
  392. * This function is called to check if all tke required channels based
  393. * on the type of gcc provider, are joined. It returns true if all
  394. * required channels are joined and false otherwise. This function uses
  395. * different channel joined flags to check which channels the given user
  396. * object is joined to.
  397. *
  398. * Formal Parameters:
  399. * None.
  400. *
  401. * Return Value
  402. * TRUE - If all channels are joined.
  403. * FALSE - If all the channels are not joined.
  404. *
  405. * Side Effects
  406. * None.
  407. *
  408. * Caveats
  409. * None.
  410. */
  411. BOOL MCSUser::AreAllChannelsJoined(void)
  412. {
  413. BOOL rc = FALSE;
  414. switch (m_pConf->GetConfNodeType())
  415. {
  416. case TOP_PROVIDER_NODE:
  417. if ((m_ChannelJoinedFlags.user_channel_joined) &&
  418. (m_ChannelJoinedFlags.broadcast_channel_joined))
  419. {
  420. rc = TRUE;
  421. }
  422. break;
  423. case JOINED_CONVENER_NODE:
  424. case CONVENER_NODE:
  425. if ((m_ChannelJoinedFlags.convener_channel_joined) &&
  426. (m_ChannelJoinedFlags.user_channel_joined) &&
  427. (m_ChannelJoinedFlags.broadcast_channel_joined))
  428. {
  429. rc = TRUE;
  430. }
  431. break;
  432. case TOP_PROVIDER_AND_CONVENER_NODE:
  433. if ((m_ChannelJoinedFlags.convener_channel_joined) &&
  434. (m_ChannelJoinedFlags.user_channel_joined) &&
  435. (m_ChannelJoinedFlags.broadcast_channel_joined))
  436. {
  437. rc = TRUE;
  438. }
  439. break;
  440. case JOINED_NODE:
  441. case INVITED_NODE:
  442. if( (m_ChannelJoinedFlags.user_channel_joined) &&
  443. (m_ChannelJoinedFlags.broadcast_channel_joined))
  444. {
  445. rc = TRUE;
  446. }
  447. break;
  448. }
  449. return rc;
  450. }
  451. /*
  452. * void SendUserIDRequest()
  453. *
  454. * Public Function Description:
  455. * This request originates from the conference object. Conference object
  456. * sends the sequence number obtained in the conference create confirm
  457. * or conference join confirm to the parent GCC provider on the parent
  458. * gcc provider's UserId channel. The pdu is encoded here and is
  459. * queued to be sent during the next heartbeat.
  460. */
  461. void MCSUser::SendUserIDRequest(TagNumber tag_number)
  462. {
  463. PPacket packet;
  464. GCCPDU gcc_pdu;
  465. PacketError packet_error;
  466. /*
  467. ** Fill in the UserIDIndication pdu structure to be passed in the
  468. ** constructor of the packet class.
  469. */
  470. gcc_pdu.choice = INDICATION_CHOSEN;
  471. gcc_pdu.u.indication.choice = USER_ID_INDICATION_CHOSEN;
  472. gcc_pdu.u.indication.u.user_id_indication.tag = tag_number;
  473. /*
  474. ** Create a packet object
  475. */
  476. DBG_SAVE_FILE_LINE
  477. packet = new Packet((PPacketCoder) g_GCCCoder,
  478. PACKED_ENCODING_RULES,
  479. &gcc_pdu,
  480. GCC_PDU, // pdu_type
  481. TRUE,
  482. &packet_error);
  483. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  484. {
  485. AddToMCSMessageQueue(packet, m_nidParent, TOP_PRIORITY, FALSE);
  486. }
  487. else
  488. {
  489. ResourceFailureHandler();
  490. }
  491. }
  492. /*
  493. * GCCError ConferenceJoinRequest()
  494. *
  495. * Public Function Description:
  496. * This call is made by the conference object of the intermediate node
  497. * to forward the conference join request over to the top provider. This
  498. * function encodes the conference join request pdu and queues it to be
  499. * sent in the next heartbeat.
  500. *
  501. * Caveats
  502. * The connection handle is used here for a TAG and should be passed back
  503. * to the owner object when the join response comes in.
  504. */
  505. GCCError MCSUser::ConferenceJoinRequest(
  506. CPassword *convener_password,
  507. CPassword *password_challenge,
  508. LPWSTR pwszCallerID,
  509. CUserDataListContainer *user_data_list,
  510. ConnectionHandle connection_handle)
  511. {
  512. GCCError rc = GCC_NO_ERROR;
  513. PPacket packet;
  514. GCCPDU gcc_pdu;
  515. PacketError packet_error;
  516. // Encode the PDU that will be forwarded to the top provider.
  517. gcc_pdu.choice = REQUEST_CHOSEN;
  518. gcc_pdu.u.request.choice = CONFERENCE_JOIN_REQUEST_CHOSEN;
  519. gcc_pdu.u.request.u.conference_join_request.tag = (TagNumber)connection_handle;
  520. gcc_pdu.u.request.u.conference_join_request.bit_mask = TAG_PRESENT;
  521. // Insert the convener password into the ASN.1 structure
  522. if (convener_password != NULL)
  523. {
  524. rc = convener_password->GetPasswordSelectorPDU(
  525. &gcc_pdu.u.request.u.conference_join_request.cjrq_convener_password);
  526. if (rc == GCC_NO_ERROR)
  527. {
  528. gcc_pdu.u.request.u.conference_join_request.bit_mask |= CJRQ_CONVENER_PASSWORD_PRESENT;
  529. }
  530. }
  531. // Insert the password challenge into the ASN.1 structure
  532. if (( password_challenge != NULL ) && (rc == GCC_NO_ERROR))
  533. {
  534. rc = password_challenge->GetPasswordChallengeResponsePDU (
  535. &gcc_pdu.u.request.u.conference_join_request.
  536. cjrq_password);
  537. if (rc == GCC_NO_ERROR)
  538. {
  539. gcc_pdu.u.request.u.conference_join_request.bit_mask |=
  540. CJRQ_PASSWORD_PRESENT;
  541. }
  542. }
  543. // Insert the caller identifier into the ASN.1 structure
  544. UINT cchCallerID = ::My_strlenW(pwszCallerID);
  545. if ((cchCallerID != 0 ) && (rc == GCC_NO_ERROR))
  546. {
  547. gcc_pdu.u.request.u.conference_join_request.cjrq_caller_id.value = pwszCallerID;
  548. gcc_pdu.u.request.u.conference_join_request.cjrq_caller_id.length = cchCallerID;
  549. gcc_pdu.u.request.u.conference_join_request.bit_mask |= CJRQ_CALLER_ID_PRESENT;
  550. }
  551. // Insert the user data into the ASN.1 structure
  552. if (( user_data_list != NULL ) && (rc == GCC_NO_ERROR))
  553. {
  554. rc = user_data_list->GetUserDataPDU (
  555. &gcc_pdu.u.request.u.conference_join_request.cjrq_user_data);
  556. if (rc == GCC_NO_ERROR)
  557. {
  558. gcc_pdu.u.request.u.conference_join_request.bit_mask |= CJRQ_USER_DATA_PRESENT;
  559. }
  560. }
  561. if (rc == GCC_NO_ERROR)
  562. {
  563. DBG_SAVE_FILE_LINE
  564. packet = new Packet((PPacketCoder) g_GCCCoder,
  565. PACKED_ENCODING_RULES,
  566. (LPVOID)&gcc_pdu,
  567. GCC_PDU,
  568. TRUE,
  569. &packet_error);
  570. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  571. {
  572. AddToMCSMessageQueue(packet, m_nidTopProvider, TOP_PRIORITY, FALSE);
  573. }
  574. else
  575. {
  576. rc = GCC_ALLOCATION_FAILURE;
  577. delete packet;
  578. }
  579. }
  580. // Cleanup after any errors
  581. if (rc == GCC_ALLOCATION_FAILURE)
  582. {
  583. ResourceFailureHandler();
  584. }
  585. return rc;
  586. }
  587. /*
  588. * GCCError SendConferenceLockRequest()
  589. *
  590. * Public Function Description:
  591. * This function is invoked by the owner object to send a conference lock
  592. * request PDU to the top provider.
  593. */
  594. GCCError MCSUser::SendConferenceLockRequest()
  595. {
  596. GCCError rc = GCC_NO_ERROR;
  597. PPacket packet;
  598. GCCPDU gcc_pdu;
  599. PacketError packet_error;
  600. gcc_pdu.choice = REQUEST_CHOSEN;
  601. gcc_pdu.u.request.choice = CONFERENCE_LOCK_REQUEST_CHOSEN;
  602. DBG_SAVE_FILE_LINE
  603. packet = new Packet((PPacketCoder) g_GCCCoder,
  604. PACKED_ENCODING_RULES,
  605. (LPVOID)&gcc_pdu,
  606. GCC_PDU,
  607. TRUE,
  608. &packet_error);
  609. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  610. {
  611. AddToMCSMessageQueue(packet, m_nidTopProvider, HIGH_PRIORITY, FALSE);
  612. }
  613. else
  614. {
  615. ResourceFailureHandler();
  616. rc = GCC_ALLOCATION_FAILURE;
  617. delete packet;
  618. }
  619. return rc;
  620. }
  621. /*
  622. * GCCError SendConferenceLockResponse()
  623. *
  624. * Public Function Description:
  625. * This function is invoked by the owner object to send a conference lock
  626. * response PDU to the requesting node.
  627. */
  628. GCCError MCSUser::SendConferenceLockResponse (
  629. UserID source_node,
  630. GCCResult result)
  631. {
  632. GCCError rc = GCC_NO_ERROR;
  633. PPacket packet;
  634. GCCPDU gcc_pdu;
  635. PacketError packet_error;
  636. gcc_pdu.choice = RESPONSE_CHOSEN;
  637. gcc_pdu.u.response.choice = CONFERENCE_LOCK_RESPONSE_CHOSEN;
  638. gcc_pdu.u.response.u.conference_lock_response.result =
  639. ::TranslateGCCResultToLockResult(result);
  640. DBG_SAVE_FILE_LINE
  641. packet = new Packet((PPacketCoder) g_GCCCoder,
  642. PACKED_ENCODING_RULES,
  643. (LPVOID)&gcc_pdu,
  644. GCC_PDU,
  645. TRUE,
  646. &packet_error);
  647. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  648. {
  649. AddToMCSMessageQueue(packet, source_node, HIGH_PRIORITY, FALSE);
  650. }
  651. else
  652. {
  653. ResourceFailureHandler();
  654. rc = GCC_ALLOCATION_FAILURE;
  655. delete packet;
  656. }
  657. return rc;
  658. }
  659. /*
  660. * GCCError SendConferenceUnlockRequest()
  661. *
  662. * Public Function Description:
  663. * This function is invoked by the owner object to send a conference unlock
  664. * request PDU to the top provider.
  665. */
  666. GCCError MCSUser::SendConferenceUnlockRequest ()
  667. {
  668. GCCError rc = GCC_NO_ERROR;
  669. PPacket packet;
  670. GCCPDU gcc_pdu;
  671. PacketError packet_error;
  672. gcc_pdu.choice = REQUEST_CHOSEN;
  673. gcc_pdu.u.request.choice = CONFERENCE_UNLOCK_REQUEST_CHOSEN;
  674. DBG_SAVE_FILE_LINE
  675. packet = new Packet((PPacketCoder) g_GCCCoder,
  676. PACKED_ENCODING_RULES,
  677. (LPVOID)&gcc_pdu,
  678. GCC_PDU,
  679. TRUE,
  680. &packet_error);
  681. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  682. {
  683. AddToMCSMessageQueue(packet, m_nidTopProvider, HIGH_PRIORITY, FALSE);
  684. }
  685. else
  686. {
  687. ResourceFailureHandler();
  688. rc = GCC_ALLOCATION_FAILURE;
  689. delete packet;
  690. }
  691. return rc;
  692. }
  693. /*
  694. * GCCError SendConferenceUnlockResponse()
  695. *
  696. * Public Function Description:
  697. * This function is invoked by the owner object to send a conference unlock
  698. * response PDU to the requesting node.
  699. */
  700. GCCError MCSUser::SendConferenceUnlockResponse (
  701. UserID source_node,
  702. GCCResult result)
  703. {
  704. GCCError rc = GCC_NO_ERROR;
  705. PPacket packet;
  706. GCCPDU gcc_pdu;
  707. PacketError packet_error;
  708. gcc_pdu.choice = RESPONSE_CHOSEN;
  709. gcc_pdu.u.response.choice = CONFERENCE_UNLOCK_RESPONSE_CHOSEN;
  710. gcc_pdu.u.response.u.conference_unlock_response.result =
  711. ::TranslateGCCResultToUnlockResult(result);
  712. DBG_SAVE_FILE_LINE
  713. packet = new Packet((PPacketCoder) g_GCCCoder,
  714. PACKED_ENCODING_RULES,
  715. (LPVOID)&gcc_pdu,
  716. GCC_PDU,
  717. TRUE,
  718. &packet_error);
  719. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  720. {
  721. AddToMCSMessageQueue(packet, source_node, HIGH_PRIORITY, FALSE);
  722. }
  723. else
  724. {
  725. ResourceFailureHandler();
  726. rc = GCC_ALLOCATION_FAILURE;
  727. delete packet;
  728. }
  729. return rc;
  730. }
  731. /*
  732. * GCCError SendConferenceLockIndication()
  733. *
  734. * Public Function Description:
  735. * This function is invoked by the owner object of the top provider
  736. * to send a conference lock indication PDU to one or all other nodes
  737. * that are registered in the conference.
  738. */
  739. GCCError MCSUser::SendConferenceLockIndication(
  740. BOOL uniform_send,
  741. UserID source_node)
  742. {
  743. GCCError rc = GCC_NO_ERROR;
  744. PPacket packet;
  745. GCCPDU gcc_pdu;
  746. PacketError packet_error;
  747. gcc_pdu.choice = INDICATION_CHOSEN;
  748. gcc_pdu.u.indication.choice = CONFERENCE_LOCK_INDICATION_CHOSEN;
  749. DBG_SAVE_FILE_LINE
  750. packet = new Packet((PPacketCoder) g_GCCCoder,
  751. PACKED_ENCODING_RULES,
  752. (LPVOID)&gcc_pdu,
  753. GCC_PDU,
  754. TRUE,
  755. &packet_error);
  756. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  757. {
  758. AddToMCSMessageQueue(
  759. packet,
  760. uniform_send ? BROADCAST_CHANNEL_ID : source_node,
  761. HIGH_PRIORITY,
  762. uniform_send);
  763. }
  764. else
  765. {
  766. ResourceFailureHandler();
  767. rc = GCC_ALLOCATION_FAILURE;
  768. delete packet;
  769. }
  770. return rc;
  771. }
  772. /*
  773. * GCCError SendConferenceUnlockIndication()
  774. *
  775. * Public Function Description:
  776. * This function is invoked by the owner object of the top provider
  777. * to send a conference unlock indication PDU to one or all other nodes
  778. * that are registered in the conference.
  779. */
  780. GCCError MCSUser::SendConferenceUnlockIndication(
  781. BOOL uniform_send,
  782. UserID source_node)
  783. {
  784. GCCError rc = GCC_NO_ERROR;
  785. PPacket packet;
  786. GCCPDU gcc_pdu;
  787. PacketError packet_error;
  788. gcc_pdu.choice = INDICATION_CHOSEN;
  789. gcc_pdu.u.indication.choice = CONFERENCE_UNLOCK_INDICATION_CHOSEN;
  790. DBG_SAVE_FILE_LINE
  791. packet = new Packet((PPacketCoder) g_GCCCoder,
  792. PACKED_ENCODING_RULES,
  793. (LPVOID)&gcc_pdu,
  794. GCC_PDU,
  795. TRUE,
  796. &packet_error);
  797. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  798. {
  799. AddToMCSMessageQueue(
  800. packet,
  801. uniform_send ? BROADCAST_CHANNEL_ID : source_node,
  802. HIGH_PRIORITY,
  803. uniform_send);
  804. }
  805. else
  806. {
  807. ResourceFailureHandler();
  808. rc = GCC_ALLOCATION_FAILURE;
  809. delete packet;
  810. }
  811. return rc;
  812. }
  813. /******************************* Registry Calls ******************************/
  814. /*
  815. * void RegistryRegisterChannelRequest()
  816. *
  817. * Public Function Description:
  818. * This routine is used when an APE wishes to register a channel in
  819. * the application registry.
  820. */
  821. void MCSUser::RegistryRegisterChannelRequest(
  822. CRegKeyContainer *registry_key_data,
  823. ChannelID channel_id,
  824. EntityID entity_id)
  825. {
  826. GCCError error_value;
  827. PPacket packet;
  828. GCCPDU gcc_pdu;
  829. PacketError packet_error;
  830. // Encode the PDU that will be forwarded to the top provider.
  831. gcc_pdu.choice = REQUEST_CHOSEN;
  832. gcc_pdu.u.request.choice = REGISTRY_REGISTER_CHANNEL_REQUEST_CHOSEN;
  833. error_value = registry_key_data->GetRegistryKeyDataPDU(
  834. &gcc_pdu.u.request.u.
  835. registry_register_channel_request.key);
  836. if (error_value == GCC_NO_ERROR)
  837. {
  838. gcc_pdu.u.request.u.registry_register_channel_request.channel_id =
  839. channel_id;
  840. gcc_pdu.u.request.u.registry_register_channel_request.entity_id =
  841. entity_id;
  842. DBG_SAVE_FILE_LINE
  843. packet = new Packet((PPacketCoder) g_GCCCoder,
  844. PACKED_ENCODING_RULES,
  845. (LPVOID)&gcc_pdu,
  846. GCC_PDU,
  847. TRUE,
  848. &packet_error);
  849. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  850. {
  851. AddToMCSMessageQueue(packet, m_nidTopProvider, HIGH_PRIORITY, FALSE);
  852. }
  853. else
  854. {
  855. ERROR_OUT(("MCSUser::RegistryRegisterChannelRequest: Error creating packet"));
  856. error_value = GCC_ALLOCATION_FAILURE;
  857. delete packet;
  858. }
  859. registry_key_data->FreeRegistryKeyDataPDU();
  860. }
  861. if (error_value == GCC_ALLOCATION_FAILURE)
  862. {
  863. ResourceFailureHandler();
  864. }
  865. }
  866. /*
  867. * MCSUser::RegistryAssignTokenRequest()
  868. *
  869. * Public Function Description:
  870. * This routine is used when an APE wishes to register a token in
  871. * the application registry. Note that there is no token ID included in
  872. * this request. The token ID is allocated at the top provider.
  873. */
  874. void MCSUser::RegistryAssignTokenRequest (
  875. CRegKeyContainer *registry_key_data,
  876. EntityID entity_id)
  877. {
  878. GCCError error_value;
  879. PPacket packet;
  880. GCCPDU gcc_pdu;
  881. PacketError packet_error;
  882. // Encode the PDU that will be forwarded to the top provider.
  883. gcc_pdu.choice = REQUEST_CHOSEN;
  884. gcc_pdu.u.request.choice = REGISTRY_ASSIGN_TOKEN_REQUEST_CHOSEN;
  885. error_value = registry_key_data->GetRegistryKeyDataPDU(
  886. &gcc_pdu.u.request.u.
  887. registry_assign_token_request.registry_key);
  888. if (error_value == GCC_NO_ERROR)
  889. {
  890. gcc_pdu.u.request.u.registry_assign_token_request.entity_id = entity_id;
  891. DBG_SAVE_FILE_LINE
  892. packet = new Packet((PPacketCoder) g_GCCCoder,
  893. PACKED_ENCODING_RULES,
  894. (LPVOID)&gcc_pdu,
  895. GCC_PDU,
  896. TRUE,
  897. &packet_error);
  898. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  899. {
  900. AddToMCSMessageQueue(packet, m_nidTopProvider, HIGH_PRIORITY, FALSE);
  901. }
  902. else
  903. {
  904. error_value = GCC_ALLOCATION_FAILURE;
  905. delete packet;
  906. }
  907. registry_key_data->FreeRegistryKeyDataPDU();
  908. }
  909. if (error_value == GCC_ALLOCATION_FAILURE)
  910. {
  911. ResourceFailureHandler();
  912. }
  913. }
  914. /*
  915. * void RegistrySetParameterRequest()
  916. *
  917. * Public Function Description:
  918. * This routine is used when an APE wishes to register a parameter in
  919. * the application registry. Note that parameter to be registered is
  920. * included in this request.
  921. */
  922. void MCSUser::RegistrySetParameterRequest (
  923. CRegKeyContainer *registry_key_data,
  924. LPOSTR parameter_value,
  925. GCCModificationRights modification_rights,
  926. EntityID entity_id)
  927. {
  928. GCCError error_value;
  929. PPacket packet;
  930. GCCPDU gcc_pdu;
  931. PacketError packet_error;
  932. // Encode the PDU that will be forwarded to the top provider.
  933. gcc_pdu.choice = REQUEST_CHOSEN;
  934. gcc_pdu.u.request.choice = REGISTRY_SET_PARAMETER_REQUEST_CHOSEN;
  935. gcc_pdu.u.request.u.registry_set_parameter_request.bit_mask = 0;
  936. error_value = registry_key_data->GetRegistryKeyDataPDU(
  937. &gcc_pdu.u.request.u.
  938. registry_set_parameter_request.key);
  939. if (error_value == GCC_NO_ERROR)
  940. {
  941. if (parameter_value != NULL)
  942. {
  943. gcc_pdu.u.request.u.registry_set_parameter_request.
  944. registry_set_parameter.length =
  945. parameter_value->length;
  946. memcpy (gcc_pdu.u.request.u.registry_set_parameter_request.
  947. registry_set_parameter.value,
  948. parameter_value->value,
  949. parameter_value->length);
  950. }
  951. else
  952. {
  953. gcc_pdu.u.request.u.registry_set_parameter_request.
  954. registry_set_parameter.length = 0;
  955. }
  956. gcc_pdu.u.request.u.registry_set_parameter_request.entity_id =
  957. entity_id;
  958. // Set up the modification rights here if it exists
  959. if (modification_rights != GCC_NO_MODIFICATION_RIGHTS_SPECIFIED)
  960. {
  961. gcc_pdu.u.request.u.registry_set_parameter_request.bit_mask |=
  962. PARAMETER_MODIFY_RIGHTS_PRESENT;
  963. gcc_pdu.u.request.u.registry_set_parameter_request.
  964. parameter_modify_rights =
  965. (RegistryModificationRights)modification_rights;
  966. }
  967. DBG_SAVE_FILE_LINE
  968. packet = new Packet((PPacketCoder) g_GCCCoder,
  969. PACKED_ENCODING_RULES,
  970. (LPVOID)&gcc_pdu,
  971. GCC_PDU,
  972. TRUE,
  973. &packet_error);
  974. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  975. {
  976. AddToMCSMessageQueue(packet, m_nidTopProvider, HIGH_PRIORITY, FALSE);
  977. }
  978. else
  979. {
  980. error_value = GCC_ALLOCATION_FAILURE;
  981. delete packet;
  982. }
  983. registry_key_data->FreeRegistryKeyDataPDU();
  984. }
  985. if (error_value == GCC_ALLOCATION_FAILURE)
  986. {
  987. ResourceFailureHandler();
  988. }
  989. }
  990. /*
  991. * void RegistryRetrieveEntryRequest()
  992. *
  993. * Public Function Description:
  994. * This routine is used when an APE wishes to retrieve an registry item
  995. * from the registry.
  996. */
  997. void MCSUser::RegistryRetrieveEntryRequest (
  998. CRegKeyContainer *registry_key_data,
  999. EntityID entity_id)
  1000. {
  1001. GCCError error_value;
  1002. PPacket packet;
  1003. GCCPDU gcc_pdu;
  1004. PacketError packet_error;
  1005. // Encode the PDU that will be forwarded to the top provider.
  1006. gcc_pdu.choice = REQUEST_CHOSEN;
  1007. gcc_pdu.u.request.choice = REGISTRY_RETRIEVE_ENTRY_REQUEST_CHOSEN;
  1008. error_value = registry_key_data->GetRegistryKeyDataPDU(
  1009. &gcc_pdu.u.request.u.
  1010. registry_retrieve_entry_request.key);
  1011. if (error_value == GCC_NO_ERROR)
  1012. {
  1013. gcc_pdu.u.request.u.registry_retrieve_entry_request.entity_id =
  1014. entity_id;
  1015. DBG_SAVE_FILE_LINE
  1016. packet = new Packet((PPacketCoder) g_GCCCoder,
  1017. PACKED_ENCODING_RULES,
  1018. (LPVOID)&gcc_pdu,
  1019. GCC_PDU,
  1020. TRUE,
  1021. &packet_error);
  1022. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  1023. {
  1024. AddToMCSMessageQueue(packet, m_nidTopProvider, HIGH_PRIORITY, FALSE);
  1025. }
  1026. else
  1027. {
  1028. error_value = GCC_ALLOCATION_FAILURE;
  1029. delete packet;
  1030. }
  1031. registry_key_data->FreeRegistryKeyDataPDU();
  1032. }
  1033. else
  1034. error_value = GCC_ALLOCATION_FAILURE;
  1035. if (error_value == GCC_ALLOCATION_FAILURE)
  1036. {
  1037. ResourceFailureHandler();
  1038. }
  1039. }
  1040. /*
  1041. * void RegistryDeleteEntryRequest()
  1042. *
  1043. * Public Function Description:
  1044. * This routine is used when an APE wishes to delete a registry item
  1045. * from the registry.
  1046. */
  1047. void MCSUser::RegistryDeleteEntryRequest (
  1048. CRegKeyContainer *registry_key_data,
  1049. EntityID entity_id)
  1050. {
  1051. GCCError error_value;
  1052. PPacket packet;
  1053. GCCPDU gcc_pdu;
  1054. PacketError packet_error;
  1055. // Encode the PDU that will be forwarded to the top provider.
  1056. gcc_pdu.choice = REQUEST_CHOSEN;
  1057. gcc_pdu.u.request.choice = REGISTRY_DELETE_ENTRY_REQUEST_CHOSEN;
  1058. error_value = registry_key_data->GetRegistryKeyDataPDU(
  1059. &gcc_pdu.u.request.u.
  1060. registry_delete_entry_request.key);
  1061. if (error_value == GCC_NO_ERROR)
  1062. {
  1063. gcc_pdu.u.request.u.registry_delete_entry_request.entity_id = entity_id;
  1064. DBG_SAVE_FILE_LINE
  1065. packet = new Packet((PPacketCoder) g_GCCCoder,
  1066. PACKED_ENCODING_RULES,
  1067. (LPVOID)&gcc_pdu,
  1068. GCC_PDU,
  1069. TRUE,
  1070. &packet_error);
  1071. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  1072. {
  1073. AddToMCSMessageQueue(packet, m_nidTopProvider, HIGH_PRIORITY, FALSE);
  1074. }
  1075. else
  1076. {
  1077. error_value = GCC_ALLOCATION_FAILURE;
  1078. delete packet;
  1079. }
  1080. registry_key_data->FreeRegistryKeyDataPDU();
  1081. }
  1082. if (error_value == GCC_ALLOCATION_FAILURE)
  1083. {
  1084. ResourceFailureHandler();
  1085. }
  1086. }
  1087. /*
  1088. * void RegistryMonitorRequest()
  1089. *
  1090. * Public Function Description:
  1091. * This routine is used when an APE wishes to monitor a registry item
  1092. * in the registry.
  1093. */
  1094. void MCSUser::RegistryMonitorRequest (
  1095. CRegKeyContainer *registry_key_data,
  1096. EntityID entity_id)
  1097. {
  1098. GCCError error_value;
  1099. PPacket packet;
  1100. GCCPDU gcc_pdu;
  1101. PacketError packet_error;
  1102. // Encode the PDU that will be forwarded to the top provider.
  1103. gcc_pdu.choice = REQUEST_CHOSEN;
  1104. gcc_pdu.u.request.choice = REGISTRY_MONITOR_ENTRY_REQUEST_CHOSEN;
  1105. error_value = registry_key_data->GetRegistryKeyDataPDU(
  1106. &gcc_pdu.u.request.u.
  1107. registry_monitor_entry_request.key);
  1108. if (error_value == GCC_NO_ERROR)
  1109. {
  1110. gcc_pdu.u.request.u.registry_monitor_entry_request.entity_id= entity_id;
  1111. DBG_SAVE_FILE_LINE
  1112. packet = new Packet((PPacketCoder) g_GCCCoder,
  1113. PACKED_ENCODING_RULES,
  1114. (LPVOID)&gcc_pdu,
  1115. GCC_PDU,
  1116. TRUE,
  1117. &packet_error);
  1118. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  1119. {
  1120. AddToMCSMessageQueue(packet, m_nidTopProvider, HIGH_PRIORITY, FALSE);
  1121. }
  1122. else
  1123. {
  1124. error_value = GCC_ALLOCATION_FAILURE;
  1125. delete packet;
  1126. }
  1127. registry_key_data->FreeRegistryKeyDataPDU();
  1128. }
  1129. if (error_value == GCC_ALLOCATION_FAILURE)
  1130. {
  1131. ResourceFailureHandler();
  1132. }
  1133. }
  1134. /*
  1135. * void RegistryAllocateHandleRequest()
  1136. *
  1137. * Public Function Description:
  1138. * This routine is used when an APE wishes to allocate a number of
  1139. * handles from the application registry.
  1140. */
  1141. void MCSUser::RegistryAllocateHandleRequest(
  1142. UINT number_of_handles,
  1143. EntityID entity_id )
  1144. {
  1145. GCCError error_value = GCC_NO_ERROR;
  1146. PPacket packet;
  1147. GCCPDU gcc_pdu;
  1148. PacketError packet_error;
  1149. // Encode the PDU that will be forwarded to the top provider.
  1150. gcc_pdu.choice = REQUEST_CHOSEN;
  1151. gcc_pdu.u.request.choice = REGISTRY_ALLOCATE_HANDLE_REQUEST_CHOSEN;
  1152. gcc_pdu.u.request.u.registry_allocate_handle_request.number_of_handles = (USHORT) number_of_handles;
  1153. gcc_pdu.u.request.u.registry_allocate_handle_request.entity_id= entity_id;
  1154. DBG_SAVE_FILE_LINE
  1155. packet = new Packet((PPacketCoder) g_GCCCoder,
  1156. PACKED_ENCODING_RULES,
  1157. (LPVOID)&gcc_pdu,
  1158. GCC_PDU,
  1159. TRUE,
  1160. &packet_error);
  1161. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  1162. {
  1163. AddToMCSMessageQueue(packet, m_nidTopProvider, HIGH_PRIORITY, FALSE);
  1164. }
  1165. else
  1166. {
  1167. error_value = GCC_ALLOCATION_FAILURE;
  1168. delete packet;
  1169. }
  1170. if (error_value == GCC_ALLOCATION_FAILURE)
  1171. {
  1172. ResourceFailureHandler();
  1173. }
  1174. }
  1175. /*
  1176. * void RegistryAllocateHandleResponse()
  1177. *
  1178. * Public Function Description:
  1179. * This routine is used by the Top Provider to respond to an allocate
  1180. * handle request from an APE at a remote node. The allocated handles
  1181. * are passed back here.
  1182. */
  1183. void MCSUser::RegistryAllocateHandleResponse (
  1184. UINT number_of_handles,
  1185. UINT registry_handle,
  1186. EntityID requester_entity_id,
  1187. UserID requester_node_id,
  1188. GCCResult result)
  1189. {
  1190. GCCError error_value = GCC_NO_ERROR;
  1191. PPacket packet;
  1192. GCCPDU gcc_pdu;
  1193. PacketError packet_error;
  1194. // Encode the PDU that will be forwarded to the top provider.
  1195. gcc_pdu.choice = RESPONSE_CHOSEN;
  1196. gcc_pdu.u.response.choice = REGISTRY_ALLOCATE_HANDLE_RESPONSE_CHOSEN;
  1197. gcc_pdu.u.response.u.registry_allocate_handle_response.number_of_handles = (USHORT) number_of_handles;
  1198. gcc_pdu.u.response.u.registry_allocate_handle_response.entity_id = requester_entity_id;
  1199. gcc_pdu.u.response.u.registry_allocate_handle_response.first_handle = (Handle) registry_handle;
  1200. if (result == GCC_RESULT_SUCCESSFUL)
  1201. {
  1202. gcc_pdu.u.response.u.registry_allocate_handle_response.result = RARS_RESULT_SUCCESS;
  1203. }
  1204. else
  1205. {
  1206. gcc_pdu.u.response.u.registry_allocate_handle_response.result = NO_HANDLES_AVAILABLE;
  1207. }
  1208. DBG_SAVE_FILE_LINE
  1209. packet = new Packet((PPacketCoder) g_GCCCoder,
  1210. PACKED_ENCODING_RULES,
  1211. (LPVOID)&gcc_pdu,
  1212. GCC_PDU,
  1213. TRUE,
  1214. &packet_error);
  1215. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  1216. {
  1217. AddToMCSMessageQueue(packet, requester_node_id, HIGH_PRIORITY, FALSE);
  1218. }
  1219. else
  1220. {
  1221. ResourceFailureHandler();
  1222. error_value = GCC_ALLOCATION_FAILURE;
  1223. delete packet;
  1224. }
  1225. }
  1226. /*
  1227. * void RegistryResponse()
  1228. *
  1229. * Public Function Description:
  1230. * This routine is used to respond to all the registry request except
  1231. * allocate handle. It formulates the response PDU and queues it for
  1232. * delivery.
  1233. */
  1234. void MCSUser::RegistryResponse (
  1235. RegistryResponsePrimitiveType primitive_type,
  1236. UserID requester_owner_id,
  1237. EntityID requester_entity_id,
  1238. CRegKeyContainer *registry_key_data,
  1239. CRegItem *registry_item_data,
  1240. GCCModificationRights modification_rights,
  1241. UserID entry_owner_id,
  1242. EntityID entry_entity_id,
  1243. GCCResult result)
  1244. {
  1245. GCCError error_value;
  1246. GCCPDU gcc_pdu;
  1247. PPacket packet;
  1248. PacketError packet_error;
  1249. DebugEntry(MCSUser::RegistryResponse);
  1250. /*
  1251. ** Encode the conference join response PDU, along with the sequence
  1252. ** number.
  1253. */
  1254. gcc_pdu.choice = RESPONSE_CHOSEN;
  1255. gcc_pdu.u.response.choice = REGISTRY_RESPONSE_CHOSEN;
  1256. gcc_pdu.u.response.u.registry_response.bit_mask = 0;
  1257. error_value = registry_key_data->GetRegistryKeyDataPDU(&gcc_pdu.u.response.u.registry_response.key);
  1258. if (error_value == GCC_NO_ERROR)
  1259. {
  1260. if (registry_item_data != NULL)
  1261. {
  1262. registry_item_data->GetRegistryItemDataPDU(&gcc_pdu.u.response.u.registry_response.item);
  1263. }
  1264. else
  1265. {
  1266. gcc_pdu.u.response.u.registry_response.item.choice = VACANT_CHOSEN;
  1267. }
  1268. TRACE_OUT(("MCSUser: RegistryResponse: item_type=%d", (UINT) gcc_pdu.u.response.u.registry_response.item.choice));
  1269. // Set up the entry owner
  1270. if (entry_owner_id != 0)
  1271. {
  1272. gcc_pdu.u.response.u.registry_response.owner.choice = OWNED_CHOSEN;
  1273. gcc_pdu.u.response.u.registry_response.owner.u.owned.node_id = entry_owner_id;
  1274. gcc_pdu.u.response.u.registry_response.owner.u.owned.entity_id = entry_entity_id;
  1275. }
  1276. else
  1277. {
  1278. gcc_pdu.u.response.u.registry_response.owner.choice = NOT_OWNED_CHOSEN;
  1279. }
  1280. // Set up the requesters entity ID
  1281. gcc_pdu.u.response.u.registry_response.entity_id = requester_entity_id;
  1282. // Set up the primitive type
  1283. gcc_pdu.u.response.u.registry_response.primitive_type = primitive_type;
  1284. gcc_pdu.u.response.u.registry_response.result =
  1285. ::TranslateGCCResultToRegistryResp(result);
  1286. if (modification_rights != GCC_NO_MODIFICATION_RIGHTS_SPECIFIED)
  1287. {
  1288. gcc_pdu.u.response.u.registry_response.bit_mask |=
  1289. RESPONSE_MODIFY_RIGHTS_PRESENT;
  1290. gcc_pdu.u.response.u.registry_response.response_modify_rights =
  1291. (RegistryModificationRights)modification_rights;
  1292. }
  1293. DBG_SAVE_FILE_LINE
  1294. packet = new Packet((PPacketCoder) g_GCCCoder,
  1295. PACKED_ENCODING_RULES,
  1296. &gcc_pdu,
  1297. GCC_PDU,
  1298. TRUE,
  1299. &packet_error);
  1300. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  1301. {
  1302. AddToMCSMessageQueue(packet, requester_owner_id, HIGH_PRIORITY, FALSE);
  1303. }
  1304. else
  1305. {
  1306. ResourceFailureHandler();
  1307. error_value = GCC_ALLOCATION_FAILURE;
  1308. delete packet;
  1309. }
  1310. }
  1311. DebugExitVOID(MCSUser::RegistryResponse);
  1312. }
  1313. /*
  1314. * void RegistryMonitorEntryIndication()
  1315. *
  1316. * Public Function Description:
  1317. * This routine is used by the top provider to issue a monitor
  1318. * indication anytime a registry entry that is being monitored changes.
  1319. */
  1320. void MCSUser::RegistryMonitorEntryIndication (
  1321. CRegKeyContainer *registry_key_data,
  1322. CRegItem *registry_item_data,
  1323. UserID entry_owner_id,
  1324. EntityID entry_entity_id,
  1325. GCCModificationRights modification_rights)
  1326. {
  1327. GCCError error_value;
  1328. GCCPDU gcc_pdu;
  1329. PPacket packet;
  1330. PacketError packet_error;
  1331. /*
  1332. ** Encode the conference join response PDU, along with the sequence
  1333. ** number.
  1334. */
  1335. gcc_pdu.choice = INDICATION_CHOSEN;
  1336. gcc_pdu.u.indication.choice = REGISTRY_MONITOR_ENTRY_INDICATION_CHOSEN;
  1337. gcc_pdu.u.indication.u.registry_monitor_entry_indication.bit_mask = 0;
  1338. error_value = registry_key_data->GetRegistryKeyDataPDU(
  1339. &gcc_pdu.u.indication.u.
  1340. registry_monitor_entry_indication.key);
  1341. if (error_value == GCC_NO_ERROR)
  1342. {
  1343. registry_item_data->GetRegistryItemDataPDU(&gcc_pdu.u.indication.u.registry_monitor_entry_indication.item);
  1344. // Set up the entry owner
  1345. if (entry_owner_id != 0)
  1346. {
  1347. gcc_pdu.u.indication.u.registry_monitor_entry_indication.owner.choice = OWNED_CHOSEN;
  1348. gcc_pdu.u.indication.u.registry_monitor_entry_indication.owner.u.owned.node_id = entry_owner_id;
  1349. gcc_pdu.u.indication.u.registry_monitor_entry_indication.owner.u.owned.entity_id = entry_entity_id;
  1350. }
  1351. else
  1352. {
  1353. gcc_pdu.u.indication.u.registry_monitor_entry_indication.owner.choice = NOT_OWNED_CHOSEN;
  1354. }
  1355. if (modification_rights != GCC_NO_MODIFICATION_RIGHTS_SPECIFIED)
  1356. {
  1357. gcc_pdu.u.indication.u.registry_monitor_entry_indication.bit_mask |= RESPONSE_MODIFY_RIGHTS_PRESENT;
  1358. gcc_pdu.u.indication.u.registry_monitor_entry_indication.entry_modify_rights =
  1359. (RegistryModificationRights)modification_rights;
  1360. }
  1361. DBG_SAVE_FILE_LINE
  1362. packet = new Packet((PPacketCoder) g_GCCCoder,
  1363. PACKED_ENCODING_RULES,
  1364. &gcc_pdu,
  1365. GCC_PDU,
  1366. TRUE,
  1367. &packet_error);
  1368. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  1369. {
  1370. AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, HIGH_PRIORITY, TRUE);
  1371. }
  1372. else
  1373. {
  1374. error_value = GCC_ALLOCATION_FAILURE;
  1375. delete packet;
  1376. }
  1377. }
  1378. if (error_value == GCC_ALLOCATION_FAILURE)
  1379. {
  1380. ResourceFailureHandler();
  1381. }
  1382. }
  1383. /************************************************************************/
  1384. /*
  1385. * GCCError AppInvokeIndication()
  1386. *
  1387. * Public Function Description:
  1388. * This routine is used to send an application invoke indication to
  1389. * every node in the conference.
  1390. */
  1391. GCCError MCSUser::AppInvokeIndication(
  1392. CInvokeSpecifierListContainer *invoke_specifier_list,
  1393. GCCSimpleNodeList *pNodeList)
  1394. {
  1395. GCCError rc = GCC_NO_ERROR;
  1396. PPacket packet;
  1397. GCCPDU gcc_pdu;
  1398. PacketError packet_error;
  1399. PSetOfDestinationNodes new_destination_node;
  1400. PSetOfDestinationNodes old_destination_node = NULL;
  1401. PSetOfDestinationNodes pDstNodesToFree = NULL;
  1402. UINT i;
  1403. // Encode the PDU that will be forwarded to the top provider.
  1404. gcc_pdu.choice = INDICATION_CHOSEN;
  1405. gcc_pdu.u.indication.choice = APPLICATION_INVOKE_INDICATION_CHOSEN;
  1406. gcc_pdu.u.indication.u.application_invoke_indication.bit_mask = 0;
  1407. gcc_pdu.u.indication.u.application_invoke_indication.destination_nodes = NULL;
  1408. gcc_pdu.u.indication.u.application_invoke_indication.application_protocol_entity_list = NULL;
  1409. // First, set up the destination node list
  1410. if (pNodeList->cNodes != 0)
  1411. {
  1412. gcc_pdu.u.indication.u.application_invoke_indication.bit_mask |=
  1413. DESTINATION_NODES_PRESENT;
  1414. for (i = 0; i < pNodeList->cNodes; i++)
  1415. {
  1416. DBG_SAVE_FILE_LINE
  1417. new_destination_node = new SetOfDestinationNodes;
  1418. if (new_destination_node != NULL)
  1419. {
  1420. if (gcc_pdu.u.indication.u.application_invoke_indication.
  1421. destination_nodes == NULL)
  1422. {
  1423. gcc_pdu.u.indication.u.application_invoke_indication.
  1424. destination_nodes = new_destination_node;
  1425. pDstNodesToFree = new_destination_node;
  1426. }
  1427. else
  1428. {
  1429. old_destination_node->next = new_destination_node;
  1430. }
  1431. old_destination_node = new_destination_node;
  1432. new_destination_node->next = NULL;
  1433. new_destination_node->value = pNodeList->aNodeIDs[i];
  1434. }
  1435. else
  1436. {
  1437. rc = GCC_ALLOCATION_FAILURE;
  1438. break;
  1439. }
  1440. }
  1441. }
  1442. if (rc == GCC_NO_ERROR)
  1443. {
  1444. rc = invoke_specifier_list->GetApplicationInvokeSpecifierListPDU(
  1445. &gcc_pdu.u.indication.u.application_invoke_indication.
  1446. application_protocol_entity_list);
  1447. }
  1448. if (rc == GCC_NO_ERROR)
  1449. {
  1450. DBG_SAVE_FILE_LINE
  1451. packet = new Packet((PPacketCoder) g_GCCCoder,
  1452. PACKED_ENCODING_RULES,
  1453. (LPVOID)&gcc_pdu,
  1454. GCC_PDU,
  1455. TRUE,
  1456. &packet_error);
  1457. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  1458. {
  1459. AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, HIGH_PRIORITY, TRUE);
  1460. }
  1461. else
  1462. {
  1463. rc = GCC_ALLOCATION_FAILURE;
  1464. delete packet;
  1465. }
  1466. }
  1467. if (NULL != pDstNodesToFree)
  1468. {
  1469. PSetOfDestinationNodes p;
  1470. while (NULL != (p = pDstNodesToFree))
  1471. {
  1472. pDstNodesToFree = pDstNodesToFree->next;
  1473. delete p;
  1474. }
  1475. }
  1476. if (rc == GCC_ALLOCATION_FAILURE)
  1477. {
  1478. ResourceFailureHandler();
  1479. }
  1480. return rc;
  1481. }
  1482. /*
  1483. * GCCError TextMessageIndication()
  1484. *
  1485. * Public Function Description:
  1486. * This routine is used to send a text message to either a specific node
  1487. * or to every node in the conference.
  1488. */
  1489. GCCError MCSUser::TextMessageIndication (
  1490. LPWSTR pwszTextMsg,
  1491. UserID destination_node )
  1492. {
  1493. GCCError rc = GCC_NO_ERROR;
  1494. PPacket packet;
  1495. GCCPDU gcc_pdu;
  1496. PacketError packet_error;
  1497. LPWSTR pwszMsg;
  1498. // Encode the PDU that will be forwarded to the top provider.
  1499. gcc_pdu.choice = INDICATION_CHOSEN;
  1500. gcc_pdu.u.indication.choice = TEXT_MESSAGE_INDICATION_CHOSEN;
  1501. if (NULL != (pwszMsg = ::My_strdupW(pwszTextMsg)))
  1502. {
  1503. gcc_pdu.u.indication.u.text_message_indication.message.length = ::lstrlenW(pwszMsg);
  1504. gcc_pdu.u.indication.u.text_message_indication.message.value = pwszMsg;
  1505. DBG_SAVE_FILE_LINE
  1506. packet = new Packet((PPacketCoder) g_GCCCoder,
  1507. PACKED_ENCODING_RULES,
  1508. (LPVOID)&gcc_pdu,
  1509. GCC_PDU,
  1510. TRUE,
  1511. &packet_error);
  1512. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  1513. {
  1514. AddToMCSMessageQueue(
  1515. packet,
  1516. (destination_node == 0) ? BROADCAST_CHANNEL_ID : destination_node,
  1517. HIGH_PRIORITY,
  1518. FALSE);
  1519. }
  1520. else
  1521. {
  1522. rc = GCC_ALLOCATION_FAILURE;
  1523. delete packet;
  1524. }
  1525. delete pwszMsg;
  1526. }
  1527. else
  1528. {
  1529. rc = GCC_ALLOCATION_FAILURE;
  1530. }
  1531. if (rc == GCC_ALLOCATION_FAILURE)
  1532. {
  1533. ResourceFailureHandler();
  1534. }
  1535. return rc;
  1536. }
  1537. /*
  1538. * GCCError ConferenceAssistanceIndication()
  1539. *
  1540. * Public Function Description:
  1541. * This routine is used to send a conference assistance indication to
  1542. * every node in the conference.
  1543. */
  1544. GCCError MCSUser::ConferenceAssistanceIndication (
  1545. UINT number_of_user_data_members,
  1546. PGCCUserData * user_data_list)
  1547. {
  1548. GCCError rc = GCC_NO_ERROR;
  1549. PPacket packet;
  1550. GCCPDU gcc_pdu;
  1551. PacketError packet_error;
  1552. CUserDataListContainer *user_data_record;
  1553. DebugEntry(MCSUser::ConferenceAssistanceIndication);
  1554. // Encode the PDU
  1555. gcc_pdu.choice = INDICATION_CHOSEN;
  1556. gcc_pdu.u.indication.choice = CONFERENCE_ASSISTANCE_INDICATION_CHOSEN;
  1557. gcc_pdu.u.indication.u.conference_assistance_indication.bit_mask = 0;
  1558. // Construct the user data list container
  1559. if ((number_of_user_data_members != 0) && (rc == GCC_NO_ERROR))
  1560. {
  1561. DBG_SAVE_FILE_LINE
  1562. user_data_record = new CUserDataListContainer(number_of_user_data_members, user_data_list, &rc);
  1563. if (user_data_record == NULL)
  1564. {
  1565. rc = GCC_ALLOCATION_FAILURE;
  1566. }
  1567. }
  1568. else
  1569. {
  1570. user_data_record = NULL;
  1571. }
  1572. if ((user_data_record != NULL) && (rc == GCC_NO_ERROR))
  1573. {
  1574. rc = user_data_record->GetUserDataPDU(
  1575. &gcc_pdu.u.indication.u.conference_assistance_indication.
  1576. cain_user_data);
  1577. gcc_pdu.u.indication.u.conference_assistance_indication.bit_mask
  1578. |= CAIN_USER_DATA_PRESENT;
  1579. }
  1580. if (rc == GCC_NO_ERROR)
  1581. {
  1582. DBG_SAVE_FILE_LINE
  1583. packet = new Packet((PPacketCoder) g_GCCCoder,
  1584. PACKED_ENCODING_RULES,
  1585. &gcc_pdu,
  1586. GCC_PDU,
  1587. TRUE,
  1588. &packet_error);
  1589. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  1590. {
  1591. AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, HIGH_PRIORITY, TRUE);
  1592. }
  1593. else
  1594. {
  1595. rc = GCC_ALLOCATION_FAILURE;
  1596. delete packet;
  1597. }
  1598. }
  1599. // Clean up containers
  1600. if (user_data_record != NULL)
  1601. {
  1602. user_data_record->Release();
  1603. }
  1604. return (rc);
  1605. }
  1606. /*
  1607. * GCCError ConferenceTransferRequest()
  1608. *
  1609. * Public Function Description:
  1610. * This routine is used to send a conference transfer request to the
  1611. * top provider in the conference.
  1612. */
  1613. GCCError MCSUser::ConferenceTransferRequest (
  1614. PGCCConferenceName destination_conference_name,
  1615. GCCNumericString destination_conference_modifier,
  1616. CNetAddrListContainer *destination_address_list,
  1617. UINT number_of_destination_nodes,
  1618. PUserID destination_node_list,
  1619. CPassword *password)
  1620. {
  1621. GCCError rc = GCC_NO_ERROR;
  1622. PPacket packet;
  1623. GCCPDU gcc_pdu;
  1624. PacketError packet_error;
  1625. UINT string_length;
  1626. PSetOfTransferringNodesRq new_set_of_nodes;
  1627. PSetOfTransferringNodesRq old_set_of_nodes;
  1628. UINT i;
  1629. DebugEntry(MCSUser::ConferenceTransferRequest);
  1630. // Encode the PDU
  1631. gcc_pdu.choice = REQUEST_CHOSEN;
  1632. gcc_pdu.u.request.choice = CONFERENCE_TRANSFER_REQUEST_CHOSEN;
  1633. gcc_pdu.u.request.u.conference_transfer_request.bit_mask = 0;
  1634. // First get the conference name (either numeric or text).
  1635. if (destination_conference_name->numeric_string != NULL)
  1636. {
  1637. gcc_pdu.u.request.u.conference_transfer_request.conference_name.choice =
  1638. NAME_SELECTOR_NUMERIC_CHOSEN;
  1639. lstrcpy (gcc_pdu.u.request.u.conference_transfer_request.
  1640. conference_name.u.name_selector_numeric,
  1641. (LPSTR)destination_conference_name->numeric_string);
  1642. }
  1643. else
  1644. {
  1645. // Use a unicode string to determine the length
  1646. gcc_pdu.u.request.u.conference_transfer_request.conference_name.choice =
  1647. NAME_SELECTOR_TEXT_CHOSEN;
  1648. string_length = ::My_strlenW(destination_conference_name->text_string);
  1649. gcc_pdu.u.request.u.conference_transfer_request.
  1650. conference_name.u.name_selector_text.length = string_length;
  1651. gcc_pdu.u.request.u.conference_transfer_request.
  1652. conference_name.u.name_selector_text.value =
  1653. destination_conference_name->text_string;
  1654. }
  1655. // Next get the conference name modifier if it exists
  1656. if (destination_conference_modifier != NULL)
  1657. {
  1658. gcc_pdu.u.request.u.conference_transfer_request.bit_mask |=
  1659. CTRQ_CONFERENCE_MODIFIER_PRESENT;
  1660. lstrcpy (gcc_pdu.u.request.u.conference_transfer_request.
  1661. ctrq_conference_modifier,
  1662. (LPSTR)destination_conference_modifier);
  1663. }
  1664. // Get the network address list if it exist
  1665. if (destination_address_list != NULL)
  1666. {
  1667. gcc_pdu.u.request.u.conference_transfer_request.bit_mask |=
  1668. CTRQ_NETWORK_ADDRESS_PRESENT;
  1669. rc = destination_address_list->GetNetworkAddressListPDU (
  1670. &gcc_pdu.u.request.u.conference_transfer_request.
  1671. ctrq_net_address);
  1672. }
  1673. // Get the destination node list if it exists
  1674. if ((number_of_destination_nodes != 0) && (rc == GCC_NO_ERROR))
  1675. {
  1676. gcc_pdu.u.request.u.conference_transfer_request.bit_mask |=
  1677. CTRQ_TRANSFERRING_NODES_PRESENT;
  1678. old_set_of_nodes = NULL;
  1679. gcc_pdu.u.request.u.conference_transfer_request.
  1680. ctrq_transferring_nodes = NULL;
  1681. for (i = 0; i < number_of_destination_nodes; i++)
  1682. {
  1683. DBG_SAVE_FILE_LINE
  1684. new_set_of_nodes = new SetOfTransferringNodesRq;
  1685. if (new_set_of_nodes == NULL)
  1686. {
  1687. rc = GCC_ALLOCATION_FAILURE;
  1688. break;
  1689. }
  1690. else
  1691. new_set_of_nodes->next = NULL;
  1692. if (old_set_of_nodes == NULL)
  1693. {
  1694. gcc_pdu.u.request.u.conference_transfer_request.
  1695. ctrq_transferring_nodes = new_set_of_nodes;
  1696. }
  1697. else
  1698. old_set_of_nodes->next = new_set_of_nodes;
  1699. old_set_of_nodes = new_set_of_nodes;
  1700. new_set_of_nodes->value = destination_node_list[i];
  1701. }
  1702. }
  1703. // Get the password if it exists
  1704. if ((password != NULL) && (rc == GCC_NO_ERROR))
  1705. {
  1706. gcc_pdu.u.request.u.conference_transfer_request.bit_mask |=
  1707. CTRQ_PASSWORD_PRESENT;
  1708. rc = password->GetPasswordSelectorPDU (
  1709. &gcc_pdu.u.request.u.conference_transfer_request.ctrq_password);
  1710. }
  1711. // Encode the PDU
  1712. if (rc == GCC_NO_ERROR)
  1713. {
  1714. DBG_SAVE_FILE_LINE
  1715. packet = new Packet((PPacketCoder) g_GCCCoder,
  1716. PACKED_ENCODING_RULES,
  1717. &gcc_pdu,
  1718. GCC_PDU,
  1719. TRUE,
  1720. &packet_error);
  1721. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  1722. {
  1723. AddToMCSMessageQueue(packet, m_nidTopProvider, HIGH_PRIORITY, FALSE);
  1724. }
  1725. else
  1726. {
  1727. rc = GCC_ALLOCATION_FAILURE;
  1728. delete packet;
  1729. }
  1730. }
  1731. // Clean up the node list if it was created
  1732. if (gcc_pdu.u.request.u.conference_transfer_request.bit_mask &
  1733. CTRQ_TRANSFERRING_NODES_PRESENT)
  1734. {
  1735. old_set_of_nodes = gcc_pdu.u.request.u.conference_transfer_request.
  1736. ctrq_transferring_nodes;
  1737. while (old_set_of_nodes != NULL)
  1738. {
  1739. new_set_of_nodes = old_set_of_nodes->next;
  1740. delete old_set_of_nodes;
  1741. old_set_of_nodes = new_set_of_nodes;
  1742. }
  1743. }
  1744. return rc;
  1745. }
  1746. /*
  1747. * GCCError ConferenceTransferIndication()
  1748. *
  1749. * Public Function Description:
  1750. * This routine is used by the top provider to send out the transfer
  1751. * indication to every node in the conference. It is each nodes
  1752. * responsiblity to search the destination node list to see if
  1753. * it should transfer.
  1754. */
  1755. GCCError MCSUser::ConferenceTransferIndication (
  1756. PGCCConferenceName destination_conference_name,
  1757. GCCNumericString destination_conference_modifier,
  1758. CNetAddrListContainer *destination_address_list,
  1759. UINT number_of_destination_nodes,
  1760. PUserID destination_node_list,
  1761. CPassword *password)
  1762. {
  1763. GCCError rc = GCC_NO_ERROR;
  1764. PPacket packet;
  1765. GCCPDU gcc_pdu;
  1766. PacketError packet_error;
  1767. UINT string_length;
  1768. PSetOfTransferringNodesIn new_set_of_nodes;
  1769. PSetOfTransferringNodesIn old_set_of_nodes;
  1770. UINT i;
  1771. DebugEntry(MCSUser::ConferenceTransferIndication);
  1772. // Encode the PDU
  1773. gcc_pdu.choice = INDICATION_CHOSEN;
  1774. gcc_pdu.u.indication.choice = CONFERENCE_TRANSFER_INDICATION_CHOSEN;
  1775. gcc_pdu.u.indication.u.conference_transfer_indication.bit_mask = 0;
  1776. // First get the conference name (either numeric or text).
  1777. if (destination_conference_name->numeric_string != NULL)
  1778. {
  1779. gcc_pdu.u.indication.u.conference_transfer_indication.
  1780. conference_name.choice =
  1781. NAME_SELECTOR_NUMERIC_CHOSEN;
  1782. lstrcpy (gcc_pdu.u.indication.u.conference_transfer_indication.
  1783. conference_name.u.name_selector_numeric,
  1784. (LPSTR)destination_conference_name->numeric_string);
  1785. }
  1786. else
  1787. {
  1788. // Use a unicode string to determine the length
  1789. gcc_pdu.u.indication.u.conference_transfer_indication.
  1790. conference_name.choice =
  1791. NAME_SELECTOR_TEXT_CHOSEN;
  1792. string_length = ::My_strlenW(destination_conference_name->text_string);
  1793. gcc_pdu.u.indication.u.conference_transfer_indication.
  1794. conference_name.u.name_selector_text.length = string_length;
  1795. gcc_pdu.u.indication.u.conference_transfer_indication.
  1796. conference_name.u.name_selector_text.value =
  1797. destination_conference_name->text_string;
  1798. }
  1799. // Next get the conference name modifier if it exists
  1800. if (destination_conference_modifier != NULL)
  1801. {
  1802. gcc_pdu.u.indication.u.conference_transfer_indication.bit_mask |=
  1803. CTIN_CONFERENCE_MODIFIER_PRESENT;
  1804. lstrcpy (gcc_pdu.u.indication.u.conference_transfer_indication.
  1805. ctin_conference_modifier,
  1806. (LPSTR)destination_conference_modifier);
  1807. }
  1808. // Get the network address list if it exist
  1809. if (destination_address_list != NULL)
  1810. {
  1811. gcc_pdu.u.indication.u.conference_transfer_indication.bit_mask |=
  1812. CTIN_NETWORK_ADDRESS_PRESENT;
  1813. rc = destination_address_list->GetNetworkAddressListPDU (
  1814. &gcc_pdu.u.indication.u.conference_transfer_indication.
  1815. ctin_net_address);
  1816. }
  1817. // Get the destination node list if it exists
  1818. if ((number_of_destination_nodes != 0) && (rc == GCC_NO_ERROR))
  1819. {
  1820. gcc_pdu.u.indication.u.conference_transfer_indication.bit_mask |=
  1821. CTIN_TRANSFERRING_NODES_PRESENT;
  1822. old_set_of_nodes = NULL;
  1823. gcc_pdu.u.indication.u.conference_transfer_indication.
  1824. ctin_transferring_nodes = NULL;
  1825. for (i = 0; i < number_of_destination_nodes; i++)
  1826. {
  1827. DBG_SAVE_FILE_LINE
  1828. new_set_of_nodes = new SetOfTransferringNodesIn;
  1829. if (new_set_of_nodes == NULL)
  1830. {
  1831. rc = GCC_ALLOCATION_FAILURE;
  1832. break;
  1833. }
  1834. else
  1835. new_set_of_nodes->next = NULL;
  1836. if (old_set_of_nodes == NULL)
  1837. {
  1838. gcc_pdu.u.indication.u.conference_transfer_indication.
  1839. ctin_transferring_nodes = new_set_of_nodes;
  1840. }
  1841. else
  1842. old_set_of_nodes->next = new_set_of_nodes;
  1843. old_set_of_nodes = new_set_of_nodes;
  1844. new_set_of_nodes->value = destination_node_list[i];
  1845. }
  1846. }
  1847. // Get the password if it exists
  1848. if ((password != NULL) && (rc == GCC_NO_ERROR))
  1849. {
  1850. gcc_pdu.u.indication.u.conference_transfer_indication.bit_mask |=
  1851. CTIN_PASSWORD_PRESENT;
  1852. rc = password->GetPasswordSelectorPDU (
  1853. &gcc_pdu.u.indication.u.conference_transfer_indication.
  1854. ctin_password);
  1855. }
  1856. // Encode the PDU
  1857. if (rc == GCC_NO_ERROR)
  1858. {
  1859. DBG_SAVE_FILE_LINE
  1860. packet = new Packet((PPacketCoder) g_GCCCoder,
  1861. PACKED_ENCODING_RULES,
  1862. &gcc_pdu,
  1863. GCC_PDU,
  1864. TRUE,
  1865. &packet_error);
  1866. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  1867. {
  1868. AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, HIGH_PRIORITY, TRUE);
  1869. }
  1870. else
  1871. {
  1872. rc = GCC_ALLOCATION_FAILURE;
  1873. delete packet;
  1874. }
  1875. }
  1876. // Clean up the node list if it was created
  1877. if (gcc_pdu.u.indication.u.conference_transfer_indication.bit_mask &
  1878. CTIN_TRANSFERRING_NODES_PRESENT)
  1879. {
  1880. old_set_of_nodes = gcc_pdu.u.indication.u.
  1881. conference_transfer_indication.ctin_transferring_nodes;
  1882. while (old_set_of_nodes != NULL)
  1883. {
  1884. new_set_of_nodes = old_set_of_nodes->next;
  1885. delete old_set_of_nodes;
  1886. old_set_of_nodes = new_set_of_nodes;
  1887. }
  1888. }
  1889. DebugExitINT(MCSUser::ConferenceTransferIndication, rc);
  1890. return rc;
  1891. }
  1892. /*
  1893. * GCCError ConferenceTransferResponse()
  1894. *
  1895. * Public Function Description:
  1896. * This routine is used by the top provider to send back a response to
  1897. * the node that made a transfer request. The info specified in the
  1898. * request is included in the response to match request to response.
  1899. */
  1900. GCCError MCSUser::ConferenceTransferResponse (
  1901. UserID requesting_node_id,
  1902. PGCCConferenceName destination_conference_name,
  1903. GCCNumericString destination_conference_modifier,
  1904. UINT number_of_destination_nodes,
  1905. PUserID destination_node_list,
  1906. GCCResult result)
  1907. {
  1908. GCCError rc = GCC_NO_ERROR;
  1909. PPacket packet;
  1910. GCCPDU gcc_pdu;
  1911. PacketError packet_error;
  1912. UINT string_length;
  1913. PSetOfTransferringNodesRs new_set_of_nodes;
  1914. PSetOfTransferringNodesRs old_set_of_nodes;
  1915. UINT i;
  1916. DebugEntry(MCSUser::ConferenceTransferResponse);
  1917. // Encode the PDU
  1918. gcc_pdu.choice = RESPONSE_CHOSEN;
  1919. gcc_pdu.u.response.choice = CONFERENCE_TRANSFER_RESPONSE_CHOSEN;
  1920. gcc_pdu.u.response.u.conference_transfer_response.bit_mask = 0;
  1921. // First get the conference name (either numeric or text).
  1922. if (destination_conference_name->numeric_string != NULL)
  1923. {
  1924. gcc_pdu.u.response.u.conference_transfer_response.
  1925. conference_name.choice =
  1926. NAME_SELECTOR_NUMERIC_CHOSEN;
  1927. ::lstrcpyA(gcc_pdu.u.response.u.conference_transfer_response.
  1928. conference_name.u.name_selector_numeric,
  1929. (LPSTR)destination_conference_name->numeric_string);
  1930. }
  1931. else
  1932. {
  1933. // Use a unicode string to determine the length
  1934. gcc_pdu.u.response.u.conference_transfer_response.
  1935. conference_name.choice =
  1936. NAME_SELECTOR_TEXT_CHOSEN;
  1937. string_length = ::My_strlenW(destination_conference_name->text_string);
  1938. gcc_pdu.u.response.u.conference_transfer_response.
  1939. conference_name.u.name_selector_text.length = string_length;
  1940. gcc_pdu.u.response.u.conference_transfer_response.
  1941. conference_name.u.name_selector_text.value =
  1942. destination_conference_name->text_string;
  1943. }
  1944. // Next get the conference name modifier if it exists
  1945. if (destination_conference_modifier != NULL)
  1946. {
  1947. gcc_pdu.u.response.u.conference_transfer_response.bit_mask |=
  1948. CTRS_CONFERENCE_MODIFIER_PRESENT;
  1949. ::lstrcpyA(gcc_pdu.u.response.u.conference_transfer_response.
  1950. ctrs_conference_modifier,
  1951. (LPSTR)destination_conference_modifier);
  1952. }
  1953. // Get the destination node list if it exists
  1954. if ((number_of_destination_nodes != 0) && (rc == GCC_NO_ERROR))
  1955. {
  1956. gcc_pdu.u.response.u.conference_transfer_response.bit_mask |=
  1957. CTRS_TRANSFERRING_NODES_PRESENT;
  1958. old_set_of_nodes = NULL;
  1959. gcc_pdu.u.response.u.conference_transfer_response.
  1960. ctrs_transferring_nodes = NULL;
  1961. for (i = 0; i < number_of_destination_nodes; i++)
  1962. {
  1963. DBG_SAVE_FILE_LINE
  1964. new_set_of_nodes = new SetOfTransferringNodesRs;
  1965. if (new_set_of_nodes == NULL)
  1966. {
  1967. rc = GCC_ALLOCATION_FAILURE;
  1968. break;
  1969. }
  1970. else
  1971. new_set_of_nodes->next = NULL;
  1972. if (old_set_of_nodes == NULL)
  1973. {
  1974. gcc_pdu.u.response.u.conference_transfer_response.
  1975. ctrs_transferring_nodes = new_set_of_nodes;
  1976. }
  1977. else
  1978. old_set_of_nodes->next = new_set_of_nodes;
  1979. old_set_of_nodes = new_set_of_nodes;
  1980. new_set_of_nodes->value = destination_node_list[i];
  1981. }
  1982. }
  1983. // Set up the result
  1984. if (result == GCC_RESULT_SUCCESSFUL)
  1985. {
  1986. gcc_pdu.u.response.u.conference_transfer_response.result =
  1987. CTRANS_RESULT_SUCCESS;
  1988. }
  1989. else
  1990. {
  1991. gcc_pdu.u.response.u.conference_transfer_response.result =
  1992. CTRANS_RESULT_INVALID_REQUESTER;
  1993. }
  1994. // Encode the PDU
  1995. if (rc == GCC_NO_ERROR)
  1996. {
  1997. DBG_SAVE_FILE_LINE
  1998. packet = new Packet((PPacketCoder) g_GCCCoder,
  1999. PACKED_ENCODING_RULES,
  2000. &gcc_pdu,
  2001. GCC_PDU,
  2002. TRUE,
  2003. &packet_error);
  2004. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  2005. {
  2006. AddToMCSMessageQueue(packet, requesting_node_id, HIGH_PRIORITY, FALSE);
  2007. }
  2008. else
  2009. {
  2010. rc = GCC_ALLOCATION_FAILURE;
  2011. delete packet;
  2012. }
  2013. }
  2014. // Clean up the node list if it was created
  2015. if (gcc_pdu.u.response.u.conference_transfer_response.bit_mask &
  2016. CTRS_TRANSFERRING_NODES_PRESENT)
  2017. {
  2018. old_set_of_nodes = gcc_pdu.u.response.u.
  2019. conference_transfer_response.ctrs_transferring_nodes;
  2020. while (old_set_of_nodes != NULL)
  2021. {
  2022. new_set_of_nodes = old_set_of_nodes->next;
  2023. delete old_set_of_nodes;
  2024. old_set_of_nodes = new_set_of_nodes;
  2025. }
  2026. }
  2027. DebugExitINT(MCSUser::ConferenceTransferResponse, rc);
  2028. return rc;
  2029. }
  2030. /*
  2031. * GCCError ConferenceAddRequest()
  2032. *
  2033. * Public Function Description:
  2034. * This routine is used to send a conference add request to the appropriate
  2035. * node. This call can be made by the requesting node or by the top
  2036. * provider to pass the add request on to the adding node.
  2037. */
  2038. GCCError MCSUser::ConferenceAddRequest (
  2039. TagNumber conference_add_tag,
  2040. UserID requesting_node,
  2041. UserID adding_node,
  2042. UserID target_node,
  2043. CNetAddrListContainer *network_address_container,
  2044. CUserDataListContainer *user_data_container)
  2045. {
  2046. GCCError rc = GCC_NO_ERROR;
  2047. PPacket packet;
  2048. GCCPDU gcc_pdu;
  2049. PacketError packet_error;
  2050. DebugEntry(MCSUser::ConferenceAddRequest);
  2051. // Encode the PDU
  2052. gcc_pdu.choice = REQUEST_CHOSEN;
  2053. gcc_pdu.u.request.choice = CONFERENCE_ADD_REQUEST_CHOSEN;
  2054. gcc_pdu.u.request.u.conference_add_request.bit_mask = 0;
  2055. // Get the network address list if it exist
  2056. if (network_address_container != NULL)
  2057. {
  2058. // Set up the network address portion of the pdu
  2059. rc = network_address_container->GetNetworkAddressListPDU (
  2060. &gcc_pdu.u.request.u.conference_add_request.
  2061. add_request_net_address);
  2062. // Set up the user data container
  2063. if ((rc == GCC_NO_ERROR) && (user_data_container != NULL))
  2064. {
  2065. rc = user_data_container->GetUserDataPDU (
  2066. &gcc_pdu.u.request.u.conference_add_request.carq_user_data);
  2067. if (rc == GCC_NO_ERROR)
  2068. {
  2069. gcc_pdu.u.request.u.conference_add_request.bit_mask |=
  2070. CARQ_USER_DATA_PRESENT;
  2071. }
  2072. }
  2073. // Encode the PDU
  2074. if (rc == GCC_NO_ERROR)
  2075. {
  2076. // specify the requesting node
  2077. gcc_pdu.u.request.u.conference_add_request.requesting_node =
  2078. requesting_node;
  2079. if (adding_node != 0)
  2080. {
  2081. gcc_pdu.u.request.u.conference_add_request.bit_mask |=
  2082. ADDING_MCU_PRESENT;
  2083. gcc_pdu.u.request.u.conference_add_request.adding_mcu =
  2084. adding_node;
  2085. }
  2086. gcc_pdu.u.request.u.conference_add_request.tag = conference_add_tag;
  2087. DBG_SAVE_FILE_LINE
  2088. packet = new Packet((PPacketCoder) g_GCCCoder,
  2089. PACKED_ENCODING_RULES,
  2090. &gcc_pdu,
  2091. GCC_PDU,
  2092. TRUE,
  2093. &packet_error);
  2094. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  2095. {
  2096. AddToMCSMessageQueue(packet, target_node, HIGH_PRIORITY, FALSE);
  2097. }
  2098. else
  2099. {
  2100. rc = GCC_ALLOCATION_FAILURE;
  2101. delete packet;
  2102. }
  2103. }
  2104. }
  2105. else
  2106. {
  2107. rc = GCC_BAD_NETWORK_ADDRESS;
  2108. }
  2109. DebugExitINT(MCSUser::ConferenceAddRequest, rc);
  2110. return rc;
  2111. }
  2112. /*
  2113. * GCCError ConferenceAddResponse()
  2114. *
  2115. * Public Function Description:
  2116. * This routine is used to send a conference add request to the appropriate
  2117. * node. This call can be made by the requesting node or by the top
  2118. * provider to pass the add request on to the adding node.
  2119. */
  2120. GCCError MCSUser::ConferenceAddResponse(
  2121. TagNumber add_request_tag,
  2122. UserID requesting_node,
  2123. CUserDataListContainer *user_data_container,
  2124. GCCResult result)
  2125. {
  2126. GCCError rc = GCC_NO_ERROR;
  2127. PPacket packet;
  2128. GCCPDU gcc_pdu;
  2129. PacketError packet_error;
  2130. DebugEntry(MCSUser::ConferenceAddResponse);
  2131. // Encode the PDU
  2132. gcc_pdu.choice = RESPONSE_CHOSEN;
  2133. gcc_pdu.u.response.choice = CONFERENCE_ADD_RESPONSE_CHOSEN;
  2134. gcc_pdu.u.response.u.conference_add_response.bit_mask = 0;
  2135. // Set up the user data container
  2136. if ((rc == GCC_NO_ERROR) && (user_data_container != NULL))
  2137. {
  2138. rc = user_data_container->GetUserDataPDU (
  2139. &gcc_pdu.u.response.u.conference_add_response.cars_user_data);
  2140. if (rc == GCC_NO_ERROR)
  2141. {
  2142. gcc_pdu.u.response.u.conference_add_response.bit_mask |=
  2143. CARS_USER_DATA_PRESENT;
  2144. }
  2145. }
  2146. // Encode the PDU
  2147. if (rc == GCC_NO_ERROR)
  2148. {
  2149. gcc_pdu.u.response.u.conference_add_response.tag = add_request_tag;
  2150. gcc_pdu.u.response.u.conference_add_response.result =
  2151. ::TranslateGCCResultToAddResult(result);
  2152. DBG_SAVE_FILE_LINE
  2153. packet = new Packet((PPacketCoder) g_GCCCoder,
  2154. PACKED_ENCODING_RULES,
  2155. &gcc_pdu,
  2156. GCC_PDU,
  2157. TRUE,
  2158. &packet_error);
  2159. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  2160. {
  2161. AddToMCSMessageQueue(packet, requesting_node, HIGH_PRIORITY, FALSE);
  2162. }
  2163. else
  2164. {
  2165. rc = GCC_ALLOCATION_FAILURE;
  2166. delete packet;
  2167. }
  2168. }
  2169. DebugExitINT(MCSUser::ConferenceAddResponse, rc);
  2170. return rc;
  2171. }
  2172. /************************* Conductorship Calls ***********************/
  2173. /*
  2174. * GCCError ConductorTokenGrab()
  2175. *
  2176. * Public Function Description:
  2177. * This routine makes the MCS calls to grab the conductor token.
  2178. */
  2179. GCCError MCSUser::ConductorTokenGrab()
  2180. {
  2181. MCSError mcs_error;
  2182. mcs_error = g_pMCSIntf->TokenGrabRequest(m_pMCSSap, CONDUCTOR_TOKEN_ID);
  2183. return (g_pMCSIntf->TranslateMCSIFErrorToGCCError (mcs_error));
  2184. }
  2185. /*
  2186. * GCCError ConductorTokenRelease()
  2187. *
  2188. * Public Function Description:
  2189. * This routine makes the MCS calls to release the conductor token.
  2190. */
  2191. GCCError MCSUser::ConductorTokenRelease()
  2192. {
  2193. MCSError mcs_error;
  2194. mcs_error = g_pMCSIntf->TokenReleaseRequest(m_pMCSSap, CONDUCTOR_TOKEN_ID);
  2195. return (g_pMCSIntf->TranslateMCSIFErrorToGCCError (mcs_error));
  2196. }
  2197. /*
  2198. * GCCError ConductorTokenPlease()
  2199. *
  2200. * Public Function Description:
  2201. * This routine makes the MCS calls to request the conductor token from
  2202. * the current conductor.
  2203. */
  2204. GCCError MCSUser::ConductorTokenPlease()
  2205. {
  2206. MCSError mcs_error;
  2207. mcs_error = g_pMCSIntf->TokenPleaseRequest(m_pMCSSap, CONDUCTOR_TOKEN_ID);
  2208. return (g_pMCSIntf->TranslateMCSIFErrorToGCCError (mcs_error));
  2209. }
  2210. /*
  2211. * GCCError ConductorTokenGive ()
  2212. *
  2213. * Public Function Description:
  2214. * This routine makes the MCS calls to give the conductor token to the
  2215. * specified node.
  2216. */
  2217. GCCError MCSUser::ConductorTokenGive(UserID recipient_user_id)
  2218. {
  2219. MCSError mcs_error;
  2220. mcs_error = g_pMCSIntf->TokenGiveRequest(m_pMCSSap, CONDUCTOR_TOKEN_ID,
  2221. recipient_user_id);
  2222. return (g_pMCSIntf->TranslateMCSIFErrorToGCCError (mcs_error));
  2223. }
  2224. /*
  2225. * GCCError ConductorTokenGiveResponse ()
  2226. *
  2227. * Public Function Description:
  2228. * This routine makes the MCS calls to respond to a conductor give
  2229. * request.
  2230. */
  2231. GCCError MCSUser::ConductorTokenGiveResponse(Result result)
  2232. {
  2233. MCSError mcs_error;
  2234. mcs_error = g_pMCSIntf->TokenGiveResponse(m_pMCSSap, CONDUCTOR_TOKEN_ID, result);
  2235. return g_pMCSIntf->TranslateMCSIFErrorToGCCError(mcs_error);
  2236. }
  2237. /*
  2238. * GCCError ConductorTokenTest ()
  2239. *
  2240. * Public Function Description:
  2241. * This routine is used to test the current state of the conductor token
  2242. * (is it grabbed or not).
  2243. */
  2244. GCCError MCSUser::ConductorTokenTest()
  2245. {
  2246. MCSError mcs_error;
  2247. mcs_error = g_pMCSIntf->TokenTestRequest(m_pMCSSap, CONDUCTOR_TOKEN_ID);
  2248. return g_pMCSIntf->TranslateMCSIFErrorToGCCError(mcs_error);
  2249. }
  2250. /*
  2251. * GCCError SendConductorAssignIndication()
  2252. *
  2253. * Public Function Description:
  2254. * This routine sends a conductor assign indication to all the
  2255. * nodes in the conference.
  2256. */
  2257. GCCError MCSUser::SendConductorAssignIndication(
  2258. UserID conductor_user_id)
  2259. {
  2260. GCCError rc = GCC_NO_ERROR;
  2261. PPacket packet;
  2262. GCCPDU gcc_pdu;
  2263. PacketError packet_error;
  2264. /*
  2265. ** Fill in the ConductorAssignIndication pdu structure to be passed in the
  2266. ** constructor of the packet class.
  2267. */
  2268. gcc_pdu.choice = INDICATION_CHOSEN;
  2269. gcc_pdu.u.indication.choice = CONDUCTOR_ASSIGN_INDICATION_CHOSEN;
  2270. gcc_pdu.u.indication.u.conductor_assign_indication.user_id =
  2271. conductor_user_id;
  2272. /*
  2273. ** Create a packet object
  2274. */
  2275. DBG_SAVE_FILE_LINE
  2276. packet = new Packet((PPacketCoder) g_GCCCoder,
  2277. PACKED_ENCODING_RULES,
  2278. &gcc_pdu,
  2279. GCC_PDU, // pdu_type
  2280. TRUE,
  2281. &packet_error);
  2282. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  2283. {
  2284. AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, TOP_PRIORITY, TRUE);
  2285. }
  2286. else
  2287. {
  2288. ResourceFailureHandler();
  2289. rc = GCC_ALLOCATION_FAILURE;
  2290. delete packet;
  2291. }
  2292. return rc;
  2293. }
  2294. /*
  2295. * GCCError SendConductorReleaseIndication()
  2296. *
  2297. * Public Function Description:
  2298. * This routine sends a conductor release indication to all the
  2299. * nodes in the conference.
  2300. */
  2301. GCCError MCSUser::SendConductorReleaseIndication()
  2302. {
  2303. GCCError rc = GCC_NO_ERROR;
  2304. PPacket packet;
  2305. GCCPDU gcc_pdu;
  2306. PacketError packet_error;
  2307. /*
  2308. ** Fill in the ConductorAssignIndication pdu structure to be passed in the
  2309. ** constructor of the packet class.
  2310. */
  2311. gcc_pdu.choice = INDICATION_CHOSEN;
  2312. gcc_pdu.u.indication.choice = CONDUCTOR_RELEASE_INDICATION_CHOSEN;
  2313. gcc_pdu.u.indication.u.conductor_release_indication.placeholder = 0;
  2314. /*
  2315. ** Create a packet object
  2316. */
  2317. DBG_SAVE_FILE_LINE
  2318. packet = new Packet((PPacketCoder) g_GCCCoder,
  2319. PACKED_ENCODING_RULES,
  2320. &gcc_pdu,
  2321. GCC_PDU, // pdu_type
  2322. TRUE,
  2323. &packet_error);
  2324. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  2325. {
  2326. AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, TOP_PRIORITY, TRUE);
  2327. }
  2328. else
  2329. {
  2330. ResourceFailureHandler();
  2331. rc = GCC_ALLOCATION_FAILURE;
  2332. delete packet;
  2333. }
  2334. return rc;
  2335. }
  2336. /*
  2337. * GCCError SendConductorPermitAsk ()
  2338. *
  2339. * Public Function Description:
  2340. * This routine sends a conductor permission ask request directly to the
  2341. * conductor node.
  2342. */
  2343. GCCError MCSUser::SendConductorPermitAsk (
  2344. BOOL grant_permission)
  2345. {
  2346. GCCError rc = GCC_NO_ERROR;
  2347. PPacket packet;
  2348. GCCPDU gcc_pdu;
  2349. PacketError packet_error;
  2350. /*
  2351. ** Fill in the ConductorPermissionAskIndication pdu structure to be passed
  2352. ** in the constructor of the packet class.
  2353. */
  2354. gcc_pdu.choice = INDICATION_CHOSEN;
  2355. gcc_pdu.u.indication.choice = CONDUCTOR_PERMISSION_ASK_INDICATION_CHOSEN;
  2356. gcc_pdu.u.indication.u.conductor_permission_ask_indication.
  2357. permission_is_granted = (ASN1bool_t)grant_permission;
  2358. /*
  2359. ** Create a packet object
  2360. */
  2361. DBG_SAVE_FILE_LINE
  2362. packet = new Packet((PPacketCoder) g_GCCCoder,
  2363. PACKED_ENCODING_RULES,
  2364. &gcc_pdu,
  2365. GCC_PDU, // pdu_type
  2366. TRUE,
  2367. &packet_error);
  2368. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  2369. {
  2370. AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, HIGH_PRIORITY, TRUE);
  2371. }
  2372. else
  2373. {
  2374. ResourceFailureHandler();
  2375. rc = GCC_ALLOCATION_FAILURE;
  2376. delete packet;
  2377. }
  2378. return rc;
  2379. }
  2380. /*
  2381. * GCCError SendConductorPermitGrant ()
  2382. *
  2383. * Public Function Description:
  2384. * This routine sends a conductor permission grant indication to every
  2385. * node in the conference. Usually issued when permissions change.
  2386. */
  2387. GCCError MCSUser::SendConductorPermitGrant (
  2388. UINT number_granted,
  2389. PUserID granted_node_list,
  2390. UINT number_waiting,
  2391. PUserID waiting_node_list)
  2392. {
  2393. GCCError rc = GCC_NO_ERROR;
  2394. PPacket packet;
  2395. GCCPDU gcc_pdu;
  2396. PacketError packet_error;
  2397. PPermissionList permission_list;
  2398. PPermissionList previous_permission_list;
  2399. PWaitingList waiting_list;
  2400. PWaitingList previous_waiting_list;
  2401. UINT i;
  2402. /*
  2403. ** Fill in the ConductorPermissionAskIndication pdu structure to be passed
  2404. ** in the constructor of the packet class.
  2405. */
  2406. gcc_pdu.choice = INDICATION_CHOSEN;
  2407. gcc_pdu.u.indication.choice = CONDUCTOR_PERMISSION_GRANT_INDICATION_CHOSEN;
  2408. gcc_pdu.u.indication.u.conductor_permission_grant_indication.bit_mask = 0;
  2409. // First fill in the granted node permission list
  2410. gcc_pdu.u.indication.u.
  2411. conductor_permission_grant_indication.permission_list = NULL;
  2412. previous_permission_list = NULL;
  2413. for (i = 0; i < number_granted; i++)
  2414. {
  2415. DBG_SAVE_FILE_LINE
  2416. permission_list = new PermissionList;
  2417. if (permission_list == NULL)
  2418. {
  2419. rc = GCC_ALLOCATION_FAILURE;
  2420. break;
  2421. }
  2422. if (previous_permission_list == NULL)
  2423. {
  2424. gcc_pdu.u.indication.u.conductor_permission_grant_indication.
  2425. permission_list = permission_list;
  2426. }
  2427. else
  2428. previous_permission_list->next = permission_list;
  2429. previous_permission_list = permission_list;
  2430. permission_list->value = granted_node_list[i];
  2431. permission_list->next = NULL;
  2432. }
  2433. // If waiting list exists fill it in
  2434. if ((number_waiting != 0) && (rc == GCC_NO_ERROR))
  2435. {
  2436. gcc_pdu.u.indication.u.conductor_permission_grant_indication.bit_mask =
  2437. WAITING_LIST_PRESENT;
  2438. gcc_pdu.u.indication.u.
  2439. conductor_permission_grant_indication.waiting_list = NULL;
  2440. previous_waiting_list = NULL;
  2441. for (i = 0; i < number_waiting; i++)
  2442. {
  2443. DBG_SAVE_FILE_LINE
  2444. waiting_list = new WaitingList;
  2445. if (waiting_list == NULL)
  2446. {
  2447. rc = GCC_ALLOCATION_FAILURE;
  2448. break;
  2449. }
  2450. if (previous_waiting_list == NULL)
  2451. {
  2452. gcc_pdu.u.indication.u.conductor_permission_grant_indication.
  2453. waiting_list = waiting_list;
  2454. }
  2455. else
  2456. previous_waiting_list->next = waiting_list;
  2457. previous_waiting_list = waiting_list;
  2458. waiting_list->value = waiting_node_list[i];
  2459. waiting_list->next = NULL;
  2460. }
  2461. }
  2462. /*
  2463. ** Create a packet object
  2464. */
  2465. DBG_SAVE_FILE_LINE
  2466. packet = new Packet((PPacketCoder) g_GCCCoder,
  2467. PACKED_ENCODING_RULES,
  2468. &gcc_pdu,
  2469. GCC_PDU, // pdu_type
  2470. TRUE,
  2471. &packet_error);
  2472. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  2473. {
  2474. AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, TOP_PRIORITY, TRUE);
  2475. }
  2476. else
  2477. {
  2478. ResourceFailureHandler();
  2479. rc = GCC_ALLOCATION_FAILURE;
  2480. delete packet;
  2481. }
  2482. return rc;
  2483. }
  2484. /**********************************************************************/
  2485. /***************** Miscelaneous calls ******************************/
  2486. /*
  2487. * GCCError TimeRemainingRequest()
  2488. *
  2489. * Public Function Description:
  2490. * This routine sends out an indication to every node in the
  2491. * conference informing how much time is remaining in the conference.
  2492. */
  2493. GCCError MCSUser::TimeRemainingRequest (
  2494. UINT time_remaining,
  2495. UserID node_id)
  2496. {
  2497. GCCError rc = GCC_NO_ERROR;
  2498. PPacket packet;
  2499. GCCPDU gcc_pdu;
  2500. PacketError packet_error;
  2501. /*
  2502. ** Fill in the TimeRemainingRequest pdu structure to be passed in the
  2503. ** constructor of the packet class.
  2504. */
  2505. gcc_pdu.choice = INDICATION_CHOSEN;
  2506. gcc_pdu.u.indication.choice = CONFERENCE_TIME_REMAINING_INDICATION_CHOSEN;
  2507. gcc_pdu.u.indication.u.conference_time_remaining_indication.bit_mask = 0;
  2508. gcc_pdu.u.indication.u.conference_time_remaining_indication.time_remaining =
  2509. time_remaining;
  2510. if (node_id != 0)
  2511. {
  2512. gcc_pdu.u.indication.u.conference_time_remaining_indication.bit_mask |=
  2513. TIME_REMAINING_NODE_ID_PRESENT;
  2514. gcc_pdu.u.indication.u.conference_time_remaining_indication.
  2515. time_remaining_node_id = node_id;
  2516. }
  2517. /*
  2518. ** Create a packet object
  2519. */
  2520. DBG_SAVE_FILE_LINE
  2521. packet = new Packet((PPacketCoder) g_GCCCoder,
  2522. PACKED_ENCODING_RULES,
  2523. &gcc_pdu,
  2524. GCC_PDU, // pdu_type
  2525. TRUE,
  2526. &packet_error);
  2527. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  2528. {
  2529. AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, HIGH_PRIORITY, TRUE);
  2530. }
  2531. else
  2532. {
  2533. ResourceFailureHandler();
  2534. rc = GCC_ALLOCATION_FAILURE;
  2535. delete packet;
  2536. }
  2537. return rc;
  2538. }
  2539. /*
  2540. * GCCError TimeInquireRequest()
  2541. *
  2542. * Public Function Description:
  2543. * This routine sends out a request for a time remaing update.
  2544. */
  2545. GCCError MCSUser::TimeInquireRequest (
  2546. BOOL time_is_conference_wide)
  2547. {
  2548. GCCError rc = GCC_NO_ERROR;
  2549. PPacket packet;
  2550. GCCPDU gcc_pdu;
  2551. PacketError packet_error;
  2552. /*
  2553. ** Fill in the TimeInquireRequest pdu structure to be passed in the
  2554. ** constructor of the packet class.
  2555. */
  2556. gcc_pdu.choice = INDICATION_CHOSEN;
  2557. gcc_pdu.u.indication.choice = CONFERENCE_TIME_INQUIRE_INDICATION_CHOSEN;
  2558. gcc_pdu.u.indication.u.conference_time_inquire_indication.
  2559. time_is_node_specific = (ASN1bool_t)time_is_conference_wide;
  2560. /*
  2561. ** Create a packet object
  2562. */
  2563. DBG_SAVE_FILE_LINE
  2564. packet = new Packet((PPacketCoder) g_GCCCoder,
  2565. PACKED_ENCODING_RULES,
  2566. &gcc_pdu,
  2567. GCC_PDU, // pdu_type
  2568. TRUE,
  2569. &packet_error);
  2570. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  2571. {
  2572. AddToMCSMessageQueue(packet, CONVENER_CHANNEL_ID, HIGH_PRIORITY, FALSE);
  2573. }
  2574. else
  2575. {
  2576. ResourceFailureHandler();
  2577. rc = GCC_ALLOCATION_FAILURE;
  2578. delete packet;
  2579. }
  2580. return rc;
  2581. }
  2582. /*
  2583. * GCCError ConferenceExtendIndication()
  2584. *
  2585. * Public Function Description:
  2586. * This routine sends out an indication informing conference participants
  2587. * of an extension.
  2588. */
  2589. GCCError MCSUser::ConferenceExtendIndication (
  2590. UINT extension_time,
  2591. BOOL time_is_conference_wide)
  2592. {
  2593. GCCError rc = GCC_NO_ERROR;
  2594. PPacket packet;
  2595. GCCPDU gcc_pdu;
  2596. PacketError packet_error;
  2597. /*
  2598. ** Fill in the ConfernceExtendIndication pdu structure to be passed in the
  2599. ** constructor of the packet class.
  2600. */
  2601. gcc_pdu.choice = INDICATION_CHOSEN;
  2602. gcc_pdu.u.indication.choice = CONFERENCE_TIME_EXTEND_INDICATION_CHOSEN;
  2603. gcc_pdu.u.indication.u.conference_time_extend_indication.
  2604. time_to_extend = extension_time;
  2605. gcc_pdu.u.indication.u.conference_time_extend_indication.
  2606. time_is_node_specific = (ASN1bool_t)time_is_conference_wide;
  2607. /*
  2608. ** Create a packet object
  2609. */
  2610. DBG_SAVE_FILE_LINE
  2611. packet = new Packet((PPacketCoder) g_GCCCoder,
  2612. PACKED_ENCODING_RULES,
  2613. &gcc_pdu,
  2614. GCC_PDU, // pdu_type
  2615. TRUE,
  2616. &packet_error);
  2617. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  2618. {
  2619. AddToMCSMessageQueue(packet, CONVENER_CHANNEL_ID, HIGH_PRIORITY, FALSE);
  2620. }
  2621. else
  2622. {
  2623. ResourceFailureHandler();
  2624. rc = GCC_ALLOCATION_FAILURE;
  2625. delete packet;
  2626. }
  2627. return rc;
  2628. }
  2629. /*
  2630. * void ConferenceJoinResponse()
  2631. *
  2632. * Functional Description:
  2633. * This function is called by the conference object of the
  2634. * top provider when it wants to send the join response back to the gcc
  2635. * provider that made the join request, through the directly connected
  2636. * intermediate node. This function does the encoding of the join response
  2637. * PDU and also adds the sequence number sent in the request.
  2638. */
  2639. void MCSUser::ConferenceJoinResponse(
  2640. UserID receiver_id,
  2641. BOOL password_is_in_the_clear,
  2642. BOOL conference_locked,
  2643. BOOL conference_listed,
  2644. GCCTerminationMethod termination_method,
  2645. CPassword *password_challenge,
  2646. CUserDataListContainer *user_data_list,
  2647. GCCResult result)
  2648. {
  2649. GCCError rc = GCC_NO_ERROR;
  2650. GCCPDU gcc_pdu;
  2651. PPacket packet;
  2652. PacketError packet_error;
  2653. TagNumber lTagNum;
  2654. if (0 == (lTagNum = m_ConfJoinResponseList2.Find(receiver_id)))
  2655. {
  2656. WARNING_OUT(("MCSUser::ConferenceJoinResponse: Unexpected Join Response"));
  2657. return;
  2658. }
  2659. /*
  2660. ** Encode the conference join response PDU, along with the sequence
  2661. ** number.
  2662. */
  2663. gcc_pdu.choice = RESPONSE_CHOSEN;
  2664. gcc_pdu.u.response.choice = CONFERENCE_JOIN_RESPONSE_CHOSEN;
  2665. gcc_pdu.u.response.u.conference_join_response.bit_mask = 0;
  2666. /*
  2667. ** Get the sequence number of the outstanding response from the
  2668. ** list of seq # vs userID using the userID passed from above.
  2669. */
  2670. gcc_pdu.u.response.u.conference_join_response.tag = lTagNum;
  2671. // Remove this entry from the list.
  2672. m_ConfJoinResponseList2.Remove(receiver_id);
  2673. // Get password challenge PDU
  2674. if ((password_challenge != NULL) && (rc == GCC_NO_ERROR))
  2675. {
  2676. rc = password_challenge->GetPasswordChallengeResponsePDU (
  2677. &gcc_pdu.u.response.u.conference_join_response.cjrs_password);
  2678. if (rc == GCC_NO_ERROR)
  2679. {
  2680. gcc_pdu.u.response.u.conference_join_response.bit_mask |=
  2681. CJRS_PASSWORD_PRESENT;
  2682. }
  2683. }
  2684. // Get user data list PDU
  2685. if ((user_data_list != NULL) && (rc == GCC_NO_ERROR))
  2686. {
  2687. rc = user_data_list->GetUserDataPDU (
  2688. &gcc_pdu.u.response.u.conference_join_response.cjrs_user_data);
  2689. if (rc == GCC_NO_ERROR)
  2690. {
  2691. gcc_pdu.u.response.u.conference_join_response.bit_mask |=
  2692. CJRS_USER_DATA_PRESENT;
  2693. }
  2694. }
  2695. if (rc == GCC_NO_ERROR)
  2696. {
  2697. gcc_pdu.u.response.u.conference_join_response.
  2698. top_node_id = m_nidTopProvider;
  2699. gcc_pdu.u.response.u.conference_join_response.
  2700. clear_password_required = (ASN1bool_t)password_is_in_the_clear;
  2701. gcc_pdu.u.response.u.conference_join_response.
  2702. conference_is_locked = (ASN1bool_t)conference_locked;
  2703. gcc_pdu.u.response.u.conference_join_response.
  2704. conference_is_listed = (ASN1bool_t)conference_listed;
  2705. gcc_pdu.u.response.u.conference_join_response.termination_method =
  2706. (TerminationMethod)termination_method;
  2707. gcc_pdu.u.response.u.conference_join_response.result =
  2708. ::TranslateGCCResultToJoinResult(result);
  2709. DBG_SAVE_FILE_LINE
  2710. packet = new Packet((PPacketCoder) g_GCCCoder,
  2711. PACKED_ENCODING_RULES,
  2712. &gcc_pdu,
  2713. GCC_PDU,
  2714. TRUE,
  2715. &packet_error);
  2716. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  2717. {
  2718. AddToMCSMessageQueue(packet, receiver_id, TOP_PRIORITY, FALSE);
  2719. }
  2720. else
  2721. {
  2722. rc = GCC_ALLOCATION_FAILURE;
  2723. delete packet;
  2724. }
  2725. }
  2726. if (rc == GCC_ALLOCATION_FAILURE)
  2727. {
  2728. ResourceFailureHandler();
  2729. }
  2730. }
  2731. /*
  2732. * void ConferenceTerminateRequest()
  2733. *
  2734. * Functional Description:
  2735. * This routine is used by a node subordinate to the top provider to
  2736. * request that the conference by terminated.
  2737. */
  2738. void MCSUser::ConferenceTerminateRequest(
  2739. GCCReason reason)
  2740. {
  2741. GCCError error_value = GCC_NO_ERROR;
  2742. GCCPDU gcc_pdu;
  2743. PPacket packet;
  2744. PacketError packet_error;
  2745. gcc_pdu.choice = REQUEST_CHOSEN;
  2746. gcc_pdu.u.request.choice = CONFERENCE_TERMINATE_REQUEST_CHOSEN;
  2747. gcc_pdu.u.request.u.conference_terminate_request.reason =
  2748. ::TranslateGCCReasonToTerminateRqReason(reason);
  2749. DBG_SAVE_FILE_LINE
  2750. packet = new Packet((PPacketCoder) g_GCCCoder,
  2751. PACKED_ENCODING_RULES,
  2752. &gcc_pdu,
  2753. GCC_PDU,
  2754. TRUE,
  2755. &packet_error);
  2756. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  2757. {
  2758. AddToMCSMessageQueue(packet, m_nidTopProvider, HIGH_PRIORITY, FALSE);
  2759. }
  2760. else
  2761. {
  2762. ResourceFailureHandler();
  2763. error_value = GCC_ALLOCATION_FAILURE;
  2764. delete packet;
  2765. }
  2766. }
  2767. /*
  2768. * void ConferenceTerminateResponse ()
  2769. *
  2770. * Functional Description:
  2771. * This routine is used by the top provider to respond to a terminate
  2772. * request issued by a subordinate node. The result indicates if the
  2773. * requesting node had the correct privileges.
  2774. */
  2775. void MCSUser::ConferenceTerminateResponse (
  2776. UserID requester_id,
  2777. GCCResult result)
  2778. {
  2779. GCCError error_value = GCC_NO_ERROR;
  2780. GCCPDU gcc_pdu;
  2781. PPacket packet;
  2782. PacketError packet_error;
  2783. gcc_pdu.choice = RESPONSE_CHOSEN;
  2784. gcc_pdu.u.response.choice = CONFERENCE_TERMINATE_RESPONSE_CHOSEN;
  2785. gcc_pdu.u.response.u.conference_terminate_response.result =
  2786. ::TranslateGCCResultToTerminateResult(result);
  2787. DBG_SAVE_FILE_LINE
  2788. packet = new Packet((PPacketCoder) g_GCCCoder,
  2789. PACKED_ENCODING_RULES,
  2790. &gcc_pdu,
  2791. GCC_PDU,
  2792. TRUE,
  2793. &packet_error);
  2794. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  2795. {
  2796. AddToMCSMessageQueue(packet, requester_id, HIGH_PRIORITY, FALSE);
  2797. }
  2798. else
  2799. {
  2800. ResourceFailureHandler();
  2801. error_value = GCC_ALLOCATION_FAILURE;
  2802. delete packet;
  2803. }
  2804. }
  2805. /*
  2806. * GCCError ConferenceTerminateIndication()
  2807. *
  2808. * Functional Description:
  2809. * This routine is used by the top provider to send out a terminate
  2810. * indication to every node in the conference.
  2811. */
  2812. void MCSUser::ConferenceTerminateIndication (
  2813. GCCReason reason)
  2814. {
  2815. GCCError error_value = GCC_NO_ERROR;
  2816. GCCPDU gcc_pdu;
  2817. PPacket packet;
  2818. PacketError packet_error;
  2819. gcc_pdu.choice = INDICATION_CHOSEN;
  2820. gcc_pdu.u.indication.choice = CONFERENCE_TERMINATE_INDICATION_CHOSEN;
  2821. gcc_pdu.u.indication.u.conference_terminate_indication.reason =
  2822. ::TranslateGCCReasonToTerminateInReason(reason);
  2823. DBG_SAVE_FILE_LINE
  2824. packet = new Packet((PPacketCoder) g_GCCCoder,
  2825. PACKED_ENCODING_RULES,
  2826. &gcc_pdu,
  2827. GCC_PDU,
  2828. TRUE,
  2829. &packet_error);
  2830. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  2831. {
  2832. AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, HIGH_PRIORITY, TRUE);
  2833. }
  2834. else
  2835. {
  2836. ResourceFailureHandler();
  2837. error_value = GCC_ALLOCATION_FAILURE;
  2838. delete packet;
  2839. }
  2840. }
  2841. /*
  2842. * void EjectNodeFromConference()
  2843. *
  2844. * Functional Description:
  2845. * This routine is used when attempting to eject a node from the
  2846. * conference.
  2847. */
  2848. GCCError MCSUser::EjectNodeFromConference ( UserID ejected_node_id,
  2849. GCCReason reason)
  2850. {
  2851. GCCError rc = GCC_NO_ERROR;
  2852. GCCPDU gcc_pdu;
  2853. PPacket packet;
  2854. PacketError packet_error;
  2855. ChannelID channel_id;
  2856. BOOL uniform_send;
  2857. Priority priority;
  2858. PAlarm alarm;
  2859. if (ejected_node_id == m_nidMyself)
  2860. {
  2861. /*
  2862. ** If the ejected node is this node we can immediately initiate the
  2863. ** ejection. There is no need to request this through the Top
  2864. ** Provider.
  2865. */
  2866. rc = InitiateEjectionFromConference (reason);
  2867. }
  2868. else
  2869. {
  2870. /*
  2871. ** If the ejected node is a child node to this node we can directly
  2872. ** eject it. Otherwise the request is forwarded to the Top Provider.
  2873. */
  2874. if (m_ChildUidConnHdlList2.Find(ejected_node_id) ||
  2875. (m_nidTopProvider == m_nidMyself))
  2876. {
  2877. gcc_pdu.choice = INDICATION_CHOSEN;
  2878. gcc_pdu.u.indication.choice =
  2879. CONFERENCE_EJECT_USER_INDICATION_CHOSEN;
  2880. gcc_pdu.u.indication.u.conference_eject_user_indication.
  2881. node_to_eject = ejected_node_id;
  2882. gcc_pdu.u.indication.u.conference_eject_user_indication.reason =
  2883. ::TranslateGCCReasonToEjectInd(reason);
  2884. uniform_send = TRUE;
  2885. channel_id = BROADCAST_CHANNEL_ID;
  2886. // If this is the top provider send the data at TOP priority
  2887. if (m_nidTopProvider == m_nidMyself)
  2888. priority = TOP_PRIORITY;
  2889. else
  2890. priority = HIGH_PRIORITY;
  2891. /*
  2892. ** Set up ejection alarm to automatically eject any misbehaving
  2893. ** nodes. Note that we only do this if we are directly connected
  2894. ** to the node to be ejected.
  2895. */
  2896. if (m_ChildUidConnHdlList2.Find(ejected_node_id))
  2897. {
  2898. DBG_SAVE_FILE_LINE
  2899. alarm = new Alarm (EJECTED_NODE_TIMER_DURATION);
  2900. if (alarm != NULL)
  2901. {
  2902. /*
  2903. ** Here we save the alarm in a list of ejected nodes. This
  2904. ** alarm is used to cleanup any misbehaving node.
  2905. */
  2906. m_EjectedNodeAlarmList2.Append(ejected_node_id, alarm);
  2907. }
  2908. else
  2909. {
  2910. rc = GCC_ALLOCATION_FAILURE;
  2911. }
  2912. }
  2913. }
  2914. else
  2915. {
  2916. gcc_pdu.choice = REQUEST_CHOSEN;
  2917. gcc_pdu.u.request.choice = CONFERENCE_EJECT_USER_REQUEST_CHOSEN;
  2918. gcc_pdu.u.request.u.conference_eject_user_request.node_to_eject =
  2919. ejected_node_id;
  2920. // The only valid reason is user initiated which is zero
  2921. gcc_pdu.u.request.u.conference_eject_user_request.reason =
  2922. CERQ_REASON_USER_INITIATED;
  2923. uniform_send = FALSE;
  2924. channel_id = m_nidTopProvider;
  2925. priority = TOP_PRIORITY;
  2926. }
  2927. if (rc == GCC_NO_ERROR)
  2928. {
  2929. DBG_SAVE_FILE_LINE
  2930. packet = new Packet((PPacketCoder) g_GCCCoder,
  2931. PACKED_ENCODING_RULES,
  2932. &gcc_pdu,
  2933. GCC_PDU,
  2934. TRUE,
  2935. &packet_error);
  2936. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  2937. {
  2938. AddToMCSMessageQueue(packet, channel_id, priority, uniform_send);
  2939. }
  2940. else
  2941. {
  2942. rc = GCC_ALLOCATION_FAILURE;
  2943. delete packet;
  2944. }
  2945. }
  2946. }
  2947. if (rc == GCC_ALLOCATION_FAILURE)
  2948. {
  2949. ResourceFailureHandler();
  2950. }
  2951. return rc;
  2952. }
  2953. /*
  2954. * void SendEjectNodeResponse()
  2955. *
  2956. * Functional Description:
  2957. * This routine is used by the top provider to respond to an eject
  2958. * user request.
  2959. */
  2960. GCCError MCSUser::SendEjectNodeResponse ( UserID requester_id,
  2961. UserID node_to_eject,
  2962. GCCResult result)
  2963. {
  2964. GCCError rc = GCC_NO_ERROR;
  2965. GCCPDU gcc_pdu;
  2966. PPacket packet;
  2967. PacketError packet_error;
  2968. gcc_pdu.choice = RESPONSE_CHOSEN;
  2969. gcc_pdu.u.response.choice = CONFERENCE_EJECT_USER_RESPONSE_CHOSEN;
  2970. gcc_pdu.u.response.u.conference_eject_user_response.node_to_eject =
  2971. node_to_eject;
  2972. gcc_pdu.u.response.u.conference_eject_user_response.result =
  2973. ::TranslateGCCResultToEjectResult(result);
  2974. DBG_SAVE_FILE_LINE
  2975. packet = new Packet((PPacketCoder) g_GCCCoder,
  2976. PACKED_ENCODING_RULES,
  2977. &gcc_pdu,
  2978. GCC_PDU,
  2979. TRUE,
  2980. &packet_error);
  2981. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  2982. {
  2983. AddToMCSMessageQueue(packet, requester_id, HIGH_PRIORITY, FALSE);
  2984. }
  2985. else
  2986. {
  2987. ResourceFailureHandler();
  2988. rc = GCC_ALLOCATION_FAILURE;
  2989. delete packet;
  2990. }
  2991. return rc;
  2992. }
  2993. /*
  2994. * void RosterUpdateIndication()
  2995. *
  2996. * Functional Description:
  2997. * This routine is used to forward a roster update indication either
  2998. * upward to the parent node or downward as a full refresh to all nodes
  2999. * in the conference.
  3000. */
  3001. void MCSUser::RosterUpdateIndication(PGCCPDU gcc_pdu,
  3002. BOOL send_update_upward)
  3003. {
  3004. PPacket packet;
  3005. PacketError packet_error;
  3006. DBG_SAVE_FILE_LINE
  3007. packet = new Packet((PPacketCoder) g_GCCCoder,
  3008. PACKED_ENCODING_RULES,
  3009. gcc_pdu,
  3010. GCC_PDU,
  3011. TRUE,
  3012. &packet_error);
  3013. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  3014. {
  3015. if (send_update_upward)
  3016. {
  3017. AddToMCSMessageQueue(packet, m_nidParent, HIGH_PRIORITY, FALSE);
  3018. }
  3019. else
  3020. {
  3021. AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, HIGH_PRIORITY, TRUE);
  3022. }
  3023. }
  3024. else
  3025. {
  3026. ResourceFailureHandler();
  3027. delete packet;
  3028. }
  3029. }
  3030. /*
  3031. * void AddToMCSMessageQueue()
  3032. *
  3033. * Private Function Description:
  3034. * This function adds the out bound messages to a queue which is
  3035. * flushed in the next heartbeat when controller call FlushMessageQueue.
  3036. * In case memory allocation for messages holding the out bound inform-
  3037. * ation fails an owner call back is sent to conference object to
  3038. * indicate insufficient memory.
  3039. *
  3040. * Formal Parameters:
  3041. * packet - (i) Pointer to packet to queue up.
  3042. * send_data_request_info - (i) Structure containing all the info
  3043. * necessary to deliver the packet.
  3044. *
  3045. * Return Value
  3046. * None.
  3047. *
  3048. * Side Effects
  3049. * None.
  3050. *
  3051. * Caveats
  3052. * None.
  3053. */
  3054. void MCSUser::
  3055. AddToMCSMessageQueue
  3056. (
  3057. PPacket packet,
  3058. ChannelID channel_id,
  3059. Priority priority,
  3060. BOOL uniform_send
  3061. )
  3062. {
  3063. SEND_DATA_REQ_INFO *pReqInfo;
  3064. DBG_SAVE_FILE_LINE
  3065. pReqInfo = new SEND_DATA_REQ_INFO;
  3066. if (pReqInfo != NULL)
  3067. {
  3068. pReqInfo->packet = packet;
  3069. pReqInfo->channel_id = channel_id;
  3070. pReqInfo->priority = priority;
  3071. pReqInfo->uniform_send = uniform_send;
  3072. /*
  3073. ** This forces the packet to be encoded. This must happen here so
  3074. ** that any memory used by the decoded portion of the packet can
  3075. ** be freed after returning.
  3076. */
  3077. // packet->Lock();
  3078. m_OutgoingPDUQueue.Append(pReqInfo);
  3079. if (m_OutgoingPDUQueue.GetCount() == 1)
  3080. {
  3081. if (FlushOutgoingPDU())
  3082. {
  3083. // Inform the MCS interface that there are PDUs queued
  3084. g_pGCCController->SetEventToFlushOutgoingPDU();
  3085. }
  3086. }
  3087. else
  3088. {
  3089. // Inform the MCS interface that there are PDUs queued
  3090. g_pGCCController->SetEventToFlushOutgoingPDU();
  3091. }
  3092. }
  3093. else
  3094. {
  3095. ResourceFailureHandler();
  3096. /*
  3097. ** This just sets a flag in the packet object that allows packet
  3098. ** to commit suicide if lock count on encoded and decoded data is
  3099. ** zero. This will occur once the packet is sent on to MCS.
  3100. */
  3101. packet->Unlock();
  3102. }
  3103. }
  3104. /*
  3105. * BOOL FlushOutgoingPDU()
  3106. *
  3107. * Public Function Description:
  3108. * This function is called by the owner object in every heartbeat. This
  3109. * function iterates throught the list of pending out bound messages
  3110. * and sends them down to MCS. Also after a successful send it frees
  3111. * any resources tied up with the outbound messages. If however a message
  3112. * can not be sent in this heartbeat, as indicated by MCS, then it
  3113. * inserts the message back onto the message queue and returns.
  3114. *
  3115. * Return value:
  3116. * TRUE, if there remain un-processed msgs in the MCS message queue
  3117. * FALSE, if all the msgs in the MCS msg queue were processed.
  3118. */
  3119. void MCSUser::
  3120. CheckEjectedNodeAlarms ( void )
  3121. {
  3122. /*
  3123. ** We first check the eject user list to make sure that no alarms have
  3124. ** expired on any of the ejected nodes.
  3125. */
  3126. if (m_EjectedNodeAlarmList2.IsEmpty() == FALSE)
  3127. {
  3128. PAlarm lpAlarm;
  3129. UserID uid;
  3130. // We copy the list so that we can remove entries in the iterator
  3131. while (NULL != (lpAlarm = m_EjectedNodeAlarmList2.Get(&uid)))
  3132. {
  3133. // Has the alarm expired for this node?
  3134. if (lpAlarm->IsExpired())
  3135. {
  3136. ConnectionHandle hConn;
  3137. /*
  3138. ** Tell the owner object to disconnect the misbehaving node
  3139. ** that exists at the connection handle accessed through
  3140. ** the m_ChildUidConnHdlList2.
  3141. */
  3142. if (NULL != (hConn = m_ChildUidConnHdlList2.Find(uid)))
  3143. {
  3144. //
  3145. // This must generate a disconnect provider for eject node to
  3146. // work properly.
  3147. //
  3148. g_pMCSIntf->DisconnectProviderRequest(hConn);
  3149. //
  3150. // Since this node will not get a disconnect indication when it
  3151. // issues a DisconnectProviderRequest we go ahead and call it
  3152. // from here.
  3153. //
  3154. m_pConf->DisconnectProviderIndication(hConn);
  3155. }
  3156. }
  3157. // Delete the alarm
  3158. delete lpAlarm;
  3159. }
  3160. }
  3161. }
  3162. BOOL MCSUser::
  3163. FlushOutgoingPDU ( void )
  3164. {
  3165. DWORD mcs_message_count;
  3166. DWORD count;
  3167. UINT rc;
  3168. SEND_DATA_REQ_INFO *pReqInfo;
  3169. mcs_message_count = m_OutgoingPDUQueue.GetCount();
  3170. for (count = 0;
  3171. (count < mcs_message_count) && (m_OutgoingPDUQueue.IsEmpty() == FALSE);
  3172. count++)
  3173. {
  3174. /*
  3175. ** Get the next message from the queue.
  3176. */
  3177. pReqInfo = m_OutgoingPDUQueue.Get();
  3178. /*
  3179. * If MCS takes the request without an error, free information
  3180. * structure and unlock the encoded information in the packet.
  3181. * Unlocking the packet before deleting the infomration structure
  3182. * ensures that packet object is deleted and not left dangling.
  3183. * This is true because here only one lock is performed.
  3184. * If there is an error in the send data request, it means mcs can not
  3185. * take any more requests, therefore insert the information
  3186. * structure back in the queue and break out of this loop.
  3187. */
  3188. if (pReqInfo->uniform_send)
  3189. {
  3190. rc = g_pMCSIntf->UniformSendDataRequest(
  3191. pReqInfo->channel_id,
  3192. m_pMCSSap,
  3193. pReqInfo->priority,
  3194. (LPBYTE) pReqInfo->packet->GetEncodedData(),
  3195. pReqInfo->packet->GetEncodedDataLength());
  3196. }
  3197. else
  3198. {
  3199. rc = g_pMCSIntf->SendDataRequest(
  3200. pReqInfo->channel_id,
  3201. m_pMCSSap,
  3202. pReqInfo->priority,
  3203. (LPBYTE) pReqInfo->packet->GetEncodedData(),
  3204. pReqInfo->packet->GetEncodedDataLength());
  3205. }
  3206. if (rc == MCS_NO_ERROR)
  3207. {
  3208. pReqInfo->packet->Unlock();
  3209. delete pReqInfo;
  3210. }
  3211. else
  3212. {
  3213. TRACE_OUT(("MCSUser::FlushMessageQueue: Could not send queued packet data in this heartbeat"));
  3214. m_OutgoingPDUQueue.Prepend(pReqInfo);
  3215. break; // breaking out of the for loop
  3216. }
  3217. }
  3218. return (! (m_OutgoingPDUQueue.IsEmpty() && m_EjectedNodeAlarmList2.IsEmpty()));
  3219. }
  3220. /*
  3221. * MCSUser::SetChildUserID()
  3222. *
  3223. * Public Function Description:
  3224. * This function is called by the conference object to pass on the user id
  3225. * of the child node to the user object. The user object inserts this
  3226. * user id into a user id list of it's children which it maintains.
  3227. */
  3228. void MCSUser::SetChildUserIDAndConnection (
  3229. UserID child_user_id,
  3230. ConnectionHandle child_connection_handle)
  3231. {
  3232. TRACE_OUT(("MCSUser::SetChildUserID: Adding Child userid=0x%04x to the list", (UINT) child_user_id));
  3233. TRACE_OUT(("MCSUser::SetChildUserID: Adding Child Connection=%d to the list", (UINT) child_connection_handle));
  3234. m_ChildUidConnHdlList2.Append(child_user_id, child_connection_handle);
  3235. }
  3236. /*
  3237. * GCCError InitiateEjectionFromConference()
  3238. *
  3239. * Private Function Description:
  3240. * This internal routine kicks of the process of ejecting this node
  3241. * from the conference. This includes ejecting all the nodes below
  3242. * this node and waiting for their disconnect indications to come back
  3243. * in.
  3244. *
  3245. * Formal Parameters:
  3246. * reason - (i) Reason for ejection.
  3247. *
  3248. * Return Value
  3249. * GCC_NO_ERROR - No error occured.
  3250. * GCC_ALLOCATION_FAILURE - A resource error occured.
  3251. *
  3252. * Side Effects
  3253. * None.
  3254. *
  3255. * Caveats
  3256. * None.
  3257. */
  3258. GCCError MCSUser::InitiateEjectionFromConference (GCCReason reason)
  3259. {
  3260. GCCError error_value = GCC_NO_ERROR;
  3261. GCCPDU gcc_pdu;
  3262. PPacket packet;
  3263. PacketError packet_error;
  3264. PAlarm alarm = NULL;
  3265. m_fEjectionPending = TRUE;
  3266. m_eEjectReason = reason;
  3267. if (m_ChildUidConnHdlList2.IsEmpty() == FALSE)
  3268. {
  3269. UserID uid;
  3270. gcc_pdu.choice = INDICATION_CHOSEN;
  3271. gcc_pdu.u.indication.choice = CONFERENCE_EJECT_USER_INDICATION_CHOSEN;
  3272. gcc_pdu.u.indication.u.conference_eject_user_indication.reason =
  3273. ::TranslateGCCReasonToEjectInd(
  3274. GCC_REASON_HIGHER_NODE_EJECTED);
  3275. m_ChildUidConnHdlList2.Reset();
  3276. while (m_ChildUidConnHdlList2.Iterate(&uid))
  3277. {
  3278. // Get the Node to eject from the list of child nodes
  3279. gcc_pdu.u.indication.u.conference_eject_user_indication.node_to_eject = uid;
  3280. DBG_SAVE_FILE_LINE
  3281. packet = new Packet((PPacketCoder) g_GCCCoder,
  3282. PACKED_ENCODING_RULES,
  3283. &gcc_pdu,
  3284. GCC_PDU,
  3285. TRUE,
  3286. &packet_error);
  3287. if ((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  3288. {
  3289. AddToMCSMessageQueue(packet, BROADCAST_CHANNEL_ID, HIGH_PRIORITY, TRUE);
  3290. DBG_SAVE_FILE_LINE
  3291. alarm = new Alarm (EJECTED_NODE_TIMER_DURATION);
  3292. if (alarm != NULL)
  3293. {
  3294. /*
  3295. ** Here we save the alarm in a list of ejected
  3296. ** nodes. This alarm is used to cleanup any
  3297. ** misbehaving node.
  3298. */
  3299. m_EjectedNodeAlarmList2.Append(uid, alarm);
  3300. }
  3301. else
  3302. {
  3303. error_value = GCC_ALLOCATION_FAILURE;
  3304. break;
  3305. }
  3306. }
  3307. else
  3308. {
  3309. error_value = GCC_ALLOCATION_FAILURE;
  3310. delete packet;
  3311. break;
  3312. }
  3313. }
  3314. }
  3315. else
  3316. {
  3317. m_pConf->ProcessEjectUserIndication(m_eEjectReason);
  3318. }
  3319. return (error_value);
  3320. }
  3321. /*
  3322. * UINT ProcessSendDataIndication()
  3323. *
  3324. * Private Function Description:
  3325. * This function is called when the user object gets send data indications
  3326. * from below. It finds out the message type and decodes the pdu in the
  3327. * user data field of send data indications. Based on the type of decoded
  3328. * pdu it take the necessary actions.
  3329. *
  3330. * Formal Parameters:
  3331. * send_data_info - (i) Send data structure to process.
  3332. *
  3333. * Return Value
  3334. * MCS_NO_ERROR is always returned from this routine.
  3335. *
  3336. * Side Effects
  3337. * None.
  3338. *
  3339. * Caveats
  3340. * None.
  3341. */
  3342. UINT MCSUser::ProcessSendDataIndication(PSendData send_data_info)
  3343. {
  3344. PPacket packet;
  3345. PacketError packet_error;
  3346. PGCCPDU gcc_pdu;
  3347. GCCError error_value = GCC_NO_ERROR;
  3348. UserID initiator;
  3349. DBG_SAVE_FILE_LINE
  3350. packet = new Packet((PPacketCoder) g_GCCCoder,
  3351. PACKED_ENCODING_RULES,
  3352. (LPBYTE)send_data_info->user_data.value,
  3353. send_data_info->user_data.length,
  3354. GCC_PDU,
  3355. TRUE,
  3356. &packet_error);
  3357. if(packet != NULL && packet_error == PACKET_NO_ERROR)
  3358. {
  3359. initiator = send_data_info->initiator;
  3360. gcc_pdu = (PGCCPDU)packet->GetDecodedData();
  3361. switch(gcc_pdu->choice)
  3362. {
  3363. case INDICATION_CHOSEN: // Data PDU
  3364. switch(gcc_pdu->u.indication.choice)
  3365. {
  3366. case USER_ID_INDICATION_CHOSEN:
  3367. {
  3368. /*
  3369. * Sequence number and User Id sent by the child
  3370. * node after a successful conference create or
  3371. * join.
  3372. */
  3373. m_pConf->ProcessUserIDIndication(
  3374. gcc_pdu->u.indication.u.user_id_indication.tag,
  3375. initiator);
  3376. }
  3377. break;
  3378. case ROSTER_UPDATE_INDICATION_CHOSEN:
  3379. if(send_data_info->channel_id == m_nidMyself)
  3380. {
  3381. //
  3382. // We only process the roster update if the conference is
  3383. // established.
  3384. //
  3385. if (m_pConf->IsConfEstablished())
  3386. {
  3387. m_pConf->ProcessRosterUpdatePDU(gcc_pdu, initiator);
  3388. }
  3389. }
  3390. break;
  3391. case CONFERENCE_TIME_INQUIRE_INDICATION_CHOSEN:
  3392. g_pControlSap->ConfTimeInquireIndication(
  3393. m_pConf->GetConfID(),
  3394. gcc_pdu->u.indication.u.conference_time_inquire_indication.time_is_node_specific,
  3395. initiator);
  3396. break;
  3397. case CONFERENCE_TIME_EXTEND_INDICATION_CHOSEN:
  3398. #ifdef JASPER
  3399. ProcessConferenceExtendIndicationPDU(
  3400. &gcc_pdu->u.indication.u.
  3401. conference_time_extend_indication,
  3402. initiator);
  3403. #endif // JASPER
  3404. break;
  3405. case APPLICATION_INVOKE_INDICATION_CHOSEN:
  3406. ProcessApplicationInvokeIndication(
  3407. &gcc_pdu->u.indication.u.
  3408. application_invoke_indication,
  3409. initiator);
  3410. break;
  3411. case TEXT_MESSAGE_INDICATION_CHOSEN:
  3412. #ifdef JASPER
  3413. if (ProcessTextMessageIndication(
  3414. &gcc_pdu->u.indication.u.
  3415. text_message_indication,
  3416. initiator) != GCC_NO_ERROR)
  3417. {
  3418. error_value = GCC_ALLOCATION_FAILURE;
  3419. }
  3420. #endif // JASPER
  3421. break;
  3422. case CONFERENCE_LOCK_INDICATION_CHOSEN:
  3423. m_pConf->ProcessConferenceLockIndication(initiator);
  3424. break;
  3425. case CONFERENCE_UNLOCK_INDICATION_CHOSEN:
  3426. m_pConf->ProcessConferenceUnlockIndication(initiator);
  3427. break;
  3428. default:
  3429. ERROR_OUT(("User::ProcessSendDataIndication Unsupported PDU"));
  3430. break;
  3431. } // switch(gcc_pdu->u.indication.choice)
  3432. break;
  3433. case REQUEST_CHOSEN: // Connection(control) PDU
  3434. switch(gcc_pdu->u.request.choice)
  3435. {
  3436. case CONFERENCE_JOIN_REQUEST_CHOSEN:
  3437. ProcessConferenceJoinRequestPDU(
  3438. &gcc_pdu->u.request.u.conference_join_request,
  3439. send_data_info);
  3440. break;
  3441. case CONFERENCE_TERMINATE_REQUEST_CHOSEN:
  3442. ProcessConferenceTerminateRequestPDU(
  3443. &gcc_pdu->u.request.u.
  3444. conference_terminate_request,
  3445. send_data_info);
  3446. break;
  3447. case CONFERENCE_EJECT_USER_REQUEST_CHOSEN:
  3448. ProcessConferenceEjectUserRequestPDU(
  3449. &gcc_pdu->u.request.u.
  3450. conference_eject_user_request,
  3451. send_data_info);
  3452. break;
  3453. case REGISTRY_ALLOCATE_HANDLE_REQUEST_CHOSEN:
  3454. ProcessRegistryAllocateHandleRequestPDU(
  3455. &gcc_pdu->u.request.u.
  3456. registry_allocate_handle_request,
  3457. send_data_info);
  3458. break;
  3459. case CONFERENCE_LOCK_REQUEST_CHOSEN:
  3460. m_pConf->ProcessConferenceLockRequest(initiator);
  3461. break;
  3462. case CONFERENCE_UNLOCK_REQUEST_CHOSEN:
  3463. m_pConf->ProcessConferenceUnlockRequest(initiator);
  3464. break;
  3465. case CONFERENCE_TRANSFER_REQUEST_CHOSEN:
  3466. ProcessTransferRequestPDU(
  3467. &gcc_pdu->u.request.u.conference_transfer_request,
  3468. send_data_info);
  3469. break;
  3470. case CONFERENCE_ADD_REQUEST_CHOSEN:
  3471. ProcessAddRequestPDU (
  3472. &gcc_pdu->u.request.u.conference_add_request,
  3473. send_data_info);
  3474. break;
  3475. case REGISTRY_REGISTER_CHANNEL_REQUEST_CHOSEN:
  3476. case REGISTRY_ASSIGN_TOKEN_REQUEST_CHOSEN:
  3477. case REGISTRY_SET_PARAMETER_REQUEST_CHOSEN:
  3478. case REGISTRY_DELETE_ENTRY_REQUEST_CHOSEN:
  3479. case REGISTRY_RETRIEVE_ENTRY_REQUEST_CHOSEN:
  3480. case REGISTRY_MONITOR_ENTRY_REQUEST_CHOSEN:
  3481. ProcessRegistryRequestPDU( gcc_pdu,
  3482. send_data_info);
  3483. break;
  3484. default:
  3485. ERROR_OUT(("User::ProcessSendDataIndication this pdu choice is not supported"));
  3486. break;
  3487. } // switch(gcc_pdu->u.request.choice)
  3488. break;
  3489. case RESPONSE_CHOSEN: // Connection(control) PDU
  3490. switch(gcc_pdu->u.response.choice)
  3491. {
  3492. case CONFERENCE_JOIN_RESPONSE_CHOSEN:
  3493. /* This comes from top provider to the intermediate
  3494. * gcc provider which has to pass it on to the node
  3495. * that made a join request.
  3496. */
  3497. ProcessConferenceJoinResponsePDU(
  3498. &gcc_pdu->u.response.u.
  3499. conference_join_response);
  3500. break;
  3501. case CONFERENCE_TERMINATE_RESPONSE_CHOSEN:
  3502. ProcessConferenceTerminateResponsePDU(
  3503. &gcc_pdu->u.response.u.
  3504. conference_terminate_response);
  3505. break;
  3506. case CONFERENCE_EJECT_USER_RESPONSE_CHOSEN:
  3507. ProcessConferenceEjectUserResponsePDU(
  3508. &gcc_pdu->u.response.u.
  3509. conference_eject_user_response);
  3510. break;
  3511. case REGISTRY_RESPONSE_CHOSEN:
  3512. ProcessRegistryResponsePDU(
  3513. &gcc_pdu->u.response.u.registry_response);
  3514. break;
  3515. case REGISTRY_ALLOCATE_HANDLE_RESPONSE_CHOSEN:
  3516. ProcessRegistryAllocateHandleResponsePDU(
  3517. &gcc_pdu->u.response.u.
  3518. registry_allocate_handle_response);
  3519. break;
  3520. case CONFERENCE_LOCK_RESPONSE_CHOSEN:
  3521. #ifdef JASPER
  3522. {
  3523. GCCResult result;
  3524. result = ::TranslateLockResultToGCCResult(gcc_pdu->u.response.u.conference_lock_response.result);
  3525. g_pControlSap->ConfLockConfirm(result, m_pConf->GetConfID());
  3526. }
  3527. #endif // JASPER
  3528. break;
  3529. case CONFERENCE_UNLOCK_RESPONSE_CHOSEN:
  3530. #ifdef JASPER
  3531. {
  3532. GCCResult result;
  3533. result = ::TranslateUnlockResultToGCCResult(gcc_pdu->u.response.u.conference_unlock_response.result);
  3534. g_pControlSap->ConfUnlockConfirm(result, m_pConf->GetConfID());
  3535. }
  3536. #endif // JASPER
  3537. break;
  3538. case CONFERENCE_TRANSFER_RESPONSE_CHOSEN:
  3539. #ifdef JASPER
  3540. ProcessTransferResponsePDU(
  3541. &gcc_pdu->u.response.u.conference_transfer_response);
  3542. #endif // JASPER
  3543. break;
  3544. case CONFERENCE_ADD_RESPONSE_CHOSEN:
  3545. ProcessAddResponsePDU(
  3546. &gcc_pdu->u.response.u.conference_add_response);
  3547. break;
  3548. case FUNCTION_NOT_SUPPORTED_RESPONSE_CHOSEN:
  3549. ProcessFunctionNotSupported (
  3550. (UINT) gcc_pdu->u.response.u.function_not_supported_response.request.choice);
  3551. break;
  3552. // other cases to be added as we go along.
  3553. default:
  3554. ERROR_OUT(("User::ProcessSendDataIndication this pdu choice is not supported"));
  3555. break;
  3556. } // switch(gcc_pdu->u.response.choice)
  3557. break;
  3558. default:
  3559. ERROR_OUT(("User::ProcessSendDataIndication this pdu type"));
  3560. break;
  3561. } // switch(gcc_pdu->choice)
  3562. packet->Unlock();
  3563. }
  3564. else
  3565. {
  3566. delete packet;
  3567. error_value = GCC_ALLOCATION_FAILURE;
  3568. }
  3569. if (error_value == GCC_ALLOCATION_FAILURE)
  3570. {
  3571. ResourceFailureHandler();
  3572. }
  3573. return(MCS_NO_ERROR);
  3574. }
  3575. /*
  3576. * void ProcessConferenceJoinRequestPDU ()
  3577. *
  3578. * Private Function Description:
  3579. * This PDU comes from below (intermediate directly connected node) to the
  3580. * top gcc provider. Pull out the tag number and user id from the
  3581. * pdu and store in a list.
  3582. *
  3583. * Formal Parameters:
  3584. * join_request - (i) Join request PDU structure to process.
  3585. * send_data_info - (i) Send data structure to process.
  3586. *
  3587. * Return Value
  3588. * None.
  3589. *
  3590. * Side Effects
  3591. * None.
  3592. *
  3593. * Caveats
  3594. * None.
  3595. */
  3596. void MCSUser::ProcessConferenceJoinRequestPDU(
  3597. PConferenceJoinRequest join_request,
  3598. PSendData send_data_info)
  3599. {
  3600. GCCError rc = GCC_NO_ERROR;
  3601. UserJoinRequestInfo join_request_info;
  3602. /*
  3603. ** Build all the containers to be used in the join request info structure.
  3604. */
  3605. // Build the convener password container
  3606. if ((join_request->bit_mask & CJRQ_CONVENER_PASSWORD_PRESENT) &&
  3607. (rc == GCC_NO_ERROR))
  3608. {
  3609. DBG_SAVE_FILE_LINE
  3610. join_request_info.convener_password = new CPassword(
  3611. &join_request->cjrq_convener_password,
  3612. &rc);
  3613. if (join_request_info.convener_password == NULL)
  3614. {
  3615. rc = GCC_ALLOCATION_FAILURE;
  3616. }
  3617. }
  3618. else
  3619. {
  3620. join_request_info.convener_password = NULL;
  3621. }
  3622. // Build the password challenge container
  3623. if ((join_request->bit_mask & CJRQ_PASSWORD_PRESENT) &&
  3624. (rc == GCC_NO_ERROR))
  3625. {
  3626. DBG_SAVE_FILE_LINE
  3627. join_request_info.password_challenge = new CPassword(
  3628. &join_request->cjrq_password,
  3629. &rc);
  3630. if (join_request_info.password_challenge == NULL)
  3631. {
  3632. rc = GCC_ALLOCATION_FAILURE;
  3633. }
  3634. }
  3635. else
  3636. {
  3637. join_request_info.password_challenge = NULL;
  3638. }
  3639. // Build the caller identifier container
  3640. if ((join_request->bit_mask & CJRQ_CALLER_ID_PRESENT) &&
  3641. (rc == GCC_NO_ERROR))
  3642. {
  3643. if (NULL == (join_request_info.pwszCallerID = ::My_strdupW2(
  3644. join_request->cjrq_caller_id.length,
  3645. join_request->cjrq_caller_id.value)))
  3646. {
  3647. rc = GCC_ALLOCATION_FAILURE;
  3648. }
  3649. }
  3650. else
  3651. {
  3652. join_request_info.pwszCallerID = NULL;
  3653. }
  3654. // Build the password challenge container
  3655. if ((join_request->bit_mask & CJRQ_USER_DATA_PRESENT) &&
  3656. (rc == GCC_NO_ERROR))
  3657. {
  3658. DBG_SAVE_FILE_LINE
  3659. join_request_info.user_data_list = new CUserDataListContainer(join_request->cjrq_user_data, &rc);
  3660. if (join_request_info.user_data_list == NULL)
  3661. {
  3662. rc = GCC_ALLOCATION_FAILURE;
  3663. }
  3664. }
  3665. else
  3666. {
  3667. join_request_info.user_data_list = NULL;
  3668. }
  3669. if (rc == GCC_NO_ERROR)
  3670. {
  3671. m_ConfJoinResponseList2.Append(send_data_info->initiator, join_request->tag);
  3672. join_request_info.sender_id = send_data_info->initiator;
  3673. g_pControlSap->ForwardedConfJoinIndication(
  3674. join_request_info.sender_id,
  3675. m_pConf->GetConfID(),
  3676. join_request_info.convener_password,
  3677. join_request_info.password_challenge,
  3678. join_request_info.pwszCallerID,
  3679. join_request_info.user_data_list);
  3680. }
  3681. // Free up the containers allocated above
  3682. if (join_request_info.convener_password != NULL)
  3683. {
  3684. join_request_info.convener_password->Release();
  3685. }
  3686. if (join_request_info.password_challenge != NULL)
  3687. {
  3688. join_request_info.password_challenge->Release();
  3689. }
  3690. delete join_request_info.pwszCallerID;
  3691. if (join_request_info.user_data_list != NULL)
  3692. {
  3693. join_request_info.user_data_list->Release();
  3694. }
  3695. if (rc == GCC_ALLOCATION_FAILURE)
  3696. {
  3697. ResourceFailureHandler();
  3698. }
  3699. }
  3700. /*
  3701. * void ProcessConferenceJoinResponsePDU ()
  3702. *
  3703. * Private Function Description:
  3704. * This comes from top provider to the intermediate gcc provider which has
  3705. * to pass it on to the node that made a join request.
  3706. *
  3707. * Formal Parameters:
  3708. * join_response - (i) Join response PDU structure to process.
  3709. *
  3710. * Return Value
  3711. * None.
  3712. *
  3713. * Side Effects
  3714. * None.
  3715. *
  3716. * Caveats
  3717. * None.
  3718. */
  3719. void MCSUser::ProcessConferenceJoinResponsePDU(
  3720. PConferenceJoinResponse join_response)
  3721. {
  3722. GCCError rc = GCC_NO_ERROR;
  3723. UserJoinResponseInfo join_response_info;
  3724. // Store the password data in the join response info structure
  3725. if ((join_response->bit_mask & CJRS_PASSWORD_PRESENT) &&
  3726. (rc == GCC_NO_ERROR))
  3727. {
  3728. DBG_SAVE_FILE_LINE
  3729. join_response_info.password_challenge = new CPassword(
  3730. &join_response->cjrs_password,
  3731. &rc);
  3732. if (join_response_info.password_challenge == NULL)
  3733. {
  3734. rc = GCC_NO_ERROR;
  3735. }
  3736. }
  3737. else
  3738. {
  3739. join_response_info.password_challenge = NULL;
  3740. }
  3741. // Store the user data in the join response info structure
  3742. if ((join_response->bit_mask & CJRS_USER_DATA_PRESENT) &&
  3743. (rc == GCC_NO_ERROR))
  3744. {
  3745. DBG_SAVE_FILE_LINE
  3746. join_response_info.user_data_list = new CUserDataListContainer(join_response->cjrs_user_data, &rc);
  3747. if (join_response_info.user_data_list == NULL)
  3748. {
  3749. rc = GCC_NO_ERROR;
  3750. }
  3751. }
  3752. else
  3753. {
  3754. join_response_info.user_data_list = NULL;
  3755. }
  3756. if (rc == GCC_NO_ERROR)
  3757. {
  3758. join_response_info.connection_handle = (ConnectionHandle)join_response->tag;
  3759. join_response_info.result = ::TranslateJoinResultToGCCResult(join_response->result);
  3760. m_pConf->ProcessConfJoinResponse(&join_response_info);
  3761. }
  3762. // Free up the containers allocated above
  3763. if (join_response_info.password_challenge != NULL)
  3764. join_response_info.password_challenge->Release();
  3765. if (join_response_info.user_data_list != NULL)
  3766. join_response_info.user_data_list->Release();
  3767. // Cleanup after any allocation failures.
  3768. if (rc == GCC_ALLOCATION_FAILURE)
  3769. {
  3770. ResourceFailureHandler();
  3771. }
  3772. }
  3773. /*
  3774. * void ProcessConferenceTerminateRequestPDU()
  3775. *
  3776. * Private Function Description:
  3777. * This routine is responsible for processing an incoming Conference
  3778. * Terminate Request PDU.
  3779. *
  3780. * Formal Parameters:
  3781. * terminate_request - (i) Terminate request PDU structure to process.
  3782. * send_data_info - (i) Send data structure to process.
  3783. *
  3784. * Return Value
  3785. * None.
  3786. *
  3787. * Side Effects
  3788. * None.
  3789. *
  3790. * Caveats
  3791. * None.
  3792. */
  3793. void MCSUser::
  3794. ProcessConferenceTerminateRequestPDU
  3795. (
  3796. PConferenceTerminateRequest terminate_request,
  3797. PSendData send_data_info
  3798. )
  3799. {
  3800. m_pConf->ProcessTerminateRequest(
  3801. send_data_info->initiator,
  3802. ::TranslateTerminateRqReasonToGCCReason(terminate_request->reason));
  3803. }
  3804. /*
  3805. * void ProcessConferenceEjectUserRequestPDU()
  3806. *
  3807. * Private Function Description:
  3808. * This routine is responsible for processing an incoming Conference
  3809. * eject user request PDU.
  3810. *
  3811. * Formal Parameters:
  3812. * eject_user_request - (i) Eject user request PDU structure to process.
  3813. * send_data_info - (i) Send data structure to process.
  3814. *
  3815. * Return Value
  3816. * None.
  3817. *
  3818. * Side Effects
  3819. * None.
  3820. *
  3821. * Caveats
  3822. * None.
  3823. */
  3824. void MCSUser::ProcessConferenceEjectUserRequestPDU(
  3825. PConferenceEjectUserRequest eject_user_request,
  3826. PSendData send_data_info)
  3827. {
  3828. UserEjectNodeRequestInfo eject_node_request;
  3829. eject_node_request.requester_id = send_data_info->initiator;
  3830. eject_node_request.node_to_eject = eject_user_request->node_to_eject;
  3831. eject_node_request.reason = GCC_REASON_NODE_EJECTED;
  3832. m_pConf->ProcessEjectUserRequest(&eject_node_request);
  3833. }
  3834. /*
  3835. * void ProcessConferenceTerminateResponsePDU()
  3836. *
  3837. * Private Function Description:
  3838. * This routine is responsible for processing an incoming Conference
  3839. * terminate response PDU.
  3840. *
  3841. * Formal Parameters:
  3842. * terminate_response - (i) Terminate response PDU structure to process.
  3843. *
  3844. * Return Value
  3845. * None.
  3846. *
  3847. * Side Effects
  3848. * None.
  3849. *
  3850. * Caveats
  3851. * None.
  3852. */
  3853. void MCSUser::ProcessConferenceTerminateResponsePDU(
  3854. PConferenceTerminateResponse terminate_response)
  3855. {
  3856. GCCResult result = ::TranslateTerminateResultToGCCResult(terminate_response->result);
  3857. //
  3858. // If the terminate was successful, go ahead and set the
  3859. // conference to not established.
  3860. //
  3861. if (result == GCC_RESULT_SUCCESSFUL)
  3862. {
  3863. m_pConf->ConfIsOver();
  3864. }
  3865. g_pControlSap->ConfTerminateConfirm(m_pConf->GetConfID(), result);
  3866. }
  3867. /*
  3868. * void ProcessConferenceEjectUserResponsePDU()
  3869. *
  3870. * Private Function Description:
  3871. * This routine is responsible for processing an incoming Conference
  3872. * Eject User response PDU.
  3873. *
  3874. * Formal Parameters:
  3875. * eject_user_response - (i) Eject user response PDU structure to
  3876. * process.
  3877. *
  3878. * Return Value
  3879. * None.
  3880. *
  3881. * Side Effects
  3882. * None.
  3883. *
  3884. * Caveats
  3885. * None.
  3886. */
  3887. void MCSUser::ProcessConferenceEjectUserResponsePDU(
  3888. PConferenceEjectUserResponse eject_user_response)
  3889. {
  3890. UserEjectNodeResponseInfo eject_node_response;
  3891. eject_node_response.node_to_eject = eject_user_response->node_to_eject;
  3892. eject_node_response.result = ::TranslateEjectResultToGCCResult(
  3893. eject_user_response->result);
  3894. m_pConf->ProcessEjectUserResponse(&eject_node_response);
  3895. }
  3896. /*
  3897. * void ProcessRegistryRequest()
  3898. *
  3899. * Private Function Description:
  3900. * This routine is responsible for processing an incoming Registry
  3901. * request PDU.
  3902. *
  3903. * Formal Parameters:
  3904. * gcc_pdu - (i) This is the PDU structure to process.
  3905. * send_data_info - (i) Send data structure to process.
  3906. *
  3907. * Return Value
  3908. * None.
  3909. *
  3910. * Side Effects
  3911. * None.
  3912. *
  3913. * Caveats
  3914. * None.
  3915. */
  3916. void MCSUser::
  3917. ProcessRegistryRequestPDU
  3918. (
  3919. PGCCPDU gcc_pdu,
  3920. PSendData send_data_info
  3921. )
  3922. {
  3923. CRegistry *pAppReg = m_pConf->GetRegistry();
  3924. if (NULL != pAppReg)
  3925. {
  3926. GCCError rc = GCC_ALLOCATION_FAILURE;
  3927. CRegKeyContainer *pRegKey = NULL;
  3928. switch (gcc_pdu->u.request.choice)
  3929. {
  3930. case REGISTRY_REGISTER_CHANNEL_REQUEST_CHOSEN:
  3931. DBG_SAVE_FILE_LINE
  3932. pRegKey = new CRegKeyContainer(
  3933. &gcc_pdu->u.request.u.registry_register_channel_request.key,
  3934. &rc);
  3935. if ((pRegKey != NULL) && (rc == GCC_NO_ERROR))
  3936. {
  3937. pAppReg->ProcessRegisterChannelPDU(
  3938. pRegKey,
  3939. gcc_pdu->u.request.u.registry_register_channel_request.channel_id,
  3940. send_data_info->initiator, // Requester node id
  3941. gcc_pdu->u.request.u.registry_register_channel_request.entity_id);
  3942. }
  3943. else
  3944. {
  3945. // rc = GCC_ALLOCATION_FAILURE;
  3946. }
  3947. break;
  3948. case REGISTRY_ASSIGN_TOKEN_REQUEST_CHOSEN:
  3949. DBG_SAVE_FILE_LINE
  3950. pRegKey = new CRegKeyContainer(
  3951. &gcc_pdu->u.request.u.registry_assign_token_request.registry_key,
  3952. &rc);
  3953. if ((pRegKey != NULL) && (rc == GCC_NO_ERROR))
  3954. {
  3955. pAppReg->ProcessAssignTokenPDU(
  3956. pRegKey,
  3957. send_data_info->initiator, // Requester node id
  3958. gcc_pdu->u.request.u.registry_assign_token_request.entity_id);
  3959. }
  3960. else
  3961. {
  3962. // rc = GCC_ALLOCATION_FAILURE;
  3963. }
  3964. break;
  3965. case REGISTRY_SET_PARAMETER_REQUEST_CHOSEN:
  3966. DBG_SAVE_FILE_LINE
  3967. pRegKey = new CRegKeyContainer(
  3968. &gcc_pdu->u.request.u.registry_set_parameter_request.key,
  3969. &rc);
  3970. if ((pRegKey != NULL) && (rc == GCC_NO_ERROR))
  3971. {
  3972. OSTR oszParamValue;
  3973. LPOSTR poszParamValue;
  3974. GCCModificationRights eRights;
  3975. if (gcc_pdu->u.request.u.registry_set_parameter_request.
  3976. registry_set_parameter.length != 0)
  3977. {
  3978. poszParamValue = &oszParamValue;
  3979. oszParamValue.length = gcc_pdu->u.request.u.registry_set_parameter_request.
  3980. registry_set_parameter.length;
  3981. oszParamValue.value = gcc_pdu->u.request.u.registry_set_parameter_request.
  3982. registry_set_parameter.value;
  3983. }
  3984. else
  3985. {
  3986. poszParamValue = NULL;
  3987. }
  3988. if (gcc_pdu->u.request.u.registry_set_parameter_request.
  3989. bit_mask & PARAMETER_MODIFY_RIGHTS_PRESENT)
  3990. {
  3991. eRights = (GCCModificationRights)gcc_pdu->u.request.u.
  3992. registry_set_parameter_request.parameter_modify_rights;
  3993. }
  3994. else
  3995. {
  3996. eRights = GCC_NO_MODIFICATION_RIGHTS_SPECIFIED;
  3997. }
  3998. pAppReg->ProcessSetParameterPDU(
  3999. pRegKey,
  4000. poszParamValue,
  4001. eRights,
  4002. send_data_info->initiator, // Requester node id
  4003. gcc_pdu->u.request.u.registry_set_parameter_request.entity_id);
  4004. }
  4005. else
  4006. {
  4007. // rc = GCC_ALLOCATION_FAILURE;
  4008. }
  4009. break;
  4010. case REGISTRY_RETRIEVE_ENTRY_REQUEST_CHOSEN:
  4011. DBG_SAVE_FILE_LINE
  4012. pRegKey = new CRegKeyContainer(
  4013. &gcc_pdu->u.request.u.registry_retrieve_entry_request.key,
  4014. &rc);
  4015. if ((pRegKey != NULL) && (rc == GCC_NO_ERROR))
  4016. {
  4017. pAppReg->ProcessRetrieveEntryPDU(
  4018. pRegKey,
  4019. send_data_info->initiator, // Requester node id
  4020. gcc_pdu->u.request.u.registry_retrieve_entry_request.entity_id);
  4021. }
  4022. else
  4023. {
  4024. // rc = GCC_ALLOCATION_FAILURE;
  4025. }
  4026. break;
  4027. case REGISTRY_DELETE_ENTRY_REQUEST_CHOSEN:
  4028. DBG_SAVE_FILE_LINE
  4029. pRegKey = new CRegKeyContainer(
  4030. &gcc_pdu->u.request.u.registry_delete_entry_request.key,
  4031. &rc);
  4032. if ((pRegKey != NULL) && (rc == GCC_NO_ERROR))
  4033. {
  4034. pAppReg->ProcessDeleteEntryPDU (
  4035. pRegKey,
  4036. send_data_info->initiator, // Requester node id
  4037. gcc_pdu->u.request.u.registry_delete_entry_request.entity_id);
  4038. }
  4039. else
  4040. {
  4041. // rc = GCC_ALLOCATION_FAILURE;
  4042. }
  4043. break;
  4044. case REGISTRY_MONITOR_ENTRY_REQUEST_CHOSEN:
  4045. DBG_SAVE_FILE_LINE
  4046. pRegKey = new CRegKeyContainer(
  4047. &gcc_pdu->u.request.u.registry_monitor_entry_request.key,
  4048. &rc);
  4049. if ((pRegKey != NULL) && (rc == GCC_NO_ERROR))
  4050. {
  4051. pAppReg->ProcessMonitorEntryPDU(
  4052. pRegKey,
  4053. send_data_info->initiator, // Requester node id
  4054. gcc_pdu->u.request.u.registry_monitor_entry_request.entity_id);
  4055. }
  4056. else
  4057. {
  4058. // rc = GCC_ALLOCATION_FAILURE;
  4059. }
  4060. break;
  4061. }
  4062. if (NULL != pRegKey)
  4063. {
  4064. pRegKey->Release();
  4065. }
  4066. // Handle resource errors
  4067. if (rc == GCC_ALLOCATION_FAILURE)
  4068. {
  4069. ResourceFailureHandler();
  4070. }
  4071. } // if pAppReg != NULL
  4072. }
  4073. /*
  4074. * void ProcessRegistryAllocateHandleRequestPDU()
  4075. *
  4076. * Private Function Description:
  4077. * This routine is responsible for processing an incoming Allocate
  4078. * Handle request PDU.
  4079. *
  4080. * Formal Parameters:
  4081. * allocate_handle_request - (i) This is the PDU structure to process.
  4082. * send_data_info - (i) Send data structure to process.
  4083. *
  4084. * Return Value
  4085. * None.
  4086. *
  4087. * Side Effects
  4088. * None.
  4089. *
  4090. * Caveats
  4091. * None.
  4092. */
  4093. void MCSUser::
  4094. ProcessRegistryAllocateHandleRequestPDU
  4095. (
  4096. PRegistryAllocateHandleRequest allocate_handle_request,
  4097. PSendData send_data_info
  4098. )
  4099. {
  4100. CRegistry *pAppReg = m_pConf->GetRegistry();
  4101. if (NULL != pAppReg)
  4102. {
  4103. pAppReg->ProcessAllocateHandleRequestPDU(
  4104. allocate_handle_request->number_of_handles,
  4105. allocate_handle_request->entity_id,
  4106. send_data_info->initiator);
  4107. }
  4108. }
  4109. /*
  4110. * void ProcessRegistryResponsePDU()
  4111. *
  4112. * Private Function Description:
  4113. * This routine is responsible for processing an incoming Registry
  4114. * Response PDU.
  4115. *
  4116. * Formal Parameters:
  4117. * registry_response - (i) This is the PDU structure to process.
  4118. *
  4119. * Return Value
  4120. * None.
  4121. *
  4122. * Side Effects
  4123. * None.
  4124. *
  4125. * Caveats
  4126. * None.
  4127. */
  4128. void MCSUser::
  4129. ProcessRegistryResponsePDU ( PRegistryResponse registry_response )
  4130. {
  4131. CRegistry *pAppReg = m_pConf->GetRegistry();
  4132. if (NULL != pAppReg)
  4133. {
  4134. GCCError rc;
  4135. UserRegistryResponseInfo urri;
  4136. ::ZeroMemory(&urri, sizeof(urri));
  4137. // urri.registry_key = NULL;
  4138. // urri.registry_item = NULL;
  4139. DBG_SAVE_FILE_LINE
  4140. urri.registry_key = new CRegKeyContainer(&registry_response->key, &rc);
  4141. if ((urri.registry_key != NULL) && (rc == GCC_NO_ERROR))
  4142. {
  4143. DBG_SAVE_FILE_LINE
  4144. urri.registry_item = new CRegItem(&registry_response->item, &rc);
  4145. if ((urri.registry_item != NULL) && (rc == GCC_NO_ERROR))
  4146. {
  4147. // Set up the original requester entity id
  4148. urri.requester_entity_id = registry_response->entity_id;
  4149. // Set up the primitive type being responded to
  4150. urri.primitive_type = registry_response->primitive_type;
  4151. // Set up the owner related variables
  4152. if (registry_response->owner.choice == OWNED_CHOSEN)
  4153. {
  4154. urri.owner_node_id = registry_response->owner.u.owned.node_id;
  4155. urri.owner_entity_id = registry_response->owner.u.owned.entity_id;
  4156. }
  4157. else
  4158. {
  4159. // urri.owner_node_id = 0;
  4160. // urri.owner_entity_id = 0;
  4161. }
  4162. // Set up the modification rights
  4163. if (registry_response->bit_mask & RESPONSE_MODIFY_RIGHTS_PRESENT)
  4164. {
  4165. urri.modification_rights = (GCCModificationRights)registry_response->response_modify_rights;
  4166. }
  4167. else
  4168. {
  4169. urri.modification_rights = GCC_NO_MODIFICATION_RIGHTS_SPECIFIED;
  4170. }
  4171. // Translate the result to a GCC result
  4172. urri.result = ::TranslateRegistryRespToGCCResult(registry_response->result);
  4173. pAppReg->ProcessRegistryResponsePDU(
  4174. urri.primitive_type,
  4175. urri.registry_key,
  4176. urri.registry_item,
  4177. urri.modification_rights,
  4178. urri.requester_entity_id,
  4179. urri.owner_node_id,
  4180. urri.owner_entity_id,
  4181. urri.result);
  4182. }
  4183. else
  4184. {
  4185. rc = GCC_ALLOCATION_FAILURE;
  4186. }
  4187. }
  4188. else
  4189. {
  4190. rc = GCC_ALLOCATION_FAILURE;
  4191. }
  4192. if (NULL != urri.registry_key)
  4193. {
  4194. urri.registry_key->Release();
  4195. }
  4196. if (NULL != urri.registry_item)
  4197. {
  4198. urri.registry_item->Release();
  4199. }
  4200. // Handle any resource errors
  4201. if (rc == GCC_ALLOCATION_FAILURE)
  4202. {
  4203. ResourceFailureHandler();
  4204. }
  4205. } // if pAppReg != NULL
  4206. }
  4207. /*
  4208. * void ProcessAllocateHandleResponsePDU()
  4209. *
  4210. * Private Function Description:
  4211. * This routine is responsible for processing an incoming Allocate
  4212. * Handle Response PDU.
  4213. *
  4214. * Formal Parameters:
  4215. * allocate_handle_response- (i) This is the PDU structure to process.
  4216. *
  4217. * Return Value
  4218. * None.
  4219. *
  4220. * Side Effects
  4221. * None.
  4222. *
  4223. * Caveats
  4224. * None.
  4225. */
  4226. void MCSUser::
  4227. ProcessRegistryAllocateHandleResponsePDU
  4228. (
  4229. PRegistryAllocateHandleResponse allocate_handle_response
  4230. )
  4231. {
  4232. CRegistry *pAppReg = m_pConf->GetRegistry();
  4233. if (NULL != pAppReg)
  4234. {
  4235. pAppReg->ProcessAllocateHandleResponsePDU(
  4236. allocate_handle_response->number_of_handles,
  4237. allocate_handle_response->first_handle,
  4238. allocate_handle_response->entity_id,
  4239. (allocate_handle_response->result == RARS_RESULT_SUCCESS) ?
  4240. GCC_RESULT_SUCCESSFUL :
  4241. GCC_RESULT_NO_HANDLES_AVAILABLE);
  4242. }
  4243. }
  4244. /*
  4245. * void ProcessTransferRequestPDU()
  4246. *
  4247. * Private Function Description:
  4248. * This routine is responsible for processing an incoming Transfer
  4249. * request PDU.
  4250. *
  4251. * Formal Parameters:
  4252. * transfer_request - (i) This is the PDU structure to process.
  4253. * send_data_info - (i) Send data structure to process.
  4254. *
  4255. * Return Value
  4256. * None.
  4257. *
  4258. * Side Effects
  4259. * None.
  4260. *
  4261. * Caveats
  4262. * None.
  4263. */
  4264. void MCSUser::
  4265. ProcessTransferRequestPDU
  4266. (
  4267. PConferenceTransferRequest transfer_request,
  4268. PSendData send_data_info
  4269. )
  4270. {
  4271. GCCError rc = GCC_NO_ERROR;
  4272. TransferInfo transfer_info;
  4273. PSetOfTransferringNodesRq set_of_nodes;
  4274. LPBYTE sub_node_list_memory = NULL;
  4275. Int i;
  4276. // Make sure that this node is the top provider
  4277. if (GetMyNodeID() != GetTopNodeID())
  4278. return;
  4279. ::ZeroMemory(&transfer_info, sizeof(transfer_info));
  4280. // First set up the conference name
  4281. if (transfer_request->conference_name.choice ==
  4282. NAME_SELECTOR_NUMERIC_CHOSEN)
  4283. {
  4284. transfer_info.destination_conference_name.numeric_string =
  4285. (LPSTR) transfer_request->conference_name.u.name_selector_numeric;
  4286. // transfer_info.destination_conference_name.text_string = NULL;
  4287. }
  4288. else
  4289. {
  4290. // transfer_info.destination_conference_name.numeric_string = NULL;
  4291. if (NULL == (transfer_info.destination_conference_name.text_string = ::My_strdupW2(
  4292. transfer_request->conference_name.u.name_selector_text.length,
  4293. transfer_request->conference_name.u.name_selector_text.value)))
  4294. {
  4295. rc = GCC_ALLOCATION_FAILURE;
  4296. }
  4297. }
  4298. // Next set up the conference name modifier
  4299. if (transfer_request->bit_mask & CTRQ_CONFERENCE_MODIFIER_PRESENT)
  4300. {
  4301. transfer_info.destination_conference_modifier =
  4302. (LPSTR) transfer_request->ctrq_conference_modifier;
  4303. }
  4304. else
  4305. {
  4306. // transfer_info.destination_conference_modifier = NULL;
  4307. }
  4308. // Next set up the network address
  4309. if (transfer_request->bit_mask & CTRQ_NETWORK_ADDRESS_PRESENT)
  4310. {
  4311. DBG_SAVE_FILE_LINE
  4312. transfer_info.destination_address_list = new CNetAddrListContainer(
  4313. transfer_request->ctrq_net_address,
  4314. &rc);
  4315. if (transfer_info.destination_address_list == NULL)
  4316. {
  4317. rc = GCC_ALLOCATION_FAILURE;
  4318. }
  4319. }
  4320. else
  4321. {
  4322. // transfer_info.destination_address_list = NULL;
  4323. }
  4324. // Set up the transferring nodes list
  4325. if (transfer_request->bit_mask & CTRQ_TRANSFERRING_NODES_PRESENT)
  4326. {
  4327. // First determine the number of nodes.
  4328. set_of_nodes = transfer_request->ctrq_transferring_nodes;
  4329. // transfer_info.number_of_destination_nodes = 0;
  4330. while (set_of_nodes != NULL)
  4331. {
  4332. transfer_info.number_of_destination_nodes++;
  4333. set_of_nodes = set_of_nodes->next;
  4334. }
  4335. // Next allocate the memory required to hold the sub nodes
  4336. DBG_SAVE_FILE_LINE
  4337. sub_node_list_memory = new BYTE[sizeof(UserID) * transfer_info.number_of_destination_nodes];
  4338. // Now fill in the permission list
  4339. if (sub_node_list_memory != NULL)
  4340. {
  4341. transfer_info.destination_node_list = (PUserID) sub_node_list_memory;
  4342. set_of_nodes = transfer_request->ctrq_transferring_nodes;
  4343. for (i = 0; i < transfer_info.number_of_destination_nodes; i++)
  4344. {
  4345. transfer_info.destination_node_list[i] = set_of_nodes->value;
  4346. set_of_nodes = set_of_nodes->next;
  4347. }
  4348. }
  4349. else
  4350. {
  4351. ERROR_OUT(("MCSUser: ProcessTransferRequestPDU: Memory Manager Alloc Failure"));
  4352. rc = GCC_ALLOCATION_FAILURE;
  4353. }
  4354. }
  4355. else
  4356. {
  4357. // transfer_info.number_of_destination_nodes = 0;
  4358. // transfer_info.destination_node_list = NULL;
  4359. }
  4360. // Set up the password
  4361. if (transfer_request->bit_mask & CTRQ_PASSWORD_PRESENT)
  4362. {
  4363. DBG_SAVE_FILE_LINE
  4364. transfer_info.password = new CPassword(&transfer_request->ctrq_password, &rc);
  4365. if (transfer_info.password == NULL)
  4366. {
  4367. rc = GCC_ALLOCATION_FAILURE;
  4368. }
  4369. }
  4370. else
  4371. {
  4372. // transfer_info.password = NULL;
  4373. }
  4374. // Save the sender ID
  4375. transfer_info.requesting_node_id = send_data_info->initiator;
  4376. if (rc == GCC_NO_ERROR)
  4377. {
  4378. m_pConf->ProcessConferenceTransferRequest(
  4379. transfer_info.requesting_node_id,
  4380. &transfer_info.destination_conference_name,
  4381. transfer_info.destination_conference_modifier,
  4382. transfer_info.destination_address_list,
  4383. transfer_info.number_of_destination_nodes,
  4384. transfer_info.destination_node_list,
  4385. transfer_info.password);
  4386. }
  4387. else
  4388. {
  4389. ERROR_OUT(("MCSUser::ProcessTransferRequestPDU: Allocation Failure"));
  4390. if (GCC_ALLOCATION_FAILURE == rc)
  4391. {
  4392. ResourceFailureHandler();
  4393. }
  4394. }
  4395. // Now cleanup any allocated memory
  4396. if (transfer_info.destination_address_list != NULL)
  4397. {
  4398. transfer_info.destination_address_list->Release();
  4399. }
  4400. delete [] sub_node_list_memory;
  4401. if (transfer_info.password != NULL)
  4402. {
  4403. transfer_info.password->Release();
  4404. }
  4405. }
  4406. /*
  4407. * void ProcessAddRequestPDU ()
  4408. *
  4409. * Private Function Description:
  4410. * This routine is responsible for processing an incoming Conference Add
  4411. * request PDU.
  4412. *
  4413. * Formal Parameters:
  4414. * conference_add_request - (i) This is the PDU structure to process.
  4415. * send_data_info - (i) Send data structure to process.
  4416. *
  4417. * Return Value
  4418. * None.
  4419. *
  4420. * Side Effects
  4421. * None.
  4422. *
  4423. * Caveats
  4424. * None.
  4425. */
  4426. void MCSUser::ProcessAddRequestPDU (
  4427. PConferenceAddRequest conference_add_request,
  4428. PSendData send_data_info)
  4429. {
  4430. GCCError rc = GCC_NO_ERROR;
  4431. AddRequestInfo add_request_info;
  4432. /*
  4433. ** Ignore this request if this node is NOT the Top Provider and the request
  4434. ** did not come from the Top Provider.
  4435. */
  4436. if (m_nidTopProvider != m_nidMyself)
  4437. {
  4438. if (m_nidTopProvider != send_data_info->initiator)
  4439. return;
  4440. }
  4441. ::ZeroMemory(&add_request_info, sizeof(add_request_info));
  4442. DBG_SAVE_FILE_LINE
  4443. add_request_info.network_address_list = new CNetAddrListContainer(
  4444. conference_add_request->add_request_net_address,
  4445. &rc);
  4446. if (add_request_info.network_address_list == NULL)
  4447. {
  4448. rc = GCC_ALLOCATION_FAILURE;
  4449. }
  4450. if ((rc == GCC_NO_ERROR) &&
  4451. (conference_add_request->bit_mask & CARQ_USER_DATA_PRESENT))
  4452. {
  4453. DBG_SAVE_FILE_LINE
  4454. add_request_info.user_data_list = new CUserDataListContainer(conference_add_request->carq_user_data, &rc);
  4455. if (add_request_info.user_data_list == NULL)
  4456. {
  4457. rc = GCC_ALLOCATION_FAILURE;
  4458. }
  4459. }
  4460. else
  4461. {
  4462. // add_request_info.user_data_list = NULL;
  4463. }
  4464. if (rc == GCC_NO_ERROR)
  4465. {
  4466. add_request_info.adding_node = (conference_add_request->bit_mask & ADDING_MCU_PRESENT) ?
  4467. conference_add_request->adding_mcu : 0;
  4468. add_request_info.requesting_node = conference_add_request->requesting_node;
  4469. add_request_info.add_request_tag = (TagNumber)conference_add_request->tag;
  4470. m_pConf->ProcessConferenceAddRequest(
  4471. add_request_info.network_address_list,
  4472. add_request_info.user_data_list,
  4473. add_request_info.adding_node,
  4474. add_request_info.add_request_tag,
  4475. add_request_info.requesting_node);
  4476. }
  4477. else
  4478. {
  4479. ERROR_OUT(("MCSUser::ProcessAddRequestPDU: Allocation Failure"));
  4480. if (GCC_ALLOCATION_FAILURE == rc)
  4481. {
  4482. ResourceFailureHandler();
  4483. }
  4484. }
  4485. if (add_request_info.network_address_list != NULL)
  4486. {
  4487. add_request_info.network_address_list->Release();
  4488. }
  4489. if (add_request_info.user_data_list != NULL)
  4490. {
  4491. add_request_info.user_data_list->Release();
  4492. }
  4493. }
  4494. /*
  4495. * void ProcessTransferResponsePDU()
  4496. *
  4497. * Private Function Description:
  4498. * This routine is responsible for processing an incoming Conference
  4499. * Transfer response PDU.
  4500. *
  4501. * Formal Parameters:
  4502. * transfer_response - (i) This is the PDU structure to process.
  4503. *
  4504. * Return Value
  4505. * None.
  4506. *
  4507. * Side Effects
  4508. * None.
  4509. *
  4510. * Caveats
  4511. * None.
  4512. */
  4513. #ifdef JASPER
  4514. void MCSUser::ProcessTransferResponsePDU (
  4515. PConferenceTransferResponse transfer_response)
  4516. {
  4517. GCCError rc = GCC_NO_ERROR;
  4518. TransferInfo transfer_info;
  4519. PSetOfTransferringNodesRs set_of_nodes;
  4520. LPBYTE sub_node_list_memory = NULL;
  4521. Int i;
  4522. ::ZeroMemory(&transfer_info, sizeof(transfer_info));
  4523. // First set up the conference name
  4524. if (transfer_response->conference_name.choice ==
  4525. NAME_SELECTOR_NUMERIC_CHOSEN)
  4526. {
  4527. transfer_info.destination_conference_name.numeric_string =
  4528. (LPSTR) transfer_response->conference_name.u.name_selector_numeric;
  4529. // transfer_info.destination_conference_name.text_string = NULL;
  4530. }
  4531. else
  4532. {
  4533. // transfer_info.destination_conference_name.numeric_string = NULL;
  4534. if (NULL == (transfer_info.destination_conference_name.text_string = ::My_strdupW2(
  4535. transfer_response->conference_name.u.name_selector_text.length,
  4536. transfer_response->conference_name.u.name_selector_text.value)))
  4537. {
  4538. rc = GCC_ALLOCATION_FAILURE;
  4539. }
  4540. }
  4541. // Next set up the conference name modifier
  4542. if (transfer_response->bit_mask & CTRS_CONFERENCE_MODIFIER_PRESENT)
  4543. {
  4544. transfer_info.destination_conference_modifier =
  4545. (LPSTR) transfer_response->ctrs_conference_modifier;
  4546. }
  4547. else
  4548. {
  4549. // transfer_info.destination_conference_modifier = NULL;
  4550. }
  4551. // Set up the transferring nodes list
  4552. if (transfer_response->bit_mask & CTRS_TRANSFERRING_NODES_PRESENT)
  4553. {
  4554. // First determine the number of nodes.
  4555. set_of_nodes = transfer_response->ctrs_transferring_nodes;
  4556. // transfer_info.number_of_destination_nodes = 0;
  4557. while (set_of_nodes != NULL)
  4558. {
  4559. transfer_info.number_of_destination_nodes++;
  4560. set_of_nodes = set_of_nodes->next;
  4561. }
  4562. // Next allocate the memory required to hold the sub nodes
  4563. DBG_SAVE_FILE_LINE
  4564. sub_node_list_memory = new BYTE[sizeof(UserID) * transfer_info.number_of_destination_nodes];
  4565. // Now fill in the permission list
  4566. if (sub_node_list_memory != NULL)
  4567. {
  4568. transfer_info.destination_node_list = (PUserID) sub_node_list_memory;
  4569. set_of_nodes = transfer_response->ctrs_transferring_nodes;
  4570. for (i = 0; i < transfer_info.number_of_destination_nodes; i++)
  4571. {
  4572. transfer_info.destination_node_list[i] = set_of_nodes->value;
  4573. set_of_nodes = set_of_nodes->next;
  4574. }
  4575. }
  4576. else
  4577. {
  4578. ERROR_OUT(("MCSUser: ProcessTransferResponsePDU: Memory Manager Alloc Failure"));
  4579. rc = GCC_ALLOCATION_FAILURE;
  4580. }
  4581. }
  4582. else
  4583. {
  4584. // transfer_info.number_of_destination_nodes = 0;
  4585. // transfer_info.destination_node_list = NULL;
  4586. }
  4587. // Save the result
  4588. transfer_info.result = (transfer_response->result == CTRANS_RESULT_SUCCESS) ?
  4589. GCC_RESULT_SUCCESSFUL :
  4590. GCC_RESULT_INVALID_REQUESTER;
  4591. if (rc == GCC_NO_ERROR)
  4592. {
  4593. g_pControlSap->ConfTransferConfirm(
  4594. m_pConf->GetConfID(),
  4595. &transfer_info.destination_conference_name,
  4596. transfer_info.destination_conference_modifier,
  4597. transfer_info.number_of_destination_nodes,
  4598. transfer_info.destination_node_list,
  4599. transfer_info.result);
  4600. }
  4601. else
  4602. {
  4603. ERROR_OUT(("MCSUser::ProcessTransferResponsePDU: Allocation Failure"));
  4604. if (GCC_ALLOCATION_FAILURE == rc)
  4605. {
  4606. ResourceFailureHandler();
  4607. }
  4608. }
  4609. // Now cleanup any allocated memory
  4610. delete sub_node_list_memory;
  4611. }
  4612. #endif // JASPER
  4613. /*
  4614. * void ProcessAddResponsePDU ()
  4615. *
  4616. * Private Function Description:
  4617. * This routine is responsible for processing an incoming Conference
  4618. * Add response PDU.
  4619. *
  4620. * Formal Parameters:
  4621. * conference_add_response - (i) This is the PDU structure to process.
  4622. *
  4623. * Return Value
  4624. * None.
  4625. *
  4626. * Side Effects
  4627. * None.
  4628. *
  4629. * Caveats
  4630. * None.
  4631. */
  4632. void MCSUser::ProcessAddResponsePDU (
  4633. PConferenceAddResponse conference_add_response)
  4634. {
  4635. GCCError error_value = GCC_NO_ERROR;
  4636. AddResponseInfo add_response_info;
  4637. if (conference_add_response->bit_mask & CARS_USER_DATA_PRESENT)
  4638. {
  4639. DBG_SAVE_FILE_LINE
  4640. add_response_info.user_data_list = new CUserDataListContainer(conference_add_response->cars_user_data, &error_value);
  4641. if (add_response_info.user_data_list == NULL)
  4642. {
  4643. error_value = GCC_ALLOCATION_FAILURE;
  4644. }
  4645. }
  4646. else
  4647. {
  4648. add_response_info.user_data_list = NULL;
  4649. }
  4650. if (error_value == GCC_NO_ERROR)
  4651. {
  4652. add_response_info.add_request_tag = (TagNumber)conference_add_response->tag;
  4653. add_response_info.result = ::TranslateAddResultToGCCResult(conference_add_response->result);
  4654. m_pConf->ProcessConfAddResponse(&add_response_info);
  4655. }
  4656. else
  4657. {
  4658. ERROR_OUT(("MCSUser::ProcessAddResponsePDU: Allocation Failure"));
  4659. if (GCC_ALLOCATION_FAILURE == error_value)
  4660. {
  4661. ResourceFailureHandler();
  4662. }
  4663. }
  4664. if (add_response_info.user_data_list != NULL)
  4665. {
  4666. add_response_info.user_data_list->Release();
  4667. }
  4668. }
  4669. /*
  4670. * void ProcessFunctionNotSupported ()
  4671. *
  4672. * Private Function Description:
  4673. * This routine is responsible for processing responses for request that
  4674. * are not supported at the node that the request was directed toward.
  4675. *
  4676. * Formal Parameters:
  4677. * request_choice - (i) This is the request that is not supported.
  4678. *
  4679. * Return Value
  4680. * None.
  4681. *
  4682. * Side Effects
  4683. * None.
  4684. *
  4685. * Caveats
  4686. * The existance of this routine does not mean that this provider does
  4687. * not support it. It only means that the node which received the
  4688. * request does not support it.
  4689. */
  4690. void MCSUser::
  4691. ProcessFunctionNotSupported ( UINT request_choice )
  4692. {
  4693. switch (request_choice)
  4694. {
  4695. case CONFERENCE_LOCK_REQUEST_CHOSEN:
  4696. #ifdef JASPER
  4697. g_pControlSap->ConfLockConfirm(GCC_RESULT_LOCKED_NOT_SUPPORTED, m_pConf->GetConfID());
  4698. #endif // JASPER
  4699. break;
  4700. case CONFERENCE_UNLOCK_REQUEST_CHOSEN:
  4701. #ifdef JASPER
  4702. g_pControlSap->ConfUnlockConfirm(GCC_RESULT_UNLOCK_NOT_SUPPORTED, m_pConf->GetConfID());
  4703. #endif // JASPER
  4704. break;
  4705. default:
  4706. ERROR_OUT(("MCSUser: ProcessFunctionNotSupported: "
  4707. "Error: Illegal request is unsupported"));
  4708. break;
  4709. }
  4710. }
  4711. /*
  4712. * UINT ProcessUniformSendDataIndication ()
  4713. *
  4714. * Private Function Description:
  4715. * This function is called when the user object gets send data indications
  4716. * from below. It finds out the message type and decodes the pdu in the
  4717. * user data field of send data indications. Based on the type of decoded
  4718. * pdu it take the necessary actions.
  4719. * This routine is responsible for processing responses for request that
  4720. * are not supported at the node that the request was directed toward.
  4721. *
  4722. * Formal Parameters:
  4723. * send_data_info - (i) This is the MCS data structure to process.
  4724. *
  4725. * Return Value
  4726. * MCS_NO_ERROR is always returned.
  4727. *
  4728. * Side Effects
  4729. * None.
  4730. *
  4731. * Caveats
  4732. * None.
  4733. */
  4734. UINT MCSUser::ProcessUniformSendDataIndication(
  4735. PSendData send_data_info)
  4736. {
  4737. PPacket packet;
  4738. PacketError packet_error;
  4739. PGCCPDU gcc_pdu;
  4740. GCCError error_value = GCC_NO_ERROR;
  4741. UserID initiator;
  4742. TRACE_OUT(("User: UniformSendDataInd: length = %d",
  4743. send_data_info->user_data.length));
  4744. DBG_SAVE_FILE_LINE
  4745. packet = new Packet((PPacketCoder) g_GCCCoder,
  4746. PACKED_ENCODING_RULES,
  4747. (LPBYTE)send_data_info->user_data.value,
  4748. send_data_info->user_data.length,
  4749. GCC_PDU,
  4750. TRUE,
  4751. &packet_error);
  4752. if((packet != NULL) && (packet_error == PACKET_NO_ERROR))
  4753. {
  4754. initiator = send_data_info->initiator;
  4755. gcc_pdu = (PGCCPDU)packet->GetDecodedData();
  4756. switch (gcc_pdu->choice)
  4757. {
  4758. case INDICATION_CHOSEN: // Data PDU
  4759. switch(gcc_pdu->u.indication.choice)
  4760. {
  4761. case CONFERENCE_TERMINATE_INDICATION_CHOSEN:
  4762. /*
  4763. ** Note that we allow the top provider to process
  4764. ** this message so that it can set up its own
  4765. ** node for termination in a generic way.
  4766. */
  4767. ProcessConferenceTerminateIndicationPDU (
  4768. &gcc_pdu->u.indication.u.
  4769. conference_terminate_indication,
  4770. initiator);
  4771. break;
  4772. case CONFERENCE_EJECT_USER_INDICATION_CHOSEN:
  4773. /*
  4774. ** Do not decode a packet that was sent uniformly
  4775. ** from this node.
  4776. */
  4777. if (initiator != m_nidMyself)
  4778. {
  4779. ProcessConferenceEjectUserIndicationPDU (
  4780. &gcc_pdu->u.indication.u.
  4781. conference_eject_user_indication,
  4782. initiator);
  4783. }
  4784. break;
  4785. case ROSTER_UPDATE_INDICATION_CHOSEN:
  4786. /*
  4787. ** Do not decode a packet that was sent uniformly
  4788. ** from this node.
  4789. */
  4790. if ((initiator != m_nidMyself) &&
  4791. (send_data_info->channel_id ==
  4792. BROADCAST_CHANNEL_ID))
  4793. {
  4794. //
  4795. // We only process the roster update if the conference is
  4796. // established.
  4797. //
  4798. if (m_pConf->IsConfEstablished())
  4799. {
  4800. m_pConf->ProcessRosterUpdatePDU(gcc_pdu, initiator);
  4801. }
  4802. }
  4803. break;
  4804. case CONFERENCE_LOCK_INDICATION_CHOSEN:
  4805. m_pConf->ProcessConferenceLockIndication(initiator);
  4806. break;
  4807. case CONFERENCE_UNLOCK_INDICATION_CHOSEN:
  4808. m_pConf->ProcessConferenceUnlockIndication(initiator);
  4809. break;
  4810. case CONDUCTOR_ASSIGN_INDICATION_CHOSEN:
  4811. m_pConf->ProcessConductorAssignIndication(
  4812. gcc_pdu->u.indication.u.conductor_assign_indication.user_id,
  4813. initiator);
  4814. break;
  4815. case CONDUCTOR_RELEASE_INDICATION_CHOSEN:
  4816. if (initiator != m_nidMyself)
  4817. {
  4818. m_pConf->ProcessConductorReleaseIndication(initiator);
  4819. }
  4820. break;
  4821. case CONDUCTOR_PERMISSION_ASK_INDICATION_CHOSEN:
  4822. #ifdef JASPER
  4823. /*
  4824. ** Do not decode a packet that was sent uniformly
  4825. ** from this node.
  4826. */
  4827. if (initiator != m_nidMyself)
  4828. {
  4829. PermitAskIndicationInfo indication_info;
  4830. indication_info.sender_id = initiator;
  4831. indication_info.permission_is_granted =
  4832. gcc_pdu->u.indication.u.
  4833. conductor_permission_ask_indication.
  4834. permission_is_granted;
  4835. m_pConf->ProcessConductorPermitAskIndication(&indication_info);
  4836. }
  4837. #endif // JASPER
  4838. break;
  4839. case CONDUCTOR_PERMISSION_GRANT_INDICATION_CHOSEN:
  4840. ProcessPermissionGrantIndication(
  4841. &(gcc_pdu->u.indication.u.
  4842. conductor_permission_grant_indication),
  4843. initiator);
  4844. break;
  4845. case CONFERENCE_TIME_REMAINING_INDICATION_CHOSEN:
  4846. #ifdef JASPER
  4847. ProcessTimeRemainingIndicationPDU (
  4848. &gcc_pdu->u.indication.u.
  4849. conference_time_remaining_indication,
  4850. initiator);
  4851. #endif // JASPER
  4852. break;
  4853. case APPLICATION_INVOKE_INDICATION_CHOSEN:
  4854. ProcessApplicationInvokeIndication(
  4855. &gcc_pdu->u.indication.u.
  4856. application_invoke_indication,
  4857. initiator);
  4858. break;
  4859. case TEXT_MESSAGE_INDICATION_CHOSEN:
  4860. #ifdef JASPER
  4861. if (ProcessTextMessageIndication(
  4862. &gcc_pdu->u.indication.u.
  4863. text_message_indication,
  4864. initiator) != GCC_NO_ERROR)
  4865. {
  4866. error_value = GCC_ALLOCATION_FAILURE;
  4867. }
  4868. #endif // JASPER
  4869. break;
  4870. case CONFERENCE_ASSISTANCE_INDICATION_CHOSEN:
  4871. #ifdef JASPER
  4872. ProcessConferenceAssistanceIndicationPDU(
  4873. &gcc_pdu->u.indication.u.
  4874. conference_assistance_indication,
  4875. initiator);
  4876. #endif // JASPER
  4877. break;
  4878. case REGISTRY_MONITOR_ENTRY_INDICATION_CHOSEN:
  4879. /*
  4880. ** Do not decode this packet if it was sent
  4881. ** uniformly from this node.
  4882. */
  4883. if (initiator != m_nidMyself)
  4884. {
  4885. ProcessRegistryMonitorIndicationPDU (
  4886. &gcc_pdu->u.indication.u.
  4887. registry_monitor_entry_indication,
  4888. initiator);
  4889. }
  4890. break;
  4891. case CONFERENCE_TRANSFER_INDICATION_CHOSEN:
  4892. #ifdef JASPER
  4893. /*
  4894. ** Do not decode this packet if it was not sent
  4895. ** from the top provider.
  4896. */
  4897. if (initiator == m_nidTopProvider)
  4898. {
  4899. ProcessTransferIndicationPDU (
  4900. &gcc_pdu->u.indication.u.
  4901. conference_transfer_indication);
  4902. }
  4903. #endif // JASPER
  4904. break;
  4905. default:
  4906. ERROR_OUT(("MCSUser::ProcessSendDataIndication"
  4907. "Unsupported PDU"));
  4908. break;
  4909. } // switch(gcc_pdu->u.indication.choice)
  4910. break;
  4911. default:
  4912. ERROR_OUT(("MCSUser::ProcessUniformSendDataIndication. wrong pdu type "));
  4913. break;
  4914. }
  4915. packet->Unlock();
  4916. }
  4917. else
  4918. {
  4919. delete packet;
  4920. error_value = GCC_ALLOCATION_FAILURE;
  4921. }
  4922. if (error_value == GCC_ALLOCATION_FAILURE)
  4923. {
  4924. ResourceFailureHandler();
  4925. }
  4926. return (MCS_NO_ERROR);
  4927. }
  4928. /*
  4929. * void ProcessTransferIndicationPDU ()
  4930. *
  4931. * Private Function Description:
  4932. * This routine is responsible for processing an incoming Conference
  4933. * Transfer indication PDU.
  4934. *
  4935. * Formal Parameters:
  4936. * transfer_indication - (i) This is the PDU structure to process.
  4937. *
  4938. * Return Value
  4939. * None.
  4940. *
  4941. * Side Effects
  4942. * None.
  4943. *
  4944. * Caveats
  4945. * None.
  4946. */
  4947. #ifdef JASPER
  4948. void MCSUser::
  4949. ProcessTransferIndicationPDU
  4950. (
  4951. PConferenceTransferIndication transfer_indication
  4952. )
  4953. {
  4954. GCCError rc = GCC_NO_ERROR;
  4955. TransferInfo transfer_info;
  4956. PSetOfTransferringNodesIn set_of_nodes;
  4957. LPBYTE sub_node_list_memory = NULL;
  4958. Int i;
  4959. BOOL process_pdu = FALSE;
  4960. ::ZeroMemory(&transfer_info, sizeof(transfer_info));
  4961. /*
  4962. ** If there is a transferring node list we must determine if this node
  4963. ** is in the list. If it isn't then the request is ignored.
  4964. */
  4965. if (transfer_indication->bit_mask & CTIN_TRANSFERRING_NODES_PRESENT)
  4966. {
  4967. set_of_nodes = transfer_indication->ctin_transferring_nodes;
  4968. while (set_of_nodes != NULL)
  4969. {
  4970. if (set_of_nodes->value == GetMyNodeID())
  4971. {
  4972. process_pdu = TRUE;
  4973. break;
  4974. }
  4975. set_of_nodes = set_of_nodes->next;
  4976. }
  4977. if (process_pdu == FALSE)
  4978. {
  4979. return;
  4980. }
  4981. }
  4982. // First set up the conference name
  4983. if (transfer_indication->conference_name.choice == NAME_SELECTOR_NUMERIC_CHOSEN)
  4984. {
  4985. transfer_info.destination_conference_name.numeric_string =
  4986. (LPSTR) transfer_indication->conference_name.u.name_selector_numeric;
  4987. // transfer_info.destination_conference_name.text_string = NULL;
  4988. }
  4989. else
  4990. {
  4991. // transfer_info.destination_conference_name.numeric_string = NULL;
  4992. if (NULL == (transfer_info.destination_conference_name.text_string = ::My_strdupW2(
  4993. transfer_indication->conference_name.u.name_selector_text.length,
  4994. transfer_indication->conference_name.u.name_selector_text.value)))
  4995. {
  4996. rc = GCC_ALLOCATION_FAILURE;
  4997. }
  4998. }
  4999. // Next set up the conference name modifier
  5000. if (transfer_indication->bit_mask & CTIN_CONFERENCE_MODIFIER_PRESENT)
  5001. {
  5002. transfer_info.destination_conference_modifier =
  5003. (LPSTR) transfer_indication->ctin_conference_modifier;
  5004. }
  5005. else
  5006. {
  5007. // transfer_info.destination_conference_modifier = NULL;
  5008. }
  5009. // Next set up the network address
  5010. if (transfer_indication->bit_mask & CTIN_NETWORK_ADDRESS_PRESENT)
  5011. {
  5012. DBG_SAVE_FILE_LINE
  5013. transfer_info.destination_address_list = new CNetAddrListContainer(
  5014. transfer_indication->ctin_net_address,
  5015. &rc);
  5016. if (transfer_info.destination_address_list == NULL)
  5017. {
  5018. rc = GCC_ALLOCATION_FAILURE;
  5019. }
  5020. }
  5021. else
  5022. {
  5023. // transfer_info.destination_address_list = NULL;
  5024. }
  5025. // Set up the transferring nodes list
  5026. if (transfer_indication->bit_mask & CTIN_TRANSFERRING_NODES_PRESENT)
  5027. {
  5028. // First determine the number of nodes.
  5029. set_of_nodes = transfer_indication->ctin_transferring_nodes;
  5030. // transfer_info.number_of_destination_nodes = 0;
  5031. while (set_of_nodes != NULL)
  5032. {
  5033. transfer_info.number_of_destination_nodes++;
  5034. set_of_nodes = set_of_nodes->next;
  5035. }
  5036. // Next allocate the memory required to hold the sub nodes
  5037. DBG_SAVE_FILE_LINE
  5038. sub_node_list_memory = new BYTE[sizeof(UserID) * transfer_info.number_of_destination_nodes];
  5039. // Now fill in the permission list
  5040. if (sub_node_list_memory != NULL)
  5041. {
  5042. transfer_info.destination_node_list = (PUserID) sub_node_list_memory;
  5043. set_of_nodes = transfer_indication->ctin_transferring_nodes;
  5044. for (i = 0; i < transfer_info.number_of_destination_nodes; i++)
  5045. {
  5046. transfer_info.destination_node_list[i] = set_of_nodes->value;
  5047. set_of_nodes = set_of_nodes->next;
  5048. }
  5049. }
  5050. else
  5051. {
  5052. ERROR_OUT(("MCSUser: ProcessTransferIndicationPDU: Memory Manager Alloc Failure"));
  5053. rc = GCC_ALLOCATION_FAILURE;
  5054. }
  5055. }
  5056. else
  5057. {
  5058. // transfer_info.number_of_destination_nodes = 0;
  5059. // transfer_info.destination_node_list = NULL;
  5060. }
  5061. // Set up the password
  5062. if (transfer_indication->bit_mask & CTIN_PASSWORD_PRESENT)
  5063. {
  5064. DBG_SAVE_FILE_LINE
  5065. transfer_info.password = new CPassword(&transfer_indication->ctin_password, &rc);
  5066. if (transfer_info.password == NULL)
  5067. {
  5068. rc = GCC_ALLOCATION_FAILURE;
  5069. }
  5070. }
  5071. else
  5072. {
  5073. // transfer_info.password = NULL;
  5074. }
  5075. if (rc == GCC_NO_ERROR)
  5076. {
  5077. g_pControlSap->ConfTransferIndication(
  5078. m_pConf->GetConfID(),
  5079. &transfer_info.destination_conference_name,
  5080. transfer_info.destination_conference_modifier,
  5081. transfer_info.destination_address_list,
  5082. transfer_info.password);
  5083. }
  5084. else
  5085. {
  5086. ERROR_OUT(("MCSUser::ProcessTransferIndicationPDU: Allocation Failure"));
  5087. if (GCC_ALLOCATION_FAILURE == rc)
  5088. {
  5089. ResourceFailureHandler();
  5090. }
  5091. }
  5092. // Now cleanup any allocated memory
  5093. if (NULL != transfer_info.destination_address_list)
  5094. {
  5095. transfer_info.destination_address_list->Release();
  5096. }
  5097. delete sub_node_list_memory;
  5098. if (NULL != transfer_info.password)
  5099. {
  5100. transfer_info.password->Release();
  5101. }
  5102. }
  5103. #endif // JASPER
  5104. /*
  5105. * void ProcessConferenceTerminateIndicationPDU()
  5106. *
  5107. * Private Function Description:
  5108. * This routine is responsible for processing an incoming Conference
  5109. * Terminate indication PDU.
  5110. *
  5111. * Formal Parameters:
  5112. * terminate_indication - (i) This is the PDU structure to process.
  5113. * sender_id - (i) Node ID of node that sent this PDU.
  5114. *
  5115. * Return Value
  5116. * None.
  5117. *
  5118. * Side Effects
  5119. * None.
  5120. *
  5121. * Caveats
  5122. * None.
  5123. */
  5124. void MCSUser::ProcessConferenceTerminateIndicationPDU (
  5125. PConferenceTerminateIndication terminate_indication,
  5126. UserID sender_id)
  5127. {
  5128. if (sender_id == m_nidTopProvider)
  5129. {
  5130. m_pConf->ProcessTerminateIndication(
  5131. ::TranslateTerminateInReasonToGCCReason(terminate_indication->reason));
  5132. }
  5133. }
  5134. /*
  5135. * void ProcessTimeRemainingIndicationPDU ()
  5136. *
  5137. * Private Function Description:
  5138. * This routine is responsible for processing an incoming Conference
  5139. * Time remaining indication PDU.
  5140. *
  5141. * Formal Parameters:
  5142. * time_remaining_indication - (i) This is the PDU structure to process
  5143. * sender_id - (i) Node ID of node that sent this PDU.
  5144. *
  5145. * Return Value
  5146. * None.
  5147. *
  5148. * Side Effects
  5149. * None.
  5150. *
  5151. * Caveats
  5152. * None.
  5153. */
  5154. #ifdef JASPER
  5155. void MCSUser::
  5156. ProcessTimeRemainingIndicationPDU
  5157. (
  5158. PConferenceTimeRemainingIndication time_remaining_indication,
  5159. UserID sender_id
  5160. )
  5161. {
  5162. g_pControlSap->ConfTimeRemainingIndication(
  5163. m_pConf->GetConfID(),
  5164. sender_id,
  5165. (time_remaining_indication->bit_mask & TIME_REMAINING_NODE_ID_PRESENT) ?
  5166. time_remaining_indication->time_remaining_node_id : 0,
  5167. time_remaining_indication->time_remaining);
  5168. }
  5169. #endif // JASPER
  5170. /*
  5171. * void ProcessConferenceAssistanceIndicationPDU ()
  5172. *
  5173. * Private Function Description:
  5174. * This routine is responsible for processing an incoming Conference
  5175. * assistance indication PDU.
  5176. *
  5177. * Formal Parameters:
  5178. * conf_assistance_indication - (i) This is the PDU structure to process
  5179. * sender_id - (i) Node ID of node that sent this PDU.
  5180. *
  5181. * Return Value
  5182. * None.
  5183. *
  5184. * Side Effects
  5185. * None.
  5186. *
  5187. * Caveats
  5188. * None.
  5189. */
  5190. #ifdef JASPER
  5191. void MCSUser::
  5192. ProcessConferenceAssistanceIndicationPDU
  5193. (
  5194. PConferenceAssistanceIndication conf_assistance_indication,
  5195. UserID sender_id
  5196. )
  5197. {
  5198. GCCError rc = GCC_NO_ERROR;
  5199. CUserDataListContainer *user_data_list = NULL;
  5200. DebugEntry(MCSUser::ProcessConferenceAssistanceIndication);
  5201. // Unpack the user data list if it exists
  5202. if (conf_assistance_indication->bit_mask & CAIN_USER_DATA_PRESENT)
  5203. {
  5204. DBG_SAVE_FILE_LINE
  5205. user_data_list = new CUserDataListContainer(conf_assistance_indication->cain_user_data, &rc);
  5206. if (user_data_list == NULL)
  5207. {
  5208. rc = GCC_ALLOCATION_FAILURE;
  5209. }
  5210. }
  5211. if (rc == GCC_NO_ERROR)
  5212. {
  5213. g_pControlSap->ConfAssistanceIndication(
  5214. m_pConf->GetConfID(),
  5215. user_data_list,
  5216. sender_id);
  5217. }
  5218. else
  5219. {
  5220. ERROR_OUT(("MCSUser::ProcessConferenceAssistanceIndication: can't create CUserDataListContainer"));
  5221. if (GCC_ALLOCATION_FAILURE == rc)
  5222. {
  5223. ResourceFailureHandler();
  5224. }
  5225. }
  5226. }
  5227. #endif // JASPER
  5228. /*
  5229. * void ProcessConferenceExtendIndicationPDU()
  5230. *
  5231. * Private Function Description:
  5232. * This routine is responsible for processing an incoming Conference
  5233. * extend indication PDU.
  5234. *
  5235. * Formal Parameters:
  5236. * conf_time_extend_indication - (i) This is the PDU structure to process
  5237. * sender_id - (i) Node ID of node that sent this PDU.
  5238. *
  5239. * Return Value
  5240. * None.
  5241. *
  5242. * Side Effects
  5243. * None.
  5244. *
  5245. * Caveats
  5246. * None.
  5247. */
  5248. #ifdef JASPER
  5249. void MCSUser::
  5250. ProcessConferenceExtendIndicationPDU
  5251. (
  5252. PConferenceTimeExtendIndication conf_time_extend_indication,
  5253. UserID sender_id
  5254. )
  5255. {
  5256. g_pControlSap->ConfExtendIndication(
  5257. m_pConf->GetConfID(),
  5258. conf_time_extend_indication->time_to_extend,
  5259. conf_time_extend_indication->time_is_node_specific,
  5260. sender_id);
  5261. }
  5262. #endif // JASPER
  5263. /*
  5264. * void ProcessConferenceEjectUserIndicationPDU ()
  5265. *
  5266. * Private Function Description:
  5267. * This routine is responsible for processing an incoming Conference
  5268. * eject user indication PDU.
  5269. *
  5270. * Formal Parameters:
  5271. * eject_user_indication - (i) This is the PDU structure to process
  5272. * sender_id - (i) Node ID of node that sent this PDU.
  5273. *
  5274. * Return Value
  5275. * None.
  5276. *
  5277. * Side Effects
  5278. * None.
  5279. *
  5280. * Caveats
  5281. * None.
  5282. */
  5283. void MCSUser::ProcessConferenceEjectUserIndicationPDU (
  5284. PConferenceEjectUserIndication eject_user_indication,
  5285. UserID sender_id)
  5286. {
  5287. GCCError error_value = GCC_NO_ERROR;
  5288. PAlarm alarm = NULL;
  5289. // First check to make sure that this is the node being ejected
  5290. if (eject_user_indication->node_to_eject == m_nidMyself)
  5291. {
  5292. /*
  5293. ** Next make sure the ejection came from either the Top Provider or
  5294. ** the Parent Node.
  5295. */
  5296. if ((sender_id == m_nidParent) || (sender_id == m_nidTopProvider))
  5297. {
  5298. TRACE_OUT(("MCSUser:ProcessEjectUserIndication: This node is ejected"));
  5299. error_value = InitiateEjectionFromConference (
  5300. ::TranslateEjectIndReasonToGCCReason(
  5301. eject_user_indication->reason));
  5302. }
  5303. else
  5304. {
  5305. ERROR_OUT(("MCSUser: ProcessEjectUserIndication: Received eject from illegal node"));
  5306. }
  5307. }
  5308. else
  5309. {
  5310. TRACE_OUT(("MCSUser: ProcessEjectUserIndication: Received eject for node other than mine"));
  5311. /*
  5312. ** If this node is a directly connected child node we insert an
  5313. ** alarm in the list m_EjectedNodeAlarmList2 to disconnect it if
  5314. ** it misbehaves and does not disconnect itself. Otherwise, we save
  5315. ** the ejected user id in the m_EjectedNodeList to inform the local
  5316. ** node of the correct reason for disconnecting (user ejected) when the
  5317. ** detch user indication comes in.
  5318. */
  5319. if (m_ChildUidConnHdlList2.Find(eject_user_indication->node_to_eject))
  5320. {
  5321. DBG_SAVE_FILE_LINE
  5322. alarm = new Alarm (EJECTED_NODE_TIMER_DURATION);
  5323. if (alarm != NULL)
  5324. {
  5325. m_EjectedNodeAlarmList2.Append(eject_user_indication->node_to_eject, alarm);
  5326. }
  5327. else
  5328. error_value = GCC_ALLOCATION_FAILURE;
  5329. }
  5330. else
  5331. {
  5332. /*
  5333. ** Here we save the alarm in a list of ejected nodes. This
  5334. ** alarm is used to cleanup any misbehaving node. Note that
  5335. ** if the ejected node is not a child of this node then no
  5336. ** alarm is set up to monitor the ejection.
  5337. */
  5338. m_EjectedNodeList.Append(eject_user_indication->node_to_eject);
  5339. }
  5340. }
  5341. if (error_value == GCC_ALLOCATION_FAILURE)
  5342. {
  5343. ERROR_OUT(("MCSUser::ProcessEjectUserIndication: Allocation Failure"));
  5344. ResourceFailureHandler();
  5345. }
  5346. }
  5347. /*
  5348. * void ProcessPermissionGrantIndication ()
  5349. *
  5350. * Private Function Description:
  5351. * This routine is responsible for processing an incoming Permission
  5352. * grant indication PDU.
  5353. *
  5354. * Formal Parameters:
  5355. * permission_grant_indication - (i) This is the PDU structure to process
  5356. * sender_id - (i) Node ID of node that sent this PDU.
  5357. *
  5358. * Return Value
  5359. * None.
  5360. *
  5361. * Side Effects
  5362. * None.
  5363. *
  5364. * Caveats
  5365. * None.
  5366. */
  5367. void MCSUser::ProcessPermissionGrantIndication(
  5368. PConductorPermissionGrantIndication permission_grant_indication,
  5369. UserID sender_id)
  5370. {
  5371. GCCError error_value = GCC_NO_ERROR;
  5372. UserPermissionGrantIndicationInfo grant_indication_info;
  5373. PPermissionList permission_list;
  5374. LPBYTE permission_list_memory = NULL;
  5375. PWaitingList waiting_list;
  5376. LPBYTE waiting_list_memory = NULL;
  5377. UINT i;
  5378. // First count the number of entries in the permission list
  5379. grant_indication_info.number_granted = 0;
  5380. permission_list = permission_grant_indication->permission_list;
  5381. while (permission_list != NULL)
  5382. {
  5383. permission_list = permission_list->next;
  5384. grant_indication_info.number_granted++;
  5385. }
  5386. TRACE_OUT(("MCSUser: ProcessPermissionGrantIndication: number_granted=%d", (UINT) grant_indication_info.number_granted));
  5387. // If a list exist allocate memory for it and copy it over.
  5388. if (grant_indication_info.number_granted != 0)
  5389. {
  5390. // allocating space to hold permission list.
  5391. DBG_SAVE_FILE_LINE
  5392. permission_list_memory = new BYTE[sizeof(UserID) * grant_indication_info.number_granted];
  5393. // Now fill in the permission list
  5394. if (permission_list_memory != NULL)
  5395. {
  5396. grant_indication_info.granted_node_list = (PUserID) permission_list_memory;
  5397. permission_list = permission_grant_indication->permission_list;
  5398. for (i = 0; i < grant_indication_info.number_granted; i++)
  5399. {
  5400. grant_indication_info.granted_node_list[i] = permission_list->value;
  5401. permission_list = permission_list->next;
  5402. }
  5403. }
  5404. else
  5405. {
  5406. ERROR_OUT(("MCSUser: ProcessPermissionGrantIndication: Memory Manager Alloc Failure"));
  5407. error_value = GCC_ALLOCATION_FAILURE;
  5408. }
  5409. }
  5410. else
  5411. {
  5412. grant_indication_info.granted_node_list = NULL;
  5413. }
  5414. // Now extract the waiting list information if any exist
  5415. if ((error_value == GCC_NO_ERROR) &&
  5416. (permission_grant_indication->bit_mask & WAITING_LIST_PRESENT))
  5417. {
  5418. // First count the number of entries in the waiting list
  5419. grant_indication_info.number_waiting = 0;
  5420. waiting_list = permission_grant_indication->waiting_list;
  5421. while (waiting_list != NULL)
  5422. {
  5423. waiting_list = waiting_list->next;
  5424. grant_indication_info.number_waiting++;
  5425. }
  5426. TRACE_OUT(("MCSUser: ProcessPermissionGrantIndication: number_waiting=%d", (UINT) grant_indication_info.number_waiting));
  5427. // allocating space to hold waiting list.
  5428. DBG_SAVE_FILE_LINE
  5429. waiting_list_memory = new BYTE[sizeof(UserID) * grant_indication_info.number_waiting];
  5430. // Now fill in the permission list
  5431. if (waiting_list_memory != NULL)
  5432. {
  5433. grant_indication_info.waiting_node_list = (PUserID) waiting_list_memory;
  5434. waiting_list = permission_grant_indication->waiting_list;
  5435. for (i = 0; i < grant_indication_info.number_waiting; i++)
  5436. {
  5437. grant_indication_info.waiting_node_list[i] = waiting_list->value;
  5438. waiting_list = waiting_list->next;
  5439. }
  5440. }
  5441. else
  5442. {
  5443. error_value = GCC_ALLOCATION_FAILURE;
  5444. }
  5445. }
  5446. else
  5447. {
  5448. grant_indication_info.number_waiting = 0;
  5449. grant_indication_info.waiting_node_list = NULL;
  5450. }
  5451. /*
  5452. ** If there were no memory errors, send the indication back to the
  5453. ** owner object.
  5454. */
  5455. if (error_value == GCC_NO_ERROR)
  5456. {
  5457. m_pConf->ProcessConductorPermitGrantInd(&grant_indication_info, sender_id);
  5458. }
  5459. else
  5460. {
  5461. ERROR_OUT(("MCSUser::ProcessPermissionGrantIndication: Alloc Failed"));
  5462. if (GCC_ALLOCATION_FAILURE == error_value)
  5463. {
  5464. ResourceFailureHandler();
  5465. }
  5466. }
  5467. // Free up any memory used in this call
  5468. delete [] permission_list_memory;
  5469. delete [] waiting_list_memory;
  5470. }
  5471. /*
  5472. * MCSUser::GetUserIDFromConnection()
  5473. *
  5474. * Public Function Description:
  5475. * This function returns the Node ID associated with the specified
  5476. * connection handle. It returns zero if the connection handle is
  5477. * not a child connection of this node.
  5478. */
  5479. UserID MCSUser::GetUserIDFromConnection(ConnectionHandle connection_handle)
  5480. {
  5481. ConnectionHandle hConn;
  5482. UserID uid;
  5483. m_ChildUidConnHdlList2.Reset();
  5484. while (NULL != (hConn = m_ChildUidConnHdlList2.Iterate(&uid)))
  5485. {
  5486. if (hConn == connection_handle)
  5487. {
  5488. return uid;
  5489. }
  5490. }
  5491. return 0;
  5492. }
  5493. /*
  5494. * MCSUser::UserDisconnectIndication()
  5495. *
  5496. * Public Function Description:
  5497. * This function informs the user object when a Node disconnects from
  5498. * the conference. This gives the user object a chance to clean up
  5499. * its internal information base.
  5500. */
  5501. void MCSUser::UserDisconnectIndication(UserID disconnected_user)
  5502. {
  5503. PAlarm lpAlarm;
  5504. /*
  5505. ** If this node has a pending ejection we will go ahead and remove the
  5506. ** ejected node from the list. Once all child nodes have disconnected
  5507. ** we will inform the owner object of the ejection.
  5508. */
  5509. if (m_fEjectionPending)
  5510. {
  5511. // Delete the Alarm if it exists
  5512. if (NULL != (lpAlarm = m_EjectedNodeAlarmList2.Remove(disconnected_user)))
  5513. {
  5514. delete lpAlarm;
  5515. /*
  5516. ** Here we must check to see if there are anymore active alarms
  5517. ** in the list. If so we wait until that node disconnects before
  5518. ** informing the owner object that this node has been ejected.
  5519. ** Otherwise, we complete the ejection process.
  5520. */
  5521. if (m_EjectedNodeAlarmList2.IsEmpty())
  5522. {
  5523. m_pConf->ProcessEjectUserIndication(m_eEjectReason);
  5524. }
  5525. }
  5526. }
  5527. // If we are the top provider, just clean the eject alarm list.
  5528. else if (TOP_PROVIDER_AND_CONVENER_NODE == m_pConf->GetConfNodeType() &&
  5529. NULL != (lpAlarm = m_EjectedNodeAlarmList2.Remove(disconnected_user)))
  5530. {
  5531. delete lpAlarm;
  5532. }
  5533. /*
  5534. ** Here we remove the entry from the list of child connections if
  5535. ** it is included in this list.
  5536. */
  5537. m_ChildUidConnHdlList2.Remove(disconnected_user);
  5538. }
  5539. /*
  5540. * void ProcessApplicationInvokeIndication ()
  5541. *
  5542. * Private Function Description:
  5543. * This routine is responsible for processing an incoming Invoke
  5544. * indication PDU.
  5545. *
  5546. * Formal Parameters:
  5547. * invoke_indication - (i) This is the PDU structure to process
  5548. * sender_id - (i) Node ID of node that sent this PDU.
  5549. *
  5550. * Return Value
  5551. * None.
  5552. *
  5553. * Side Effects
  5554. * None.
  5555. *
  5556. * Caveats
  5557. * None.
  5558. */
  5559. void MCSUser::ProcessApplicationInvokeIndication(
  5560. PApplicationInvokeIndication invoke_indication,
  5561. UserID sender_id)
  5562. {
  5563. GCCError error_value = GCC_NO_ERROR;
  5564. BOOL process_pdu = FALSE;
  5565. CInvokeSpecifierListContainer *invoke_list;
  5566. PSetOfDestinationNodes set_of_destination_nodes;
  5567. if (invoke_indication->bit_mask & DESTINATION_NODES_PRESENT)
  5568. {
  5569. set_of_destination_nodes = invoke_indication->destination_nodes;
  5570. while (set_of_destination_nodes != NULL)
  5571. {
  5572. if (set_of_destination_nodes->value == m_nidMyself)
  5573. {
  5574. process_pdu = TRUE;
  5575. break;
  5576. }
  5577. else
  5578. {
  5579. set_of_destination_nodes = set_of_destination_nodes->next;
  5580. }
  5581. }
  5582. }
  5583. else
  5584. {
  5585. process_pdu = TRUE;
  5586. }
  5587. if (process_pdu)
  5588. {
  5589. TRACE_OUT(("MCSUser: ProcessApplicationInvokeIndication: Process PDU"));
  5590. DBG_SAVE_FILE_LINE
  5591. invoke_list = new CInvokeSpecifierListContainer(
  5592. invoke_indication->application_protocol_entity_list,
  5593. &error_value);
  5594. if ((invoke_list != NULL) && (error_value == GCC_NO_ERROR))
  5595. {
  5596. m_pConf->ProcessAppInvokeIndication(invoke_list, sender_id);
  5597. invoke_list->Release();
  5598. }
  5599. else if (invoke_list == NULL)
  5600. {
  5601. error_value = GCC_ALLOCATION_FAILURE;
  5602. }
  5603. else
  5604. {
  5605. invoke_list->Release();
  5606. }
  5607. if (error_value == GCC_ALLOCATION_FAILURE)
  5608. {
  5609. ERROR_OUT(("MCSUser::ProcessApplicationInvokeIndication: Allocation Failure"));
  5610. ResourceFailureHandler();
  5611. }
  5612. }
  5613. else
  5614. {
  5615. WARNING_OUT(("MCSUser:ProcessApplicationInvokeIndication: Don't Process PDU"));
  5616. }
  5617. }
  5618. /*
  5619. * GCCError ProcessTextMessageIndication ()
  5620. *
  5621. * Private Function Description:
  5622. * This routine is responsible for processing an incoming Text
  5623. * message indication PDU.
  5624. *
  5625. * Formal Parameters:
  5626. * text_message_indication - (i) This is the PDU structure to process
  5627. * sender_id - (i) Node ID of node that sent this PDU.
  5628. *
  5629. * Return Value
  5630. * GCC_NO_ERROR - No error occured.
  5631. * GCC_ALLOCATION_FAILURE - A resource error occured.
  5632. *
  5633. * Side Effects
  5634. * None.
  5635. *
  5636. * Caveats
  5637. * None.
  5638. */
  5639. #ifdef JASPER
  5640. GCCError MCSUser::ProcessTextMessageIndication(
  5641. PTextMessageIndication text_message_indication,
  5642. UserID sender_id)
  5643. {
  5644. LPWSTR gcc_unicode_string;
  5645. GCCError rc;
  5646. if (NULL != (gcc_unicode_string = ::My_strdupW2(
  5647. text_message_indication->message.length,
  5648. text_message_indication->message.value)))
  5649. {
  5650. rc = g_pControlSap->TextMessageIndication(
  5651. m_pConf->GetConfID(),
  5652. gcc_unicode_string,
  5653. sender_id);
  5654. }
  5655. else
  5656. {
  5657. rc = GCC_ALLOCATION_FAILURE;
  5658. }
  5659. return rc;
  5660. }
  5661. #endif // JASPER
  5662. /*
  5663. * void ProcessRegistryMonitorIndication ()
  5664. *
  5665. * Private Function Description:
  5666. * This routine is responsible for processing an incoming Registry
  5667. * monitor indication PDU.
  5668. *
  5669. * Formal Parameters:
  5670. * monitor_indication - (i) This is the PDU structure to process
  5671. * sender_id - (i) Node ID of node that sent this PDU.
  5672. *
  5673. * Return Value
  5674. * None.
  5675. *
  5676. * Side Effects
  5677. * None.
  5678. *
  5679. * Caveats
  5680. * None.
  5681. */
  5682. void MCSUser::
  5683. ProcessRegistryMonitorIndicationPDU
  5684. (
  5685. PRegistryMonitorEntryIndication monitor_indication,
  5686. UserID sender_id
  5687. )
  5688. {
  5689. if (sender_id == m_nidTopProvider)
  5690. {
  5691. CRegistry *pAppReg = m_pConf->GetRegistry();
  5692. if (NULL != pAppReg)
  5693. {
  5694. GCCError rc;
  5695. UserRegistryMonitorInfo urmi;
  5696. ::ZeroMemory(&urmi, sizeof(urmi));
  5697. // urmi.registry_key = NULL;
  5698. // urmi.registry_item = NULL;
  5699. DBG_SAVE_FILE_LINE
  5700. urmi.registry_key = new CRegKeyContainer(&monitor_indication->key, &rc);
  5701. if ((urmi.registry_key != NULL) && (rc == GCC_NO_ERROR))
  5702. {
  5703. DBG_SAVE_FILE_LINE
  5704. urmi.registry_item = new CRegItem(&monitor_indication->item, &rc);
  5705. if ((urmi.registry_item != NULL) && (rc == GCC_NO_ERROR))
  5706. {
  5707. // Set up the owner related variables
  5708. if (monitor_indication->owner.choice == OWNED_CHOSEN)
  5709. {
  5710. urmi.owner_node_id = monitor_indication->owner.u.owned.node_id;
  5711. urmi.owner_entity_id = monitor_indication->owner.u.owned.entity_id;
  5712. }
  5713. else
  5714. {
  5715. // urmi.owner_node_id = 0;
  5716. // urmi.owner_entity_id = 0;
  5717. }
  5718. // Set up the modification rights
  5719. if (monitor_indication->bit_mask & RESPONSE_MODIFY_RIGHTS_PRESENT)
  5720. {
  5721. urmi.modification_rights = (GCCModificationRights)monitor_indication->entry_modify_rights;
  5722. }
  5723. else
  5724. {
  5725. urmi.modification_rights = GCC_NO_MODIFICATION_RIGHTS_SPECIFIED;
  5726. }
  5727. pAppReg->ProcessMonitorIndicationPDU(
  5728. urmi.registry_key,
  5729. urmi.registry_item,
  5730. urmi.modification_rights,
  5731. urmi.owner_node_id,
  5732. urmi.owner_entity_id);
  5733. }
  5734. else
  5735. {
  5736. rc = GCC_ALLOCATION_FAILURE;
  5737. }
  5738. }
  5739. else
  5740. {
  5741. rc = GCC_ALLOCATION_FAILURE;
  5742. }
  5743. if (NULL != urmi.registry_key)
  5744. {
  5745. urmi.registry_key->Release();
  5746. }
  5747. if (NULL != urmi.registry_item)
  5748. {
  5749. urmi.registry_item->Release();
  5750. }
  5751. // Handle any resource errors
  5752. if (rc == GCC_ALLOCATION_FAILURE)
  5753. {
  5754. ResourceFailureHandler();
  5755. }
  5756. }
  5757. else
  5758. {
  5759. WARNING_OUT(("MCSUser:ProcessRegistryMonitorIndication: invalid app registry"));
  5760. }
  5761. }
  5762. else
  5763. {
  5764. WARNING_OUT(("MCSUser:ProcessRegistryMonitorIndication:"
  5765. "Monitor Indication received from NON Top Provider"));
  5766. }
  5767. }
  5768. /*
  5769. * UINT ProcessDetachUserIndication()
  5770. *
  5771. * Private Function Description:
  5772. * This function is called when the user object gets detach user
  5773. * indications from nodes in it's subtree or it's parent node.
  5774. * Depending upon the reason of the indication it sends to the
  5775. * conference object the appropriate owner callback.
  5776. * If the reason contained in the indication is UserInitiated or
  5777. * provider initiated a DETACH USER INDICATION is sent to the con-
  5778. * ference. The MCS reason is converted to GCC reason. If MCS
  5779. * reason in indication is neither user initiated nor provider initiated
  5780. * then the above owner callback carries a GCC reason ERROR_TERMINATION
  5781. * else it carries a GCC reason USER_INITIATED.
  5782. * If the detach user indication reveals the user id of the sendar as
  5783. * the parent user id of this node a CONFERENCE_TERMINATE_INDICATION
  5784. * is sent to the conference object.
  5785. *
  5786. * Formal Parameters:
  5787. * mcs_reason - (i) MCS reason for being detached.
  5788. * sender_id - (i) User ID of user being detached.
  5789. *
  5790. * Return Value
  5791. * MCS_NO_ERROR is always returned fro this routine.
  5792. *
  5793. * Side Effects
  5794. * None.
  5795. *
  5796. * Caveats
  5797. * None.
  5798. */
  5799. UINT MCSUser::ProcessDetachUserIndication( Reason mcs_reason,
  5800. UserID detached_user)
  5801. {
  5802. GCCReason gcc_reason;
  5803. if (detached_user == m_nidParent)
  5804. {
  5805. WARNING_OUT(("MCSUser: Fatal Error: Parent User Detached"));
  5806. m_pConf->ProcessTerminateIndication(GCC_REASON_PARENT_DISCONNECTED);
  5807. }
  5808. else
  5809. {
  5810. TRACE_OUT(("MCSUser: User Detached: uid=0x%04x", (UINT) detached_user));
  5811. /*
  5812. ** First, we check to see if the detching node was ejected.
  5813. ** If not, translate the mcs reason to a gcc reason.
  5814. */
  5815. if (m_EjectedNodeList.Find(detached_user))
  5816. {
  5817. gcc_reason = GCC_REASON_NODE_EJECTED;
  5818. // Remove this entry from the ejected node list.
  5819. m_EjectedNodeList.Remove(detached_user);
  5820. }
  5821. else if (m_EjectedNodeAlarmList2.Find(detached_user))
  5822. {
  5823. // Here we wait for the disconnect before removing the entry.
  5824. gcc_reason = GCC_REASON_NODE_EJECTED;
  5825. }
  5826. else if ((mcs_reason == REASON_USER_REQUESTED) ||
  5827. (mcs_reason == REASON_PROVIDER_INITIATED))
  5828. {
  5829. gcc_reason = GCC_REASON_USER_INITIATED;
  5830. }
  5831. else
  5832. {
  5833. gcc_reason = GCC_REASON_ERROR_TERMINATION;
  5834. }
  5835. m_pConf->ProcessDetachUserIndication(detached_user, gcc_reason);
  5836. }
  5837. return (MCS_NO_ERROR);
  5838. }
  5839. void MCSUser::
  5840. ProcessTokenGrabConfirm
  5841. (
  5842. TokenID tidConductor,
  5843. Result result
  5844. )
  5845. {
  5846. if (tidConductor == CONDUCTOR_TOKEN_ID)
  5847. {
  5848. m_pConf->ProcessConductorGrabConfirm(::TranslateMCSResultToGCCResult(result));
  5849. }
  5850. else
  5851. {
  5852. ERROR_OUT(("MCSUser:Assertion Failure: Non Conductor Grab Confirm"));
  5853. }
  5854. }
  5855. void MCSUser::
  5856. ProcessTokenGiveIndication
  5857. (
  5858. TokenID tidConductor,
  5859. UserID uidRecipient
  5860. )
  5861. {
  5862. if (tidConductor == CONDUCTOR_TOKEN_ID)
  5863. {
  5864. m_pConf->ProcessConductorGiveIndication(uidRecipient);
  5865. }
  5866. else
  5867. {
  5868. ERROR_OUT(("MCSUser:Assertion Failure: Non Conductor Please Ind"));
  5869. }
  5870. }
  5871. void MCSUser::
  5872. ProcessTokenGiveConfirm
  5873. (
  5874. TokenID tidConductor,
  5875. Result result
  5876. )
  5877. {
  5878. if (tidConductor == CONDUCTOR_TOKEN_ID)
  5879. {
  5880. m_pConf->ProcessConductorGiveConfirm(::TranslateMCSResultToGCCResult(result));
  5881. }
  5882. else
  5883. {
  5884. ERROR_OUT(("MCSUser:Assertion Failure: Non Conductor Grab Confirm"));
  5885. }
  5886. }
  5887. #ifdef JASPER
  5888. void MCSUser::
  5889. ProcessTokenPleaseIndication
  5890. (
  5891. TokenID tidConductor,
  5892. UserID uidRequester
  5893. )
  5894. {
  5895. if (tidConductor == CONDUCTOR_TOKEN_ID)
  5896. {
  5897. if (m_pConf->IsConfConductible())
  5898. {
  5899. // Inform the control SAP.
  5900. g_pControlSap->ConductorPleaseIndication(
  5901. m_pConf->GetConfID(),
  5902. uidRequester);
  5903. }
  5904. }
  5905. else
  5906. {
  5907. ERROR_OUT(("MCSUser:Assertion Failure: Non Conductor Please Ind"));
  5908. }
  5909. }
  5910. #endif // JASPER
  5911. #ifdef JASPER
  5912. void MCSUser::
  5913. ProcessTokenReleaseConfirm
  5914. (
  5915. TokenID tidConductor,
  5916. Result result
  5917. )
  5918. {
  5919. if (tidConductor == CONDUCTOR_TOKEN_ID)
  5920. {
  5921. g_pControlSap->ConductorReleaseConfirm(::TranslateMCSResultToGCCResult(result),
  5922. m_pConf->GetConfID());
  5923. }
  5924. else
  5925. {
  5926. ERROR_OUT(("MCSUser:Assertion Failure: Non Conductor Release Cfrm"));
  5927. }
  5928. }
  5929. #endif // JASPER
  5930. void MCSUser::
  5931. ProcessTokenTestConfirm
  5932. (
  5933. TokenID tidConductor,
  5934. TokenStatus eStatus
  5935. )
  5936. {
  5937. if (tidConductor == CONDUCTOR_TOKEN_ID)
  5938. {
  5939. m_pConf->ProcessConductorTestConfirm((eStatus == TOKEN_NOT_IN_USE) ?
  5940. GCC_RESULT_NOT_IN_CONDUCTED_MODE :
  5941. GCC_RESULT_SUCCESSFUL);
  5942. }
  5943. else
  5944. {
  5945. ERROR_OUT(("MCSUser:Assertion Failure: Non Conductor Release Cfrm"));
  5946. }
  5947. }
  5948. void MCSUser::ResourceFailureHandler(void)
  5949. {
  5950. ERROR_OUT(("MCSUser::ResourceFailureHandler: terminating the conference"));
  5951. m_pConf->InitiateTermination(GCC_REASON_ERROR_LOW_RESOURCES, 0);
  5952. }
  5953.