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.

1464 lines
42 KiB

  1. #include "precomp.h"
  2. DEBUG_FILEZONE(ZONE_T120_T123PSTN);
  3. /* SCFCall.cpp
  4. *
  5. * Copyright (c) 1994-1995 by DataBeam Corporation, Lexington, KY
  6. *
  7. * Abstract:
  8. * This class is instantiated by the SCF class. For each call that the
  9. * local site or remote site initiates, a SCFCall object is instantiated.
  10. * SCF can can manage 254 different calls simultaneously. For each call
  11. * there is a specific Q.933 based protocol that must occur to make the
  12. * connection valid. This object sends and receives the Q.933 packets.
  13. *
  14. * Private Instance Variables:
  15. * m_pSCF - Address of the owner of this object
  16. * Lower_Layer - Address of the layer below this layer
  17. * m_nMsgBase - The owner of this object gives it a base
  18. * number to use for OwnerCallbacks ()
  19. * Maximum_Packet_Size - Maximum transmittable packet size
  20. * Packet_Pending - Tells which packet is to be transmitted
  21. * next.
  22. * Link_Originator - TRUE is this site initiated the call
  23. *
  24. * Write_Buffer - Address of write buffer
  25. * Send_Priority - TRUE if we are suppose to respond to the
  26. * priority requested by the remote site
  27. *
  28. * Call_Reference - Call reference number of this call.
  29. * DLCI - Holds the suggested and confirmed DLCI for
  30. * this call.
  31. * Priority - Holds the suggested and confirmed priority
  32. * for this call.
  33. *
  34. * State - Holds the current state of the call.
  35. * Release_Cause - Reason the the breakup of the link.
  36. * Default_Priority - Default priority of a non-specified call.
  37. *
  38. * T303_Timeout - T303 timeout value.
  39. * T303_Handle - System timer handle to T303 timer
  40. * T303_Active - TRUE if the timer is currently active
  41. * T303_Count - Number of T303 Timeouts
  42. *
  43. * T313_Timeout - T313 timeout value
  44. * T313_Handle - System timer handle to T313 timer
  45. * T313_Active - TRUE if the timer is currently active.
  46. *
  47. * Caveats:
  48. * None.
  49. *
  50. * Authors:
  51. * James W. Lawwill
  52. */
  53. #include "scf.h"
  54. #include "scfcall.h"
  55. /*
  56. * SCFCall::SCFCall (
  57. * PTransportResources transport_resources,
  58. * IObject * owner_object
  59. * IProtocolLayer * lower_layer,
  60. * USHORT message_base,
  61. * PDataLinkParameters datalink_struct,
  62. * PMemoryManager data_request_memory_manager,
  63. * BOOL * initialized)
  64. *
  65. * Public
  66. *
  67. * Functional Description:
  68. * This is the SCFCall constructor. This routine initializes all
  69. * variables and allocates write buffer space.
  70. */
  71. SCFCall::SCFCall (
  72. CLayerSCF *owner_object,
  73. IProtocolLayer * lower_layer,
  74. USHORT message_base,
  75. PDataLinkParameters datalink_struct,
  76. PMemoryManager data_request_memory_manager,
  77. BOOL * initialized)
  78. {
  79. TRACE_OUT(("SCFCall::SCFCall"));
  80. m_pSCF = owner_object;
  81. Lower_Layer = lower_layer;
  82. m_nMsgBase = message_base;
  83. Data_Request_Memory_Manager = data_request_memory_manager;
  84. *initialized = TRUE;
  85. DataLink_Struct.k_factor = datalink_struct->k_factor;
  86. DataLink_Struct.default_k_factor = datalink_struct->default_k_factor;
  87. DataLink_Struct.n201 = datalink_struct->n201;
  88. DataLink_Struct.default_n201 = datalink_struct->default_n201;
  89. /*
  90. ** T200 is represented in milliseconds, we need to convert it to
  91. ** tenths of seconds.
  92. */
  93. DataLink_Struct.t200 = datalink_struct->t200 / 100;
  94. DataLink_Struct.default_t200 = datalink_struct->default_t200 / 100;
  95. Lower_Layer -> GetParameters (
  96. &Maximum_Packet_Size,
  97. &Lower_Layer_Prepend,
  98. &Lower_Layer_Append);
  99. Packet_Pending = NO_PACKET;
  100. Link_Originator = FALSE;
  101. State = NOT_CONNECTED;
  102. Received_Priority = FALSE;
  103. Received_K_Factor = FALSE;
  104. Received_N201 = FALSE;
  105. Received_T200 = FALSE;
  106. DLC_Identifier = 0;
  107. T303_Active = FALSE;
  108. T313_Active = FALSE;
  109. /*
  110. ** Get configuration data
  111. */
  112. T303_Timeout = DEFAULT_T303_TIMEOUT;
  113. T313_Timeout = DEFAULT_T313_TIMEOUT;
  114. Default_Priority = DEFAULT_PRIORITY;
  115. }
  116. /*
  117. * SCFCall::~SCFCall (void)
  118. *
  119. * Public
  120. *
  121. * Functional Description:
  122. * This is the SCFCall destructor. This routine cleans up the mess
  123. */
  124. SCFCall::~SCFCall (void)
  125. {
  126. if (T303_Active)
  127. {
  128. StopTimerT303 ();
  129. }
  130. if (T313_Active)
  131. {
  132. StopTimerT313 ();
  133. }
  134. }
  135. /*
  136. * SCFCall::ConnectRequest (
  137. * CallReference call_reference,
  138. * DLCI dlci,
  139. * USHORT priority)
  140. *
  141. * Public
  142. *
  143. * Functional Description:
  144. * This function is called when SCF wants to initiate a call.
  145. * As a result, we queue a SETUP command to be sent out.
  146. */
  147. SCFCallError SCFCall::ConnectRequest(
  148. CallReference call_reference,
  149. DLCI dlci,
  150. TransportPriority priority)
  151. {
  152. TRACE_OUT(("SCFCall::ConnectRequest"));
  153. Call_Reference = call_reference;
  154. DLC_Identifier = dlci;
  155. Priority = priority;
  156. Link_Originator = TRUE;
  157. if (State == NOT_CONNECTED)
  158. Packet_Pending = SETUP;
  159. return (SCFCALL_NO_ERROR);
  160. }
  161. /*
  162. * SCFCallError SCFCall::ConnectResponse (
  163. * BOOL valid_dlci)
  164. *
  165. * Public
  166. *
  167. * Functional Description:
  168. * This function is called in response to a NETWORK_CONNECT_INDICATION
  169. * callback to the owner of this object. Previously, the remote site
  170. * sent us a SETUP packet with a suggested DLCI. This DLCI is sent to
  171. * the owner in the NETWORK_CONNECT_INDICATION call. The owner calls
  172. * this function with a BOOL , telling us if the DLCI was valid.
  173. */
  174. SCFCallError SCFCall::ConnectResponse (
  175. BOOL valid_dlci)
  176. {
  177. TRACE_OUT(("SCFCall::ConnectResponse"));
  178. if (valid_dlci)
  179. {
  180. /*
  181. ** This DLCI can be used in a link. If the remote site did not
  182. ** request a priority, we set it to Default_Priority
  183. */
  184. if (Priority == 0xffff)
  185. Priority = Default_Priority;
  186. Packet_Pending = CONNECT;
  187. }
  188. else
  189. {
  190. /*
  191. ** Queue up a RELEASE COMPLETE packet
  192. */
  193. Packet_Pending = RELEASE_COMPLETE;
  194. Release_Cause = REQUESTED_CHANNEL_UNAVAILABLE;
  195. }
  196. return (SCFCALL_NO_ERROR);
  197. }
  198. /*
  199. * SCFCallError SCFCall::DisconnectRequest ()
  200. *
  201. * Public
  202. *
  203. * Functional Description:
  204. * This function is called when the SCF wants to terminate the call
  205. */
  206. SCFCallError SCFCall::DisconnectRequest ()
  207. {
  208. TRACE_OUT(("SCFCall::DisconnectRequest"));
  209. /*
  210. ** Queue up the Release Complete
  211. */
  212. if (State != NOT_CONNECTED)
  213. {
  214. Packet_Pending = RELEASE_COMPLETE;
  215. Release_Cause = NORMAL_USER_DISCONNECT;
  216. }
  217. return (SCFCALL_NO_ERROR);
  218. }
  219. /*
  220. * BOOL SCFCall::ProcessSetup (
  221. * CallReference call_reference,
  222. * LPBYTE packet_address,
  223. * USHORT packet_length)
  224. *
  225. * Public
  226. *
  227. * Functional Description:
  228. * This function processes an incoming SETUP packet
  229. */
  230. BOOL SCFCall::ProcessSetup (
  231. CallReference call_reference,
  232. LPBYTE packet_address,
  233. USHORT packet_length)
  234. {
  235. USHORT length;
  236. BOOL packet_successful;
  237. USHORT remainder_length;
  238. USHORT n201;
  239. USHORT k_factor;
  240. USHORT t200;
  241. NetworkConnectStruct connect_struct;
  242. TRACE_OUT(("SCFCall::ProcessSetup"));
  243. if (State != NOT_CONNECTED)
  244. return (FALSE);
  245. Call_Reference = call_reference;
  246. packet_successful = TRUE;
  247. remainder_length = packet_length;
  248. /*
  249. ** Bearer capability element
  250. */
  251. if (*(packet_address++) != BEARER_CAPABILITY)
  252. return (FALSE);
  253. remainder_length--;
  254. length = *(packet_address++);
  255. remainder_length--;
  256. if (length != 3)
  257. return (FALSE);
  258. /*
  259. ** Verify that the Bearer Capability is correct
  260. */
  261. if (*(packet_address) !=
  262. (EXTENSION | CODING_STANDARD | INFORMATION_TRANSFER_CAPABILITY))
  263. {
  264. return (FALSE);
  265. }
  266. if (*(packet_address + 1) != (EXTENSION | TRANSFER_MODE))
  267. {
  268. return (FALSE);
  269. }
  270. if (*(packet_address + 2) !=
  271. (EXTENSION | LAYER_2_IDENT | USER_INFORMATION_LAYER_2))
  272. {
  273. return (FALSE);
  274. }
  275. packet_address += length;
  276. remainder_length -= length;
  277. /*
  278. ** DLCI element
  279. */
  280. if (*(packet_address++) != DLCI_ELEMENT)
  281. return (FALSE);
  282. remainder_length--;
  283. length = *(packet_address++);
  284. if (length != 2)
  285. return (FALSE);
  286. remainder_length--;
  287. /*
  288. ** If the Preferred/Exclusive bit is set, its illegal
  289. */
  290. if (((*(packet_address) & PREFERRED_EXCLUSIVE) == PREFERRED_EXCLUSIVE) ||
  291. ((*(packet_address + 1) & EXTENSION) == 0))
  292. {
  293. return (FALSE);
  294. }
  295. DLC_Identifier = (*(packet_address) & 0x3f) << 4;
  296. DLC_Identifier |= ((*(packet_address + 1) & 0x78) >> 3);
  297. packet_address += length;
  298. remainder_length -= length;
  299. Priority = 0xffff;
  300. /*
  301. ** Go thru each of the elements and decode them
  302. */
  303. while (remainder_length)
  304. {
  305. switch (*(packet_address++))
  306. {
  307. case X213_PRIORITY:
  308. length = *(packet_address++);
  309. remainder_length--;
  310. if (((*(packet_address) & EXTENSION) == 1) ||
  311. ((*(packet_address + 1) & EXTENSION) == 0))
  312. {
  313. ERROR_OUT(("SCFCall: ProcessSetup: SETUP packet: Illegal X.213 priority"));
  314. return (FALSE);
  315. }
  316. Priority = (*packet_address & 0x0f);
  317. packet_address += length;
  318. remainder_length -= length;
  319. Received_Priority = TRUE;
  320. break;
  321. case LINK_LAYER_CORE_PARAMETERS:
  322. length = *(packet_address++);
  323. remainder_length -= (length + 1);
  324. while (length)
  325. {
  326. switch (*(packet_address++))
  327. {
  328. case FMIF_SIZE:
  329. /*
  330. ** N201 is a Q922 parameter. It is the number of
  331. ** maximum information bytes in a packet
  332. */
  333. n201 =
  334. ((*packet_address << 7) |
  335. (*(packet_address + 1) & 0x7f));
  336. if ((*(packet_address+1) & EXTENSION) == EXTENSION)
  337. {
  338. length -= 2;
  339. packet_address += 2;
  340. }
  341. else
  342. {
  343. packet_address += 4;
  344. length -= 4;
  345. }
  346. /*
  347. ** If the requested n201 value is less than our
  348. ** value, it will be our new N201, otherwise send
  349. ** our N201 back as the arbitrated value.
  350. */
  351. if (n201 < DataLink_Struct.n201)
  352. DataLink_Struct.n201 = n201;
  353. Received_N201 = TRUE;
  354. TRACE_OUT(("SCFCALL: ProcessSetup: n201 = %d", DataLink_Struct.n201));
  355. break;
  356. default:
  357. while ((*(packet_address++) & EXTENSION) == 0)
  358. length--;
  359. length--;
  360. break;
  361. }
  362. length--;
  363. }
  364. break;
  365. case LINK_LAYER_PROTOCOL_PARAMETERS:
  366. length = *(packet_address++);
  367. remainder_length -= (length + 1);
  368. while (length)
  369. {
  370. switch (*(packet_address++))
  371. {
  372. case TRANSMIT_WINDOW_SIZE_IDENTIFIER:
  373. /*
  374. ** The Window size is the maximum number of
  375. ** outstanding packets at any one time
  376. */
  377. k_factor = *packet_address & 0x7f;
  378. packet_address++;
  379. length--;
  380. /*
  381. ** If the requested k_factor value is less than our
  382. ** value, it will be our new k_factor, otherwise
  383. ** send our k_factor back as the arbitrated value.
  384. */
  385. if (k_factor < DataLink_Struct.k_factor)
  386. DataLink_Struct.k_factor = k_factor;
  387. Received_K_Factor = TRUE;
  388. TRACE_OUT(("SCFCALL: ProcessSetup: k_factor = %d", DataLink_Struct.k_factor));
  389. break;
  390. case RETRANSMISSION_TIMER_IDENTIFIER:
  391. /*
  392. ** t200 is the timeout value before retransmission
  393. */
  394. t200 = ((*packet_address << 7) |
  395. (*(packet_address + 1) & 0x7f));
  396. packet_address += 2;
  397. length -= 2;
  398. /*
  399. ** If the requested t200 value is too small,
  400. ** value, it will be our new T200, otherwise
  401. ** send our T200 back as the arbitrated value.
  402. */
  403. if (t200 > DataLink_Struct.t200)
  404. DataLink_Struct.t200 = t200;
  405. Received_T200 = TRUE;
  406. TRACE_OUT(("SCFCALL: ProcessSetup: t200 = %d", DataLink_Struct.t200));
  407. break;
  408. default:
  409. while ((*(packet_address++) & EXTENSION) == 0)
  410. length--;
  411. length--;
  412. break;
  413. }
  414. length--;
  415. }
  416. break;
  417. case END_TO_END_DELAY:
  418. case CALLING_PARTY_SUBADDRESS:
  419. case CALLED_PARTY_SUBADDRESS:
  420. default:
  421. TRACE_OUT(("SCFCall: ProcessSetup: SETUP packet: Option 0x%x"
  422. "requested, but not supported", *(packet_address-1)));
  423. length = *(packet_address);
  424. packet_address += (length + 1);
  425. remainder_length -= (length + 1);
  426. break;
  427. }
  428. remainder_length--;
  429. }
  430. if (Received_N201 == FALSE)
  431. DataLink_Struct.n201 = DataLink_Struct.default_n201;
  432. if (Received_K_Factor == FALSE)
  433. DataLink_Struct.k_factor = DataLink_Struct.default_k_factor;
  434. if (Received_T200 == FALSE)
  435. DataLink_Struct.t200 = DataLink_Struct.default_t200;
  436. if (packet_successful)
  437. {
  438. /*
  439. ** If the packet was successfully decoded, tell the owner the requested
  440. ** DLCI and priority.
  441. */
  442. connect_struct.dlci = DLC_Identifier;
  443. connect_struct.priority = Priority;
  444. connect_struct.datalink_struct = &DataLink_Struct;
  445. /*
  446. ** Convert t200 into milliseconds
  447. */
  448. DataLink_Struct.t200 *= 100;
  449. m_pSCF->OwnerCallback(m_nMsgBase + NETWORK_CONNECT_INDICATION, 0, 0, &connect_struct);
  450. DataLink_Struct.t200 /= 100;
  451. }
  452. return (packet_successful);
  453. }
  454. /*
  455. * BOOL SCFCall::ProcessConnect (
  456. * LPBYTE packet_address,
  457. * USHORT packet_length)
  458. *
  459. * Public
  460. *
  461. * Functional Description:
  462. * This function processes an incoming CONNECT packet
  463. */
  464. BOOL SCFCall::ProcessConnect (
  465. LPBYTE packet_address,
  466. USHORT packet_length)
  467. {
  468. TRACE_OUT(("SCFCall::ProcessConnect"));
  469. BOOL packet_successful;
  470. USHORT length;
  471. DLCI exclusive_dlci;
  472. USHORT remainder_length;
  473. USHORT k_factor;
  474. USHORT t200;
  475. if (State != SETUP_SENT)
  476. {
  477. ERROR_OUT(("SCFCall: ProcessConnect: Call in wrong state"));
  478. return (FALSE);
  479. }
  480. remainder_length = packet_length;
  481. packet_successful = TRUE;
  482. /*
  483. ** DLCI element
  484. */
  485. if (*(packet_address++) != DLCI_ELEMENT)
  486. {
  487. ERROR_OUT(("SCFCall: ProcessConnect: DLCI_ELEMENT not in packet"));
  488. return (FALSE);
  489. }
  490. remainder_length--;
  491. length = *(packet_address++);
  492. if (length != 2)
  493. {
  494. ERROR_OUT(("SCFCall: ProcessConnect: DLCI length must be 2"));
  495. return (FALSE);
  496. }
  497. remainder_length--;
  498. /*
  499. ** If the Preferred/Exclusive bit is not set, its illegal
  500. */
  501. if (((*(packet_address) & PREFERRED_EXCLUSIVE) == 0) ||
  502. ((*(packet_address + 1) & EXTENSION) == 0))
  503. {
  504. ERROR_OUT(("SCFCall: CONNECT: Illegal DLCI"));
  505. return (FALSE);
  506. }
  507. /*
  508. ** Get the DLCI
  509. */
  510. exclusive_dlci = (*(packet_address) & 0x3f) << 4;
  511. exclusive_dlci |= ((*(packet_address + 1) & 0x78) >> 3);
  512. packet_address += length;
  513. remainder_length -= length;
  514. /*
  515. ** Go thru each of the elements and decode them
  516. */
  517. while (remainder_length != 0)
  518. {
  519. switch (*(packet_address++))
  520. {
  521. case X213_PRIORITY:
  522. length = *(packet_address++);
  523. remainder_length--;
  524. if ((*(packet_address) & EXTENSION) == 0)
  525. {
  526. ERROR_OUT(("SCFCall: DataIndication: CONNECT packet: Illegal X.213 priority"));
  527. return (FALSE);
  528. }
  529. Priority = (*packet_address & 0x0f);
  530. packet_address += length;
  531. remainder_length -= length;
  532. break;
  533. case LINK_LAYER_CORE_PARAMETERS:
  534. length = *(packet_address++);
  535. remainder_length -= (length + 1);
  536. while (length)
  537. {
  538. switch (*(packet_address++))
  539. {
  540. case FMIF_SIZE:
  541. /*
  542. ** FMIF_Size is the max. number of bytes allowed in
  543. ** a information packet
  544. */
  545. DataLink_Struct.n201 =
  546. ((*packet_address << 7) |
  547. (*(packet_address + 1) & 0x7f));
  548. if ((*(packet_address+1) & EXTENSION) == EXTENSION)
  549. {
  550. length -= 2;
  551. packet_address += 2;
  552. }
  553. else
  554. {
  555. packet_address += 4;
  556. length -= 4;
  557. }
  558. Received_N201 = TRUE;
  559. TRACE_OUT(("SCFCALL: ProcessConnect: n201 = %d", DataLink_Struct.n201));
  560. break;
  561. default:
  562. while ((*(packet_address++) & EXTENSION) == 0)
  563. length--;
  564. length--;
  565. break;
  566. }
  567. length--;
  568. }
  569. break;
  570. case LINK_LAYER_PROTOCOL_PARAMETERS:
  571. length = *(packet_address++);
  572. remainder_length -= (length + 1);
  573. while (length)
  574. {
  575. switch (*(packet_address++))
  576. {
  577. case TRANSMIT_WINDOW_SIZE_IDENTIFIER:
  578. /*
  579. ** The Window size is the maximum number of
  580. ** outstanding packets at any one time
  581. */
  582. k_factor = *packet_address & 0x7f;
  583. packet_address++;
  584. length--;
  585. DataLink_Struct.k_factor = k_factor;
  586. Received_K_Factor = TRUE;
  587. TRACE_OUT(("SCFCALL: ProcessConnect: k_factor = %d", DataLink_Struct.k_factor));
  588. break;
  589. case RETRANSMISSION_TIMER_IDENTIFIER:
  590. /*
  591. ** t200 is the timeout value before retransmission
  592. */
  593. t200 = ((*packet_address << 7) |
  594. (*(packet_address + 1) & 0x7f));
  595. packet_address += 2;
  596. length -= 2;
  597. DataLink_Struct.t200 = t200;
  598. Received_T200 = TRUE;
  599. TRACE_OUT(("SCFCALL: ProcessConnect: t200 = %d", DataLink_Struct.t200));
  600. break;
  601. default:
  602. while ((*(packet_address++) & EXTENSION) == 0)
  603. length--;
  604. length--;
  605. break;
  606. }
  607. length--;
  608. }
  609. break;
  610. case END_TO_END_DELAY:
  611. case CALLING_PARTY_SUBADDRESS:
  612. case CALLED_PARTY_SUBADDRESS:
  613. default:
  614. TRACE_OUT(("SCFCall: DataIndication: CONNECT packet: Option "
  615. "requested, but not supported", *(packet_address-1)));
  616. length = *(packet_address++);
  617. remainder_length--;
  618. packet_address += length;
  619. remainder_length -= length;
  620. break;
  621. }
  622. remainder_length--;
  623. }
  624. if (Received_N201 == FALSE)
  625. DataLink_Struct.n201 = DataLink_Struct.default_n201;
  626. if (Received_K_Factor == FALSE)
  627. DataLink_Struct.k_factor = DataLink_Struct.default_k_factor;
  628. if (Received_T200 == FALSE)
  629. DataLink_Struct.t200 = DataLink_Struct.default_t200;
  630. /*
  631. ** If the packet was successfully decoded, queue up the CONNECT ACK
  632. */
  633. if (packet_successful)
  634. {
  635. Packet_Pending = CONNECT_ACKNOWLEDGE;
  636. StopTimerT303 ();
  637. }
  638. return (packet_successful);
  639. }
  640. /*
  641. * BOOL SCFCall::ProcessConnectAcknowledge (
  642. * LPBYTE,
  643. * USHORT)
  644. *
  645. * Public
  646. *
  647. * Functional Description:
  648. * This function processes an incoming CONNECT ACK packet
  649. *
  650. */
  651. BOOL SCFCall::ProcessConnectAcknowledge (
  652. LPBYTE,
  653. USHORT)
  654. {
  655. TRACE_OUT(("SCFCall::ProcessConnectAcknowledge"));
  656. if (State != CONNECT_SENT)
  657. return (FALSE);
  658. StopTimerT313 ();
  659. return (TRUE);
  660. }
  661. /*
  662. * BOOL SCFCall::ProcessReleaseComplete (
  663. * LPBYTE packet_address,
  664. * USHORT)
  665. *
  666. * Public
  667. *
  668. * Functional Description:
  669. * This function processes an incoming RELEASE COMPLETE
  670. */
  671. BOOL SCFCall::ProcessReleaseComplete (
  672. LPBYTE packet_address,
  673. USHORT)
  674. {
  675. TRACE_OUT(("SCFCall::ProcessReleaseComplete"));
  676. USHORT cause;
  677. if (State == NOT_CONNECTED)
  678. return (FALSE);
  679. if (*(packet_address++) == CAUSE)
  680. {
  681. packet_address++;
  682. if ((*(packet_address++) & EXTENSION) == 0)
  683. packet_address++;
  684. cause = *(packet_address++) & (~EXTENSION);
  685. TRACE_OUT(("SCFCall: Disconnect: cause = %d", cause));
  686. }
  687. State = NOT_CONNECTED;
  688. /*
  689. ** Tell the owner about the Disconnection
  690. */
  691. m_pSCF->OwnerCallback(m_nMsgBase + NETWORK_DISCONNECT_INDICATION,
  692. (void *) DLC_Identifier,
  693. (void *) (ULONG_PTR)(((Link_Originator << 16) | cause)));
  694. return (TRUE);
  695. }
  696. /*
  697. * void SCFCall::PollTransmitter (
  698. * USHORT data_to_transmit,
  699. * USHORT * pending_data);
  700. *
  701. * Public
  702. *
  703. * Functional Description:
  704. * This function is called to transmit any queued up packets
  705. */
  706. void SCFCall::PollTransmitter (
  707. USHORT data_to_transmit,
  708. USHORT * pending_data)
  709. {
  710. // TRACE_OUT(("SCFCall::PollTransmitter"));
  711. NetworkConnectStruct connect_struct;
  712. if (data_to_transmit & PROTOCOL_CONTROL_DATA)
  713. {
  714. switch (Packet_Pending)
  715. {
  716. case SETUP:
  717. SendSetup ();
  718. break;
  719. case CONNECT:
  720. SendConnect ();
  721. break;
  722. case CONNECT_ACKNOWLEDGE:
  723. SendConnectAcknowledge ();
  724. if (Packet_Pending != CONNECT_ACKNOWLEDGE)
  725. {
  726. /*
  727. ** If the CONNECT ACK packet was sent, notify the owner
  728. */
  729. connect_struct.dlci = DLC_Identifier;
  730. connect_struct.priority = Priority;
  731. connect_struct.datalink_struct = &DataLink_Struct;
  732. /*
  733. ** Convert t200 to milliseconds
  734. */
  735. DataLink_Struct.t200 *= 100;
  736. m_pSCF->OwnerCallback(m_nMsgBase + NETWORK_CONNECT_CONFIRM, 0, 0, &connect_struct);
  737. DataLink_Struct.t200 /= 100;
  738. }
  739. break;
  740. case RELEASE_COMPLETE:
  741. SendReleaseComplete ();
  742. if (Packet_Pending != RELEASE_COMPLETE)
  743. {
  744. /*
  745. ** If the RELEASE COMPLETE packet was sent, notify
  746. ** the owner
  747. */
  748. m_pSCF->OwnerCallback(m_nMsgBase + NETWORK_DISCONNECT_INDICATION,
  749. (void *) DLC_Identifier,
  750. (void *) ((((ULONG_PTR) Link_Originator) << 16) | Release_Cause));
  751. }
  752. break;
  753. }
  754. if (Packet_Pending != NO_PACKET)
  755. *pending_data = PROTOCOL_CONTROL_DATA;
  756. else
  757. *pending_data = 0;
  758. }
  759. return;
  760. }
  761. /*
  762. * void SCFCall::SendSetup (void);
  763. *
  764. * Functional Description
  765. * This function attempts to send out a SETUP packet. The T303 timer
  766. * is started. If a CONNECT is not received before the timer expires,
  767. * we terminate the link.
  768. *
  769. * Formal Parameters
  770. * None
  771. *
  772. * Return Value
  773. * None
  774. *
  775. * Side Effects
  776. * If this function is able to send a SETUP packet to the lower layer,
  777. * it sets the Packet_Pending variable to NO_PACKET
  778. *
  779. * Caveats
  780. * None
  781. */
  782. void SCFCall::SendSetup (void)
  783. {
  784. TRACE_OUT(("SCFCall::SendSetup"));
  785. LPBYTE packet_address;
  786. ULONG bytes_accepted;
  787. USHORT total_length;
  788. PMemory memory;
  789. total_length = SETUP_PACKET_SIZE + Lower_Layer_Prepend +
  790. Lower_Layer_Append;
  791. memory = Data_Request_Memory_Manager -> AllocateMemory (
  792. NULL,
  793. total_length);
  794. if (memory == NULL)
  795. return;
  796. packet_address = memory -> GetPointer ();
  797. packet_address += Lower_Layer_Prepend;
  798. *(packet_address++) = Q931_PROTOCOL_DISCRIMINATOR;
  799. *(packet_address++) = 1;
  800. *(packet_address++) = (UChar) Call_Reference;
  801. *(packet_address++) = SETUP;
  802. /*
  803. ** Bearer Capability
  804. */
  805. *(packet_address++) = BEARER_CAPABILITY;
  806. *(packet_address++) = 3;
  807. *(packet_address++) =
  808. EXTENSION | CODING_STANDARD | INFORMATION_TRANSFER_CAPABILITY;
  809. *(packet_address++) = EXTENSION | TRANSFER_MODE;
  810. *(packet_address++) = EXTENSION | LAYER_2_IDENT | USER_INFORMATION_LAYER_2;
  811. /*
  812. ** DLCI
  813. */
  814. *(packet_address++) = DLCI_ELEMENT;
  815. *(packet_address++) = 2;
  816. *(packet_address++) = (DLC_Identifier >> 4);
  817. *(packet_address++) = EXTENSION | ((DLC_Identifier & 0x0f) << 3);
  818. /*
  819. ** Link Layer Core Parameters
  820. */
  821. *(packet_address++) = LINK_LAYER_CORE_PARAMETERS;
  822. *(packet_address++) = 3;
  823. *(packet_address++) = FMIF_SIZE;
  824. *(packet_address++) = (DataLink_Struct.n201 >> 7);
  825. *(packet_address++) = EXTENSION | (DataLink_Struct.n201 & 0x7f);
  826. /*
  827. ** Link Layer Protocol Parameters
  828. */
  829. *(packet_address++) = LINK_LAYER_PROTOCOL_PARAMETERS;
  830. *(packet_address++) = 5;
  831. *(packet_address++) = TRANSMIT_WINDOW_SIZE_IDENTIFIER;
  832. *(packet_address++) = EXTENSION | DataLink_Struct.k_factor;
  833. *(packet_address++) = RETRANSMISSION_TIMER_IDENTIFIER;
  834. *(packet_address++) = (DataLink_Struct.t200 >> 7) & 0x7f;
  835. *(packet_address++) = EXTENSION | (DataLink_Struct.t200 & 0x7f);
  836. /*
  837. ** X.213 Priority
  838. */
  839. *(packet_address++) = X213_PRIORITY;
  840. *(packet_address++) = 2;
  841. *(packet_address++) = (UChar) Priority;
  842. /*
  843. ** The next byte contains the lowest priority acceptable, 0
  844. */
  845. *(packet_address++) = EXTENSION | 0;
  846. /*
  847. ** Attempt to send the packet down
  848. */
  849. Lower_Layer -> DataRequest (
  850. 0,
  851. memory,
  852. &bytes_accepted);
  853. if (bytes_accepted == total_length)
  854. {
  855. T303_Count = 0;
  856. Packet_Pending = NO_PACKET;
  857. State = SETUP_SENT;
  858. StartTimerT303 ();
  859. }
  860. Data_Request_Memory_Manager -> FreeMemory (memory);
  861. }
  862. /*
  863. * void SCFCall::SendConnect (void);
  864. *
  865. * Functional Description
  866. * This function attempts to send out a CONNECT packet. The T313 timer
  867. * is started. If a CONNECT ACK is not received before the timer expires,
  868. * we terminate the link.
  869. *
  870. * Formal Parameters
  871. * None
  872. *
  873. * Return Value
  874. * None
  875. *
  876. * Side Effects
  877. * If this function is able to send a CONNECT packet to the lower layer,
  878. * it sets the Packet_Pending variable to NO_PACKET
  879. *
  880. * Caveats
  881. * None
  882. *
  883. */
  884. void SCFCall::SendConnect (void)
  885. {
  886. TRACE_OUT(("SCFCall::SendConnect"));
  887. LPBYTE packet_address;
  888. LPBYTE length_address;
  889. ULONG bytes_accepted;
  890. USHORT total_length;
  891. PMemory memory;
  892. total_length = CONNECT_PACKET_BASE_SIZE + Lower_Layer_Prepend +
  893. Lower_Layer_Append;
  894. if (Received_N201)
  895. total_length += 5;
  896. if (Received_K_Factor || Received_T200)
  897. {
  898. total_length += 2;
  899. if (Received_K_Factor)
  900. total_length += 2;
  901. if (Received_T200)
  902. total_length += 3;
  903. }
  904. if (Received_Priority)
  905. total_length += 3;
  906. /*
  907. ** Prepare the CONNECT command and send it to the lower layer
  908. */
  909. memory = Data_Request_Memory_Manager -> AllocateMemory (
  910. NULL,
  911. total_length);
  912. if (memory == NULL)
  913. return;
  914. packet_address = memory -> GetPointer ();
  915. packet_address += Lower_Layer_Prepend;
  916. *(packet_address++) = Q931_PROTOCOL_DISCRIMINATOR;
  917. *(packet_address++) = 1;
  918. *(packet_address++) = REMOTE_CALL_REFERENCE | Call_Reference;
  919. *(packet_address++) = CONNECT;
  920. /*
  921. ** DLCI
  922. */
  923. *(packet_address++) = DLCI_ELEMENT;
  924. *(packet_address++) = 2;
  925. *(packet_address++) = PREFERRED_EXCLUSIVE | (DLC_Identifier >> 4);
  926. *(packet_address++) = EXTENSION | ((DLC_Identifier & 0x0f) << 3);
  927. if (Received_N201)
  928. {
  929. /*
  930. ** Link Layer Core Parameters
  931. */
  932. *(packet_address++) = LINK_LAYER_CORE_PARAMETERS;
  933. *(packet_address++) = 3;
  934. *(packet_address++) = FMIF_SIZE;
  935. *(packet_address++) = (DataLink_Struct.n201 >> 7);
  936. *(packet_address++) = EXTENSION | (DataLink_Struct.n201 & 0x7f);
  937. }
  938. else
  939. DataLink_Struct.n201 = DataLink_Struct.default_n201;
  940. if (Received_K_Factor || Received_T200)
  941. {
  942. /*
  943. ** Link Layer Protocol Parameters
  944. */
  945. *(packet_address++) = LINK_LAYER_PROTOCOL_PARAMETERS;
  946. length_address = packet_address;
  947. *(packet_address++) = 0;
  948. if (Received_K_Factor)
  949. {
  950. *length_address += 2;
  951. *(packet_address++) = TRANSMIT_WINDOW_SIZE_IDENTIFIER;
  952. *(packet_address++) = EXTENSION | DataLink_Struct.k_factor;
  953. }
  954. if (Received_T200)
  955. {
  956. *length_address += 3;
  957. *(packet_address++) = RETRANSMISSION_TIMER_IDENTIFIER;
  958. *(packet_address++) = (DataLink_Struct.t200 >> 7) & 0x7f;
  959. *(packet_address++) = EXTENSION | (DataLink_Struct.t200 & 0x7f);
  960. }
  961. }
  962. if (Received_K_Factor == FALSE)
  963. DataLink_Struct.k_factor = DataLink_Struct.default_k_factor;
  964. if (Received_T200 == FALSE)
  965. DataLink_Struct.t200 = DataLink_Struct.default_t200;
  966. if (Received_Priority)
  967. {
  968. /*
  969. ** X.213 Priority
  970. */
  971. *(packet_address++) = X213_PRIORITY;
  972. *(packet_address++) = 1;
  973. *(packet_address++) = (BYTE) (EXTENSION | Priority);
  974. }
  975. /*
  976. ** Attempt to send the packet to the lower layer
  977. */
  978. Lower_Layer -> DataRequest (
  979. 0,
  980. memory,
  981. &bytes_accepted);
  982. if (bytes_accepted == total_length)
  983. {
  984. StartTimerT313 ();
  985. Packet_Pending = NO_PACKET;
  986. State = CONNECT_SENT;
  987. }
  988. Data_Request_Memory_Manager -> FreeMemory (memory);
  989. }
  990. /*
  991. * void SCFCall::SendConnectAcknowledge (void);
  992. *
  993. * Functional Description
  994. * This function attempts to send out a CONNECT ACKNOWLEDGE packet
  995. *
  996. * Formal Parameters
  997. * None
  998. *
  999. * Return Value
  1000. * None
  1001. *
  1002. * Side Effects
  1003. * If this function is able to send the packet to the lower layer,
  1004. * it sets the Packet_Pending variable to NO_PACKET
  1005. *
  1006. * Caveats
  1007. * None
  1008. *
  1009. */
  1010. void SCFCall::SendConnectAcknowledge (void)
  1011. {
  1012. TRACE_OUT(("SCFCall::SendConnectAcknowledge"));
  1013. LPBYTE packet_address;
  1014. USHORT total_length;
  1015. PMemory memory;
  1016. ULONG bytes_accepted;
  1017. total_length = CONNECT_ACK_PACKET_SIZE + Lower_Layer_Prepend +
  1018. Lower_Layer_Append;
  1019. /*
  1020. ** Prepare the command and send it to the lower layer
  1021. */
  1022. memory = Data_Request_Memory_Manager -> AllocateMemory (
  1023. NULL,
  1024. total_length);
  1025. if (memory == NULL)
  1026. return;
  1027. packet_address = memory -> GetPointer ();
  1028. packet_address += Lower_Layer_Prepend;
  1029. *(packet_address++) = Q931_PROTOCOL_DISCRIMINATOR;
  1030. *(packet_address++) = 1;
  1031. *(packet_address++) = (UChar) Call_Reference;
  1032. *(packet_address++) = CONNECT_ACKNOWLEDGE;
  1033. Lower_Layer -> DataRequest (
  1034. 0,
  1035. memory,
  1036. &bytes_accepted);
  1037. if (bytes_accepted == total_length)
  1038. {
  1039. State = CALL_ESTABLISHED;
  1040. Packet_Pending = NO_PACKET;
  1041. }
  1042. Data_Request_Memory_Manager -> FreeMemory (memory);
  1043. }
  1044. /*
  1045. * void SCFCall::SendReleaseComplete (void);
  1046. *
  1047. * Functional Description
  1048. * This function attempts to send out a RELEASE COMPLETE packet
  1049. *
  1050. * Formal Parameters
  1051. * None
  1052. *
  1053. * Return Value
  1054. * None
  1055. *
  1056. * Side Effects
  1057. * If this function is able to send a RELEASE COMPLETE packet to the lower
  1058. * layer, it sets the Packet_Pending variable to NO_PACKET
  1059. *
  1060. * Caveats
  1061. * None
  1062. *
  1063. */
  1064. void SCFCall::SendReleaseComplete (void)
  1065. {
  1066. TRACE_OUT(("SCFCall::SendReleaseComplete"));
  1067. LPBYTE packet_address;
  1068. ULONG bytes_accepted;
  1069. USHORT total_length;
  1070. PMemory memory;
  1071. total_length = RELEASE_COMPLETE_PACKET_SIZE + Lower_Layer_Prepend +
  1072. Lower_Layer_Append;
  1073. /*
  1074. ** Prepare the command and send it to the lower layer
  1075. */
  1076. memory = Data_Request_Memory_Manager -> AllocateMemory (
  1077. NULL,
  1078. total_length);
  1079. if (memory == NULL)
  1080. return;
  1081. packet_address = memory -> GetPointer ();
  1082. packet_address += Lower_Layer_Prepend;
  1083. *(packet_address++) = Q931_PROTOCOL_DISCRIMINATOR;
  1084. *(packet_address++) = 1;
  1085. if (Link_Originator)
  1086. *(packet_address++) = (UChar) Call_Reference;
  1087. else
  1088. *(packet_address++) = 0x80 | Call_Reference;
  1089. *(packet_address++) = RELEASE_COMPLETE;
  1090. /*
  1091. ** Append the CAUSE for the link breakup
  1092. */
  1093. *(packet_address++) = CAUSE;
  1094. *(packet_address++) = 2;
  1095. *(packet_address++) = EXTENSION;
  1096. *(packet_address++) = EXTENSION | Release_Cause;
  1097. Lower_Layer -> DataRequest (
  1098. 0,
  1099. memory,
  1100. &bytes_accepted);
  1101. if (bytes_accepted == total_length)
  1102. {
  1103. State = NOT_CONNECTED;
  1104. Packet_Pending = NO_PACKET;
  1105. }
  1106. Data_Request_Memory_Manager -> FreeMemory (memory);
  1107. }
  1108. /*
  1109. * void SCFCall::StartTimerT303 (void);
  1110. *
  1111. * Functional Description
  1112. * This function Starts the T303 Timer. This is started when we send
  1113. * out the SETUP packet. It is stopped when we receive a CONNECT
  1114. * packet. If it expires we terminate the link.
  1115. *
  1116. * Formal Parameters
  1117. * None
  1118. *
  1119. * Return Value
  1120. * None
  1121. *
  1122. * Side Effects
  1123. * None
  1124. *
  1125. * Caveats
  1126. * None
  1127. *
  1128. */
  1129. void SCFCall::StartTimerT303 (void)
  1130. {
  1131. TRACE_OUT(("SCFCall::StartTimerT303"));
  1132. if (T303_Active)
  1133. StopTimerT303 ();
  1134. T303_Handle = g_pSystemTimer->CreateTimerEvent(
  1135. T303_Timeout,
  1136. TIMER_EVENT_ONE_SHOT,
  1137. this,
  1138. (PTimerFunction) &SCFCall::T303Timeout);
  1139. T303_Active = TRUE;
  1140. }
  1141. /*
  1142. * void SCFCall::StopTimerT303 (void);
  1143. *
  1144. * Functional Description
  1145. * This function stops the T303 Timer. This is called when we receive
  1146. * the CONNECT packet. As a result, we stop the timer.
  1147. *
  1148. * Formal Parameters
  1149. * None
  1150. *
  1151. * Return Value
  1152. * None
  1153. *
  1154. * Side Effects
  1155. * None
  1156. *
  1157. * Caveats
  1158. * None
  1159. *
  1160. */
  1161. void SCFCall::StopTimerT303 (void)
  1162. {
  1163. TRACE_OUT(("SCFCall::StopTimerT303"));
  1164. if (T303_Active)
  1165. {
  1166. g_pSystemTimer->DeleteTimerEvent(T303_Handle);
  1167. T303_Active = FALSE;
  1168. }
  1169. }
  1170. /*
  1171. * void SCFCall::T303Timeout (
  1172. * TimerEventHandle);
  1173. *
  1174. * Functional Description
  1175. * This function is called by the System timer when the T303 timeout
  1176. * expires. As a result, we terminate the link.
  1177. *
  1178. * Formal Parameters
  1179. * None used
  1180. *
  1181. * Return Value
  1182. * None
  1183. *
  1184. * Side Effects
  1185. * None
  1186. *
  1187. * Caveats
  1188. * None
  1189. *
  1190. */
  1191. void SCFCall::T303Timeout (
  1192. TimerEventHandle)
  1193. {
  1194. TRACE_OUT(("SCFCall: T303Timeout"));
  1195. if (T303_Count >= 1)
  1196. State = NOT_CONNECTED;
  1197. T303_Count++;
  1198. Packet_Pending = RELEASE_COMPLETE;
  1199. Release_Cause = NORMAL_USER_DISCONNECT;
  1200. }
  1201. /*
  1202. * void SCFCall::StartTimerT313 (void);
  1203. *
  1204. * Functional Description
  1205. * This function Starts the T313 Timer. This is started when we send
  1206. * out the CONNECT packet. It is stopped when we receive a CONNECT ACK
  1207. * packet. If it expires we terminate the link.
  1208. *
  1209. * Formal Parameters
  1210. * None
  1211. *
  1212. * Return Value
  1213. * None
  1214. *
  1215. * Side Effects
  1216. * None
  1217. *
  1218. * Caveats
  1219. * None
  1220. *
  1221. */
  1222. void SCFCall::StartTimerT313 (void)
  1223. {
  1224. TRACE_OUT(("SCFCall: StartTimerT313"));
  1225. if (T313_Active)
  1226. StopTimerT313 ();
  1227. T313_Handle = g_pSystemTimer->CreateTimerEvent(
  1228. T313_Timeout,
  1229. TIMER_EVENT_ONE_SHOT,
  1230. this,
  1231. (PTimerFunction) &SCFCall::T313Timeout);
  1232. T313_Active = TRUE;
  1233. }
  1234. /*
  1235. * void SCFCall::StopTimerT313 (void);
  1236. *
  1237. * Functional Description
  1238. * This function stops the T313 Timer. This is called when we receive
  1239. * the CONNECT ACK packet. As a result, we stop the timer.
  1240. *
  1241. * Formal Parameters
  1242. * None
  1243. *
  1244. * Return Value
  1245. * None
  1246. *
  1247. * Side Effects
  1248. * None
  1249. *
  1250. * Caveats
  1251. * None
  1252. *
  1253. */
  1254. void SCFCall::StopTimerT313 (void)
  1255. {
  1256. TRACE_OUT(("SCFCall: StopTimerT313"));
  1257. if (T313_Active)
  1258. {
  1259. g_pSystemTimer->DeleteTimerEvent(T313_Handle);
  1260. T313_Active = FALSE;
  1261. }
  1262. }
  1263. /*
  1264. * void SCFCall::T313Timeout (
  1265. * TimerEventHandle);
  1266. *
  1267. * Functional Description
  1268. * This function is called by the System timer when the T313 timeout
  1269. * expires. As a result, we terminate the link.
  1270. *
  1271. * Formal Parameters
  1272. * None used
  1273. *
  1274. * Return Value
  1275. * None
  1276. *
  1277. * Side Effects
  1278. * None
  1279. *
  1280. * Caveats
  1281. * None
  1282. *
  1283. */
  1284. void SCFCall::T313Timeout (
  1285. TimerEventHandle)
  1286. {
  1287. TRACE_OUT(("SCFCall: T313Timeout"));
  1288. State = NOT_CONNECTED;
  1289. Packet_Pending = RELEASE_COMPLETE;
  1290. Release_Cause = NORMAL_USER_DISCONNECT;
  1291. }