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

416 lines
10 KiB

  1. #include "precomp.h"
  2. DEBUG_FILEZONE(ZONE_T120_MCSNC);
  3. /*
  4. * channel.cpp
  5. *
  6. * Copyright (c) 1993 - 1995 by DataBeam Corporation, Lexington, KY
  7. *
  8. * Abstract:
  9. * This is the implementation file for class Channel. It contains the
  10. * code necessary to implement static and assigned channels in the
  11. * MCS system.
  12. *
  13. * This is also to be the base class for other classes that represent
  14. * channels in the system. Therefore, there will be times when some
  15. * of these member functions are overridden to provide different
  16. * behavior. These derived classes may or may not invoke the operations
  17. * in this class.
  18. *
  19. * Protected Instance Variables:
  20. * Channel_ID
  21. * This instance variable contains the channel ID that is associated
  22. * with a given instance of this class.
  23. * m_pDomain
  24. * This is a pointer to the local provider. Note that no messages
  25. * ever sent to this provider. This pointer is used as a parameter
  26. * whenever other MCS commands are issued, since this class acts on
  27. * behalf of the local provider.
  28. * m_pConnToTopProvider
  29. * This is a pointer to the Top Provider. This is used when it is
  30. * necessary to send requests to the Top Provider.
  31. * m_pChannelList2
  32. * This is a reference to the channel list that is owned and maintained
  33. * by the parent domain. It is NEVER modified by this class.
  34. * m_JoinedAttachmentList
  35. * This is a container that contains the list of attachments currently
  36. * joined to the channel.
  37. *
  38. * Private Member Functions:
  39. * None.
  40. *
  41. * Caveats:
  42. * None.
  43. *
  44. * Author:
  45. * James P. Galvin, Jr.
  46. */
  47. /*
  48. * Channel ()
  49. *
  50. * Public
  51. *
  52. * Functional Description:
  53. * This is the primary constructor for the Channel class. It simply
  54. * initializes the instance variable to valid values. It leaves the
  55. * attachment list empty.
  56. */
  57. Channel::Channel (
  58. ChannelID channel_id,
  59. PDomain local_provider,
  60. PConnection top_provider,
  61. CChannelList2 *channel_list,
  62. CAttachmentList *attachment_list)
  63. :
  64. Channel_ID (channel_id),
  65. m_pDomain(local_provider),
  66. m_pConnToTopProvider(top_provider),
  67. m_pChannelList2(channel_list),
  68. m_pAttachmentList(attachment_list)
  69. {
  70. }
  71. /*
  72. * Channel ()
  73. *
  74. * Public
  75. *
  76. * Functional Description:
  77. * This version of the constructor is used to create a Channel object
  78. * with an existing attachment. It is otherwise the same as the primary
  79. * constructor above.
  80. */
  81. Channel::Channel (
  82. ChannelID channel_id,
  83. PDomain local_provider,
  84. PConnection top_provider,
  85. CChannelList2 *channel_list,
  86. CAttachmentList *attachment_list,
  87. PConnection pConn)
  88. :
  89. Channel_ID (channel_id),
  90. m_pDomain(local_provider),
  91. m_pConnToTopProvider(top_provider),
  92. m_pChannelList2(channel_list),
  93. m_pAttachmentList(attachment_list)
  94. {
  95. /*
  96. * Add the initial attachment to the attachment list.
  97. */
  98. if (pConn != NULL)
  99. m_JoinedAttachmentList.Append(pConn);
  100. }
  101. /*
  102. * ~Channel ()
  103. *
  104. * Public
  105. *
  106. * Functional Description:
  107. * If the object is destroyed before the attachment list is empty, it is
  108. * the responsibility of this destructor to issue channel leave indications
  109. * to all locally joined users.
  110. */
  111. Channel::~Channel ()
  112. {
  113. CAttachment *pAtt;
  114. //DWORD type;
  115. /*
  116. * Iterate through the joined attachment list sending channel leave
  117. * indications to all users who are locally attached to this provider.
  118. */
  119. m_JoinedAttachmentList.Reset();
  120. while (NULL != (pAtt = m_JoinedAttachmentList.Iterate()))
  121. {
  122. if (m_pAttachmentList->Find(pAtt) && pAtt->IsUserAttachment())
  123. {
  124. PUser pUser = (PUser) pAtt;
  125. pUser->ChannelLeaveIndication(REASON_CHANNEL_PURGED, Channel_ID);
  126. }
  127. }
  128. }
  129. /*
  130. * Channel_Type GetChannelType ()
  131. *
  132. * Public
  133. *
  134. * Functional Description:
  135. * This function returns the type of the channel. For a Channel object,
  136. * this will always be either STATIC_CHANNEL or ASSIGNED_CHANNEL, depending
  137. * on the value of the channel ID.
  138. */
  139. Channel_Type Channel::GetChannelType ()
  140. {
  141. /*
  142. * T.125 specifies that channels from 1 to 1000 are static. The rest
  143. * are dynamic (for this type of Channel object, that equates to
  144. * assigned).
  145. */
  146. return (Channel_ID <= 1000) ? STATIC_CHANNEL : ASSIGNED_CHANNEL;
  147. }
  148. /*
  149. * BOOL IsValid ()
  150. *
  151. * Public
  152. *
  153. * Functional Description:
  154. * This function returns TRUE if the Channel object is still valid, or
  155. * FALSE if it is ready to be deleted.
  156. */
  157. BOOL Channel::IsValid ()
  158. {
  159. CAttachment *pAtt;
  160. CAttachmentList deletion_list;
  161. /*
  162. * Iterate through the joined attachment list, building a list of those
  163. * attachments in the list that are no longer valid.
  164. */
  165. m_JoinedAttachmentList.Reset();
  166. while (NULL != (pAtt = m_JoinedAttachmentList.Iterate()))
  167. {
  168. if (m_pAttachmentList->Find(pAtt) == FALSE)
  169. deletion_list.Append(pAtt);
  170. }
  171. /*
  172. * Iterate through the deletion list, removing all those attachments that
  173. * were found to be invalid above.
  174. */
  175. while (NULL != (pAtt = deletion_list.Get()))
  176. {
  177. m_JoinedAttachmentList.Remove(pAtt);
  178. }
  179. return (! m_JoinedAttachmentList.IsEmpty());
  180. }
  181. /*
  182. * Void IssueMergeRequest ()
  183. *
  184. * Public
  185. *
  186. * Functional Description:
  187. * This member function is used to cause the Channel object to issue a
  188. * merge request to the pending top provier.
  189. */
  190. Void Channel::IssueMergeRequest ()
  191. {
  192. Channel_Type channel_type;
  193. ChannelAttributes channel_attributes;
  194. CChannelAttributesList merge_channel_list;
  195. CChannelIDList purge_channel_list;
  196. if (m_pConnToTopProvider != NULL)
  197. {
  198. /*
  199. * Fill in the fields of the channel attributes structure so that it
  200. * accurately describes this channel. Then put the structure into the
  201. * merge channel list.
  202. */
  203. channel_type = GetChannelType ();
  204. channel_attributes.channel_type = channel_type;
  205. switch (channel_type)
  206. {
  207. case STATIC_CHANNEL:
  208. channel_attributes.u.static_channel_attributes.channel_id =
  209. Channel_ID;
  210. break;
  211. case ASSIGNED_CHANNEL:
  212. channel_attributes.u.assigned_channel_attributes.channel_id =
  213. Channel_ID;
  214. break;
  215. }
  216. merge_channel_list.Append(&channel_attributes);
  217. /*
  218. * Send the merge request to the indicated provider.
  219. */
  220. m_pConnToTopProvider->MergeChannelsRequest(&merge_channel_list, &purge_channel_list);
  221. }
  222. }
  223. /*
  224. * Void ChannelJoinRequest ()
  225. *
  226. * Public
  227. *
  228. * Functional Description:
  229. * This function is used to add a new attachment to the attachment list.
  230. * If the user ID is valid, this routine will also issue an automatic
  231. * join confirm to the user.
  232. */
  233. Void Channel::ChannelJoinRequest (
  234. CAttachment *pOrigAtt,
  235. UserID uidInitiator,
  236. ChannelID channel_id)
  237. {
  238. /*
  239. * Make sure the attachment isn't already in the list before adding it.
  240. */
  241. if (m_JoinedAttachmentList.Find(pOrigAtt) == FALSE)
  242. {
  243. TRACE_OUT (("Channel::ChannelJoinRequest: "
  244. "user %04X joining channel %04X", (UINT) uidInitiator, (UINT) Channel_ID));
  245. m_JoinedAttachmentList.Append(pOrigAtt);
  246. }
  247. /*
  248. * If the user ID is valid, then send a join confirm to the initiating
  249. * attachment. Note that setting the user ID to 0 is a way of disabling
  250. * this behavior. This is sometimes useful when adding attachments during
  251. * a domain merge.
  252. */
  253. if (uidInitiator != 0)
  254. {
  255. pOrigAtt->ChannelJoinConfirm(RESULT_SUCCESSFUL, uidInitiator, channel_id, Channel_ID);
  256. }
  257. }
  258. /*
  259. * Void ChannelJoinConfirm ()
  260. *
  261. * Public
  262. *
  263. * Functional Description:
  264. * This function performs the same operation as JoinRequest above.
  265. */
  266. Void Channel::ChannelJoinConfirm (
  267. CAttachment *pOrigAtt,
  268. Result,
  269. UserID uidInitiator,
  270. ChannelID requested_id,
  271. ChannelID)
  272. {
  273. /*
  274. * Make sure the attachment isn't already in the list before adding it.
  275. */
  276. if (m_JoinedAttachmentList.Find(pOrigAtt) == FALSE)
  277. {
  278. TRACE_OUT (("Channel::ChannelJoinConfirm: "
  279. "user %04X joining channel %04X", (UINT) uidInitiator, (UINT) Channel_ID));
  280. m_JoinedAttachmentList.Append(pOrigAtt);
  281. }
  282. /*
  283. * Send a join confirm to the initiating attachment.
  284. */
  285. pOrigAtt->ChannelJoinConfirm(RESULT_SUCCESSFUL, uidInitiator, requested_id, Channel_ID);
  286. }
  287. /*
  288. * Void ChannelLeaveRequest ()
  289. *
  290. * Public
  291. *
  292. * Functional Description:
  293. * This function is used to remove an attachment from the attachment list.
  294. * A leave request will also be issued upward (unless this is the Top
  295. * Provider).
  296. */
  297. Void Channel::ChannelLeaveRequest (
  298. CAttachment *pOrigAtt,
  299. CChannelIDList *)
  300. {
  301. CChannelIDList channel_leave_list;
  302. /*
  303. * Make sure the attachment is in the list before trying to remove it.
  304. */
  305. if (m_JoinedAttachmentList.Remove(pOrigAtt))
  306. {
  307. TRACE_OUT (("Channel::ChannelLeaveRequest: leaving channel %04X", Channel_ID));
  308. /*
  309. * Remove the attachment from the list.
  310. */
  311. /*
  312. * If this results in an empty list, then we have more work to do.
  313. */
  314. if (m_JoinedAttachmentList.IsEmpty())
  315. {
  316. /*
  317. * If this is not the Top Provider, send a leave request upward
  318. * to the Top Provider.
  319. */
  320. if (! IsTopProvider())
  321. {
  322. TRACE_OUT (("Channel::ChannelLeaveRequest: "
  323. "sending ChannelLeaveRequest to Top Provider"));
  324. channel_leave_list.Append(Channel_ID);
  325. m_pConnToTopProvider->ChannelLeaveRequest(&channel_leave_list);
  326. }
  327. }
  328. }
  329. }
  330. /*
  331. * Void SendDataRequest ()
  332. *
  333. * Public
  334. *
  335. * Functional Description:
  336. * This function is used to send data through the channel.
  337. */
  338. Void Channel::SendDataRequest (
  339. CAttachment *pOrigAtt,
  340. UINT type,
  341. PDataPacket data_packet)
  342. {
  343. CAttachment *pAtt;
  344. ASSERT (Channel_ID == data_packet->GetChannelID());
  345. /*
  346. * If this is not the Top Provider, forward the data upward.
  347. */
  348. if (m_pConnToTopProvider != NULL)
  349. m_pConnToTopProvider->SendDataRequest(data_packet);
  350. /*
  351. * Iterate through the attachment list, sending the data to all
  352. * the attachments (except for one from whence the data came).
  353. */
  354. m_JoinedAttachmentList.Reset();
  355. while (NULL != (pAtt = m_JoinedAttachmentList.Iterate()))
  356. {
  357. if ((pAtt != pOrigAtt) || (type != MCS_SEND_DATA_INDICATION))
  358. {
  359. pAtt->SendDataIndication(type, data_packet);
  360. }
  361. }
  362. }
  363. /*
  364. * Void SendDataIndication ()
  365. *
  366. * Public
  367. *
  368. * Functional Description:
  369. * This function is used to send data through the channel.
  370. */
  371. Void Channel::SendDataIndication (
  372. PConnection,
  373. UINT type,
  374. PDataPacket data_packet)
  375. {
  376. CAttachment *pAtt;
  377. ASSERT (Channel_ID == data_packet->GetChannelID());
  378. /*
  379. * Iterate through the attachment list, sending the data to all
  380. * the attachments.
  381. */
  382. m_JoinedAttachmentList.Reset();
  383. while (NULL != (pAtt = m_JoinedAttachmentList.Iterate()))
  384. {
  385. pAtt->SendDataIndication(type, data_packet);
  386. }
  387. }