1465 lines
42 KiB
C++
1465 lines
42 KiB
C++
|
#include "precomp.h"
|
||
|
DEBUG_FILEZONE(ZONE_T120_T123PSTN);
|
||
|
/* SCFCall.cpp
|
||
|
*
|
||
|
* Copyright (c) 1994-1995 by DataBeam Corporation, Lexington, KY
|
||
|
*
|
||
|
* Abstract:
|
||
|
* This class is instantiated by the SCF class. For each call that the
|
||
|
* local site or remote site initiates, a SCFCall object is instantiated.
|
||
|
* SCF can can manage 254 different calls simultaneously. For each call
|
||
|
* there is a specific Q.933 based protocol that must occur to make the
|
||
|
* connection valid. This object sends and receives the Q.933 packets.
|
||
|
*
|
||
|
* Private Instance Variables:
|
||
|
* m_pSCF - Address of the owner of this object
|
||
|
* Lower_Layer - Address of the layer below this layer
|
||
|
* m_nMsgBase - The owner of this object gives it a base
|
||
|
* number to use for OwnerCallbacks ()
|
||
|
* Maximum_Packet_Size - Maximum transmittable packet size
|
||
|
* Packet_Pending - Tells which packet is to be transmitted
|
||
|
* next.
|
||
|
* Link_Originator - TRUE is this site initiated the call
|
||
|
*
|
||
|
* Write_Buffer - Address of write buffer
|
||
|
* Send_Priority - TRUE if we are suppose to respond to the
|
||
|
* priority requested by the remote site
|
||
|
*
|
||
|
* Call_Reference - Call reference number of this call.
|
||
|
* DLCI - Holds the suggested and confirmed DLCI for
|
||
|
* this call.
|
||
|
* Priority - Holds the suggested and confirmed priority
|
||
|
* for this call.
|
||
|
*
|
||
|
* State - Holds the current state of the call.
|
||
|
* Release_Cause - Reason the the breakup of the link.
|
||
|
* Default_Priority - Default priority of a non-specified call.
|
||
|
*
|
||
|
* T303_Timeout - T303 timeout value.
|
||
|
* T303_Handle - System timer handle to T303 timer
|
||
|
* T303_Active - TRUE if the timer is currently active
|
||
|
* T303_Count - Number of T303 Timeouts
|
||
|
*
|
||
|
* T313_Timeout - T313 timeout value
|
||
|
* T313_Handle - System timer handle to T313 timer
|
||
|
* T313_Active - TRUE if the timer is currently active.
|
||
|
*
|
||
|
* Caveats:
|
||
|
* None.
|
||
|
*
|
||
|
* Authors:
|
||
|
* James W. Lawwill
|
||
|
*/
|
||
|
#include "scf.h"
|
||
|
#include "scfcall.h"
|
||
|
|
||
|
|
||
|
/*
|
||
|
* SCFCall::SCFCall (
|
||
|
* PTransportResources transport_resources,
|
||
|
* IObject * owner_object
|
||
|
* IProtocolLayer * lower_layer,
|
||
|
* USHORT message_base,
|
||
|
* PDataLinkParameters datalink_struct,
|
||
|
* PMemoryManager data_request_memory_manager,
|
||
|
* BOOL * initialized)
|
||
|
*
|
||
|
* Public
|
||
|
*
|
||
|
* Functional Description:
|
||
|
* This is the SCFCall constructor. This routine initializes all
|
||
|
* variables and allocates write buffer space.
|
||
|
*/
|
||
|
SCFCall::SCFCall (
|
||
|
CLayerSCF *owner_object,
|
||
|
IProtocolLayer * lower_layer,
|
||
|
USHORT message_base,
|
||
|
PDataLinkParameters datalink_struct,
|
||
|
PMemoryManager data_request_memory_manager,
|
||
|
BOOL * initialized)
|
||
|
{
|
||
|
TRACE_OUT(("SCFCall::SCFCall"));
|
||
|
|
||
|
m_pSCF = owner_object;
|
||
|
Lower_Layer = lower_layer;
|
||
|
m_nMsgBase = message_base;
|
||
|
Data_Request_Memory_Manager = data_request_memory_manager;
|
||
|
*initialized = TRUE;
|
||
|
|
||
|
DataLink_Struct.k_factor = datalink_struct->k_factor;
|
||
|
DataLink_Struct.default_k_factor = datalink_struct->default_k_factor;
|
||
|
DataLink_Struct.n201 = datalink_struct->n201;
|
||
|
DataLink_Struct.default_n201 = datalink_struct->default_n201;
|
||
|
|
||
|
/*
|
||
|
** T200 is represented in milliseconds, we need to convert it to
|
||
|
** tenths of seconds.
|
||
|
*/
|
||
|
DataLink_Struct.t200 = datalink_struct->t200 / 100;
|
||
|
DataLink_Struct.default_t200 = datalink_struct->default_t200 / 100;
|
||
|
|
||
|
Lower_Layer -> GetParameters (
|
||
|
&Maximum_Packet_Size,
|
||
|
&Lower_Layer_Prepend,
|
||
|
&Lower_Layer_Append);
|
||
|
|
||
|
Packet_Pending = NO_PACKET;
|
||
|
Link_Originator = FALSE;
|
||
|
State = NOT_CONNECTED;
|
||
|
Received_Priority = FALSE;
|
||
|
Received_K_Factor = FALSE;
|
||
|
Received_N201 = FALSE;
|
||
|
Received_T200 = FALSE;
|
||
|
DLC_Identifier = 0;
|
||
|
|
||
|
T303_Active = FALSE;
|
||
|
T313_Active = FALSE;
|
||
|
|
||
|
/*
|
||
|
** Get configuration data
|
||
|
*/
|
||
|
T303_Timeout = DEFAULT_T303_TIMEOUT;
|
||
|
T313_Timeout = DEFAULT_T313_TIMEOUT;
|
||
|
Default_Priority = DEFAULT_PRIORITY;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* SCFCall::~SCFCall (void)
|
||
|
*
|
||
|
* Public
|
||
|
*
|
||
|
* Functional Description:
|
||
|
* This is the SCFCall destructor. This routine cleans up the mess
|
||
|
*/
|
||
|
SCFCall::~SCFCall (void)
|
||
|
{
|
||
|
if (T303_Active)
|
||
|
{
|
||
|
StopTimerT303 ();
|
||
|
}
|
||
|
|
||
|
if (T313_Active)
|
||
|
{
|
||
|
StopTimerT313 ();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* SCFCall::ConnectRequest (
|
||
|
* CallReference call_reference,
|
||
|
* DLCI dlci,
|
||
|
* USHORT priority)
|
||
|
*
|
||
|
* Public
|
||
|
*
|
||
|
* Functional Description:
|
||
|
* This function is called when SCF wants to initiate a call.
|
||
|
* As a result, we queue a SETUP command to be sent out.
|
||
|
*/
|
||
|
SCFCallError SCFCall::ConnectRequest(
|
||
|
CallReference call_reference,
|
||
|
DLCI dlci,
|
||
|
TransportPriority priority)
|
||
|
{
|
||
|
TRACE_OUT(("SCFCall::ConnectRequest"));
|
||
|
Call_Reference = call_reference;
|
||
|
DLC_Identifier = dlci;
|
||
|
Priority = priority;
|
||
|
Link_Originator = TRUE;
|
||
|
|
||
|
if (State == NOT_CONNECTED)
|
||
|
Packet_Pending = SETUP;
|
||
|
|
||
|
return (SCFCALL_NO_ERROR);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* SCFCallError SCFCall::ConnectResponse (
|
||
|
* BOOL valid_dlci)
|
||
|
*
|
||
|
* Public
|
||
|
*
|
||
|
* Functional Description:
|
||
|
* This function is called in response to a NETWORK_CONNECT_INDICATION
|
||
|
* callback to the owner of this object. Previously, the remote site
|
||
|
* sent us a SETUP packet with a suggested DLCI. This DLCI is sent to
|
||
|
* the owner in the NETWORK_CONNECT_INDICATION call. The owner calls
|
||
|
* this function with a BOOL , telling us if the DLCI was valid.
|
||
|
*/
|
||
|
SCFCallError SCFCall::ConnectResponse (
|
||
|
BOOL valid_dlci)
|
||
|
{
|
||
|
TRACE_OUT(("SCFCall::ConnectResponse"));
|
||
|
if (valid_dlci)
|
||
|
{
|
||
|
/*
|
||
|
** This DLCI can be used in a link. If the remote site did not
|
||
|
** request a priority, we set it to Default_Priority
|
||
|
*/
|
||
|
if (Priority == 0xffff)
|
||
|
Priority = Default_Priority;
|
||
|
|
||
|
Packet_Pending = CONNECT;
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/*
|
||
|
** Queue up a RELEASE COMPLETE packet
|
||
|
*/
|
||
|
Packet_Pending = RELEASE_COMPLETE;
|
||
|
Release_Cause = REQUESTED_CHANNEL_UNAVAILABLE;
|
||
|
}
|
||
|
|
||
|
return (SCFCALL_NO_ERROR);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* SCFCallError SCFCall::DisconnectRequest ()
|
||
|
*
|
||
|
* Public
|
||
|
*
|
||
|
* Functional Description:
|
||
|
* This function is called when the SCF wants to terminate the call
|
||
|
*/
|
||
|
SCFCallError SCFCall::DisconnectRequest ()
|
||
|
{
|
||
|
TRACE_OUT(("SCFCall::DisconnectRequest"));
|
||
|
/*
|
||
|
** Queue up the Release Complete
|
||
|
*/
|
||
|
if (State != NOT_CONNECTED)
|
||
|
{
|
||
|
Packet_Pending = RELEASE_COMPLETE;
|
||
|
Release_Cause = NORMAL_USER_DISCONNECT;
|
||
|
}
|
||
|
|
||
|
return (SCFCALL_NO_ERROR);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* BOOL SCFCall::ProcessSetup (
|
||
|
* CallReference call_reference,
|
||
|
* LPBYTE packet_address,
|
||
|
* USHORT packet_length)
|
||
|
*
|
||
|
* Public
|
||
|
*
|
||
|
* Functional Description:
|
||
|
* This function processes an incoming SETUP packet
|
||
|
*/
|
||
|
BOOL SCFCall::ProcessSetup (
|
||
|
CallReference call_reference,
|
||
|
LPBYTE packet_address,
|
||
|
USHORT packet_length)
|
||
|
{
|
||
|
USHORT length;
|
||
|
BOOL packet_successful;
|
||
|
USHORT remainder_length;
|
||
|
USHORT n201;
|
||
|
USHORT k_factor;
|
||
|
USHORT t200;
|
||
|
NetworkConnectStruct connect_struct;
|
||
|
|
||
|
TRACE_OUT(("SCFCall::ProcessSetup"));
|
||
|
|
||
|
if (State != NOT_CONNECTED)
|
||
|
return (FALSE);
|
||
|
|
||
|
Call_Reference = call_reference;
|
||
|
packet_successful = TRUE;
|
||
|
remainder_length = packet_length;
|
||
|
|
||
|
/*
|
||
|
** Bearer capability element
|
||
|
*/
|
||
|
if (*(packet_address++) != BEARER_CAPABILITY)
|
||
|
return (FALSE);
|
||
|
remainder_length--;
|
||
|
|
||
|
length = *(packet_address++);
|
||
|
remainder_length--;
|
||
|
if (length != 3)
|
||
|
return (FALSE);
|
||
|
|
||
|
/*
|
||
|
** Verify that the Bearer Capability is correct
|
||
|
*/
|
||
|
if (*(packet_address) !=
|
||
|
(EXTENSION | CODING_STANDARD | INFORMATION_TRANSFER_CAPABILITY))
|
||
|
{
|
||
|
return (FALSE);
|
||
|
}
|
||
|
if (*(packet_address + 1) != (EXTENSION | TRANSFER_MODE))
|
||
|
{
|
||
|
return (FALSE);
|
||
|
}
|
||
|
if (*(packet_address + 2) !=
|
||
|
(EXTENSION | LAYER_2_IDENT | USER_INFORMATION_LAYER_2))
|
||
|
{
|
||
|
return (FALSE);
|
||
|
}
|
||
|
packet_address += length;
|
||
|
remainder_length -= length;
|
||
|
|
||
|
/*
|
||
|
** DLCI element
|
||
|
*/
|
||
|
if (*(packet_address++) != DLCI_ELEMENT)
|
||
|
return (FALSE);
|
||
|
remainder_length--;
|
||
|
|
||
|
length = *(packet_address++);
|
||
|
if (length != 2)
|
||
|
return (FALSE);
|
||
|
remainder_length--;
|
||
|
|
||
|
/*
|
||
|
** If the Preferred/Exclusive bit is set, its illegal
|
||
|
*/
|
||
|
if (((*(packet_address) & PREFERRED_EXCLUSIVE) == PREFERRED_EXCLUSIVE) ||
|
||
|
((*(packet_address + 1) & EXTENSION) == 0))
|
||
|
{
|
||
|
return (FALSE);
|
||
|
}
|
||
|
|
||
|
DLC_Identifier = (*(packet_address) & 0x3f) << 4;
|
||
|
DLC_Identifier |= ((*(packet_address + 1) & 0x78) >> 3);
|
||
|
|
||
|
packet_address += length;
|
||
|
remainder_length -= length;
|
||
|
|
||
|
Priority = 0xffff;
|
||
|
|
||
|
/*
|
||
|
** Go thru each of the elements and decode them
|
||
|
*/
|
||
|
while (remainder_length)
|
||
|
{
|
||
|
switch (*(packet_address++))
|
||
|
{
|
||
|
case X213_PRIORITY:
|
||
|
length = *(packet_address++);
|
||
|
remainder_length--;
|
||
|
if (((*(packet_address) & EXTENSION) == 1) ||
|
||
|
((*(packet_address + 1) & EXTENSION) == 0))
|
||
|
{
|
||
|
ERROR_OUT(("SCFCall: ProcessSetup: SETUP packet: Illegal X.213 priority"));
|
||
|
return (FALSE);
|
||
|
}
|
||
|
Priority = (*packet_address & 0x0f);
|
||
|
packet_address += length;
|
||
|
remainder_length -= length;
|
||
|
Received_Priority = TRUE;
|
||
|
break;
|
||
|
|
||
|
case LINK_LAYER_CORE_PARAMETERS:
|
||
|
length = *(packet_address++);
|
||
|
remainder_length -= (length + 1);
|
||
|
while (length)
|
||
|
{
|
||
|
switch (*(packet_address++))
|
||
|
{
|
||
|
case FMIF_SIZE:
|
||
|
/*
|
||
|
** N201 is a Q922 parameter. It is the number of
|
||
|
** maximum information bytes in a packet
|
||
|
*/
|
||
|
n201 =
|
||
|
((*packet_address << 7) |
|
||
|
(*(packet_address + 1) & 0x7f));
|
||
|
if ((*(packet_address+1) & EXTENSION) == EXTENSION)
|
||
|
{
|
||
|
length -= 2;
|
||
|
packet_address += 2;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
packet_address += 4;
|
||
|
length -= 4;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
** If the requested n201 value is less than our
|
||
|
** value, it will be our new N201, otherwise send
|
||
|
** our N201 back as the arbitrated value.
|
||
|
*/
|
||
|
if (n201 < DataLink_Struct.n201)
|
||
|
DataLink_Struct.n201 = n201;
|
||
|
Received_N201 = TRUE;
|
||
|
TRACE_OUT(("SCFCALL: ProcessSetup: n201 = %d", DataLink_Struct.n201));
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
while ((*(packet_address++) & EXTENSION) == 0)
|
||
|
length--;
|
||
|
length--;
|
||
|
break;
|
||
|
}
|
||
|
length--;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case LINK_LAYER_PROTOCOL_PARAMETERS:
|
||
|
length = *(packet_address++);
|
||
|
remainder_length -= (length + 1);
|
||
|
while (length)
|
||
|
{
|
||
|
switch (*(packet_address++))
|
||
|
{
|
||
|
case TRANSMIT_WINDOW_SIZE_IDENTIFIER:
|
||
|
/*
|
||
|
** The Window size is the maximum number of
|
||
|
** outstanding packets at any one time
|
||
|
*/
|
||
|
k_factor = *packet_address & 0x7f;
|
||
|
packet_address++;
|
||
|
length--;
|
||
|
|
||
|
/*
|
||
|
** If the requested k_factor value is less than our
|
||
|
** value, it will be our new k_factor, otherwise
|
||
|
** send our k_factor back as the arbitrated value.
|
||
|
*/
|
||
|
if (k_factor < DataLink_Struct.k_factor)
|
||
|
DataLink_Struct.k_factor = k_factor;
|
||
|
Received_K_Factor = TRUE;
|
||
|
TRACE_OUT(("SCFCALL: ProcessSetup: k_factor = %d", DataLink_Struct.k_factor));
|
||
|
break;
|
||
|
|
||
|
case RETRANSMISSION_TIMER_IDENTIFIER:
|
||
|
/*
|
||
|
** t200 is the timeout value before retransmission
|
||
|
*/
|
||
|
t200 = ((*packet_address << 7) |
|
||
|
(*(packet_address + 1) & 0x7f));
|
||
|
packet_address += 2;
|
||
|
length -= 2;
|
||
|
|
||
|
/*
|
||
|
** If the requested t200 value is too small,
|
||
|
** value, it will be our new T200, otherwise
|
||
|
** send our T200 back as the arbitrated value.
|
||
|
*/
|
||
|
if (t200 > DataLink_Struct.t200)
|
||
|
DataLink_Struct.t200 = t200;
|
||
|
Received_T200 = TRUE;
|
||
|
TRACE_OUT(("SCFCALL: ProcessSetup: t200 = %d", DataLink_Struct.t200));
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
while ((*(packet_address++) & EXTENSION) == 0)
|
||
|
length--;
|
||
|
length--;
|
||
|
break;
|
||
|
}
|
||
|
length--;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case END_TO_END_DELAY:
|
||
|
case CALLING_PARTY_SUBADDRESS:
|
||
|
case CALLED_PARTY_SUBADDRESS:
|
||
|
default:
|
||
|
TRACE_OUT(("SCFCall: ProcessSetup: SETUP packet: Option 0x%x"
|
||
|
"requested, but not supported", *(packet_address-1)));
|
||
|
length = *(packet_address);
|
||
|
|
||
|
packet_address += (length + 1);
|
||
|
remainder_length -= (length + 1);
|
||
|
break;
|
||
|
}
|
||
|
remainder_length--;
|
||
|
}
|
||
|
if (Received_N201 == FALSE)
|
||
|
DataLink_Struct.n201 = DataLink_Struct.default_n201;
|
||
|
if (Received_K_Factor == FALSE)
|
||
|
DataLink_Struct.k_factor = DataLink_Struct.default_k_factor;
|
||
|
if (Received_T200 == FALSE)
|
||
|
DataLink_Struct.t200 = DataLink_Struct.default_t200;
|
||
|
|
||
|
if (packet_successful)
|
||
|
{
|
||
|
/*
|
||
|
** If the packet was successfully decoded, tell the owner the requested
|
||
|
** DLCI and priority.
|
||
|
*/
|
||
|
connect_struct.dlci = DLC_Identifier;
|
||
|
connect_struct.priority = Priority;
|
||
|
connect_struct.datalink_struct = &DataLink_Struct;
|
||
|
|
||
|
/*
|
||
|
** Convert t200 into milliseconds
|
||
|
*/
|
||
|
DataLink_Struct.t200 *= 100;
|
||
|
m_pSCF->OwnerCallback(m_nMsgBase + NETWORK_CONNECT_INDICATION, 0, 0, &connect_struct);
|
||
|
DataLink_Struct.t200 /= 100;
|
||
|
}
|
||
|
|
||
|
return (packet_successful);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* BOOL SCFCall::ProcessConnect (
|
||
|
* LPBYTE packet_address,
|
||
|
* USHORT packet_length)
|
||
|
*
|
||
|
* Public
|
||
|
*
|
||
|
* Functional Description:
|
||
|
* This function processes an incoming CONNECT packet
|
||
|
*/
|
||
|
BOOL SCFCall::ProcessConnect (
|
||
|
LPBYTE packet_address,
|
||
|
USHORT packet_length)
|
||
|
{
|
||
|
TRACE_OUT(("SCFCall::ProcessConnect"));
|
||
|
|
||
|
BOOL packet_successful;
|
||
|
USHORT length;
|
||
|
DLCI exclusive_dlci;
|
||
|
USHORT remainder_length;
|
||
|
USHORT k_factor;
|
||
|
USHORT t200;
|
||
|
|
||
|
if (State != SETUP_SENT)
|
||
|
{
|
||
|
ERROR_OUT(("SCFCall: ProcessConnect: Call in wrong state"));
|
||
|
return (FALSE);
|
||
|
}
|
||
|
|
||
|
remainder_length = packet_length;
|
||
|
packet_successful = TRUE;
|
||
|
|
||
|
/*
|
||
|
** DLCI element
|
||
|
*/
|
||
|
if (*(packet_address++) != DLCI_ELEMENT)
|
||
|
{
|
||
|
ERROR_OUT(("SCFCall: ProcessConnect: DLCI_ELEMENT not in packet"));
|
||
|
return (FALSE);
|
||
|
}
|
||
|
remainder_length--;
|
||
|
|
||
|
length = *(packet_address++);
|
||
|
if (length != 2)
|
||
|
{
|
||
|
ERROR_OUT(("SCFCall: ProcessConnect: DLCI length must be 2"));
|
||
|
return (FALSE);
|
||
|
}
|
||
|
remainder_length--;
|
||
|
|
||
|
/*
|
||
|
** If the Preferred/Exclusive bit is not set, its illegal
|
||
|
*/
|
||
|
if (((*(packet_address) & PREFERRED_EXCLUSIVE) == 0) ||
|
||
|
((*(packet_address + 1) & EXTENSION) == 0))
|
||
|
{
|
||
|
ERROR_OUT(("SCFCall: CONNECT: Illegal DLCI"));
|
||
|
return (FALSE);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
** Get the DLCI
|
||
|
*/
|
||
|
exclusive_dlci = (*(packet_address) & 0x3f) << 4;
|
||
|
exclusive_dlci |= ((*(packet_address + 1) & 0x78) >> 3);
|
||
|
|
||
|
packet_address += length;
|
||
|
remainder_length -= length;
|
||
|
|
||
|
/*
|
||
|
** Go thru each of the elements and decode them
|
||
|
*/
|
||
|
while (remainder_length != 0)
|
||
|
{
|
||
|
switch (*(packet_address++))
|
||
|
{
|
||
|
case X213_PRIORITY:
|
||
|
length = *(packet_address++);
|
||
|
remainder_length--;
|
||
|
if ((*(packet_address) & EXTENSION) == 0)
|
||
|
{
|
||
|
ERROR_OUT(("SCFCall: DataIndication: CONNECT packet: Illegal X.213 priority"));
|
||
|
return (FALSE);
|
||
|
}
|
||
|
Priority = (*packet_address & 0x0f);
|
||
|
packet_address += length;
|
||
|
remainder_length -= length;
|
||
|
break;
|
||
|
|
||
|
case LINK_LAYER_CORE_PARAMETERS:
|
||
|
length = *(packet_address++);
|
||
|
remainder_length -= (length + 1);
|
||
|
while (length)
|
||
|
{
|
||
|
switch (*(packet_address++))
|
||
|
{
|
||
|
case FMIF_SIZE:
|
||
|
/*
|
||
|
** FMIF_Size is the max. number of bytes allowed in
|
||
|
** a information packet
|
||
|
*/
|
||
|
DataLink_Struct.n201 =
|
||
|
((*packet_address << 7) |
|
||
|
(*(packet_address + 1) & 0x7f));
|
||
|
if ((*(packet_address+1) & EXTENSION) == EXTENSION)
|
||
|
{
|
||
|
length -= 2;
|
||
|
packet_address += 2;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
packet_address += 4;
|
||
|
length -= 4;
|
||
|
}
|
||
|
|
||
|
Received_N201 = TRUE;
|
||
|
TRACE_OUT(("SCFCALL: ProcessConnect: n201 = %d", DataLink_Struct.n201));
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
while ((*(packet_address++) & EXTENSION) == 0)
|
||
|
length--;
|
||
|
length--;
|
||
|
break;
|
||
|
}
|
||
|
length--;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case LINK_LAYER_PROTOCOL_PARAMETERS:
|
||
|
length = *(packet_address++);
|
||
|
remainder_length -= (length + 1);
|
||
|
while (length)
|
||
|
{
|
||
|
switch (*(packet_address++))
|
||
|
{
|
||
|
case TRANSMIT_WINDOW_SIZE_IDENTIFIER:
|
||
|
/*
|
||
|
** The Window size is the maximum number of
|
||
|
** outstanding packets at any one time
|
||
|
*/
|
||
|
k_factor = *packet_address & 0x7f;
|
||
|
packet_address++;
|
||
|
length--;
|
||
|
|
||
|
DataLink_Struct.k_factor = k_factor;
|
||
|
Received_K_Factor = TRUE;
|
||
|
TRACE_OUT(("SCFCALL: ProcessConnect: k_factor = %d", DataLink_Struct.k_factor));
|
||
|
break;
|
||
|
|
||
|
case RETRANSMISSION_TIMER_IDENTIFIER:
|
||
|
/*
|
||
|
** t200 is the timeout value before retransmission
|
||
|
*/
|
||
|
t200 = ((*packet_address << 7) |
|
||
|
(*(packet_address + 1) & 0x7f));
|
||
|
packet_address += 2;
|
||
|
length -= 2;
|
||
|
|
||
|
DataLink_Struct.t200 = t200;
|
||
|
Received_T200 = TRUE;
|
||
|
TRACE_OUT(("SCFCALL: ProcessConnect: t200 = %d", DataLink_Struct.t200));
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
while ((*(packet_address++) & EXTENSION) == 0)
|
||
|
length--;
|
||
|
length--;
|
||
|
break;
|
||
|
}
|
||
|
length--;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case END_TO_END_DELAY:
|
||
|
case CALLING_PARTY_SUBADDRESS:
|
||
|
case CALLED_PARTY_SUBADDRESS:
|
||
|
default:
|
||
|
TRACE_OUT(("SCFCall: DataIndication: CONNECT packet: Option "
|
||
|
"requested, but not supported", *(packet_address-1)));
|
||
|
length = *(packet_address++);
|
||
|
remainder_length--;
|
||
|
|
||
|
packet_address += length;
|
||
|
remainder_length -= length;
|
||
|
break;
|
||
|
}
|
||
|
remainder_length--;
|
||
|
}
|
||
|
|
||
|
if (Received_N201 == FALSE)
|
||
|
DataLink_Struct.n201 = DataLink_Struct.default_n201;
|
||
|
if (Received_K_Factor == FALSE)
|
||
|
DataLink_Struct.k_factor = DataLink_Struct.default_k_factor;
|
||
|
if (Received_T200 == FALSE)
|
||
|
DataLink_Struct.t200 = DataLink_Struct.default_t200;
|
||
|
|
||
|
/*
|
||
|
** If the packet was successfully decoded, queue up the CONNECT ACK
|
||
|
*/
|
||
|
if (packet_successful)
|
||
|
{
|
||
|
Packet_Pending = CONNECT_ACKNOWLEDGE;
|
||
|
StopTimerT303 ();
|
||
|
}
|
||
|
|
||
|
return (packet_successful);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* BOOL SCFCall::ProcessConnectAcknowledge (
|
||
|
* LPBYTE,
|
||
|
* USHORT)
|
||
|
*
|
||
|
* Public
|
||
|
*
|
||
|
* Functional Description:
|
||
|
* This function processes an incoming CONNECT ACK packet
|
||
|
*
|
||
|
*/
|
||
|
BOOL SCFCall::ProcessConnectAcknowledge (
|
||
|
LPBYTE,
|
||
|
USHORT)
|
||
|
{
|
||
|
TRACE_OUT(("SCFCall::ProcessConnectAcknowledge"));
|
||
|
|
||
|
if (State != CONNECT_SENT)
|
||
|
return (FALSE);
|
||
|
|
||
|
StopTimerT313 ();
|
||
|
|
||
|
return (TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* BOOL SCFCall::ProcessReleaseComplete (
|
||
|
* LPBYTE packet_address,
|
||
|
* USHORT)
|
||
|
*
|
||
|
* Public
|
||
|
*
|
||
|
* Functional Description:
|
||
|
* This function processes an incoming RELEASE COMPLETE
|
||
|
*/
|
||
|
BOOL SCFCall::ProcessReleaseComplete (
|
||
|
LPBYTE packet_address,
|
||
|
USHORT)
|
||
|
{
|
||
|
TRACE_OUT(("SCFCall::ProcessReleaseComplete"));
|
||
|
|
||
|
USHORT cause;
|
||
|
|
||
|
if (State == NOT_CONNECTED)
|
||
|
return (FALSE);
|
||
|
|
||
|
if (*(packet_address++) == CAUSE)
|
||
|
{
|
||
|
packet_address++;
|
||
|
if ((*(packet_address++) & EXTENSION) == 0)
|
||
|
packet_address++;
|
||
|
|
||
|
cause = *(packet_address++) & (~EXTENSION);
|
||
|
TRACE_OUT(("SCFCall: Disconnect: cause = %d", cause));
|
||
|
}
|
||
|
|
||
|
State = NOT_CONNECTED;
|
||
|
|
||
|
/*
|
||
|
** Tell the owner about the Disconnection
|
||
|
*/
|
||
|
m_pSCF->OwnerCallback(m_nMsgBase + NETWORK_DISCONNECT_INDICATION,
|
||
|
(void *) DLC_Identifier,
|
||
|
(void *) (ULONG_PTR)(((Link_Originator << 16) | cause)));
|
||
|
return (TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* void SCFCall::PollTransmitter (
|
||
|
* USHORT data_to_transmit,
|
||
|
* USHORT * pending_data);
|
||
|
*
|
||
|
* Public
|
||
|
*
|
||
|
* Functional Description:
|
||
|
* This function is called to transmit any queued up packets
|
||
|
*/
|
||
|
void SCFCall::PollTransmitter (
|
||
|
USHORT data_to_transmit,
|
||
|
USHORT * pending_data)
|
||
|
{
|
||
|
// TRACE_OUT(("SCFCall::PollTransmitter"));
|
||
|
|
||
|
NetworkConnectStruct connect_struct;
|
||
|
|
||
|
if (data_to_transmit & PROTOCOL_CONTROL_DATA)
|
||
|
{
|
||
|
switch (Packet_Pending)
|
||
|
{
|
||
|
case SETUP:
|
||
|
SendSetup ();
|
||
|
break;
|
||
|
|
||
|
case CONNECT:
|
||
|
SendConnect ();
|
||
|
break;
|
||
|
|
||
|
case CONNECT_ACKNOWLEDGE:
|
||
|
SendConnectAcknowledge ();
|
||
|
if (Packet_Pending != CONNECT_ACKNOWLEDGE)
|
||
|
{
|
||
|
/*
|
||
|
** If the CONNECT ACK packet was sent, notify the owner
|
||
|
*/
|
||
|
connect_struct.dlci = DLC_Identifier;
|
||
|
connect_struct.priority = Priority;
|
||
|
connect_struct.datalink_struct = &DataLink_Struct;
|
||
|
|
||
|
/*
|
||
|
** Convert t200 to milliseconds
|
||
|
*/
|
||
|
DataLink_Struct.t200 *= 100;
|
||
|
m_pSCF->OwnerCallback(m_nMsgBase + NETWORK_CONNECT_CONFIRM, 0, 0, &connect_struct);
|
||
|
DataLink_Struct.t200 /= 100;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case RELEASE_COMPLETE:
|
||
|
SendReleaseComplete ();
|
||
|
if (Packet_Pending != RELEASE_COMPLETE)
|
||
|
{
|
||
|
/*
|
||
|
** If the RELEASE COMPLETE packet was sent, notify
|
||
|
** the owner
|
||
|
*/
|
||
|
m_pSCF->OwnerCallback(m_nMsgBase + NETWORK_DISCONNECT_INDICATION,
|
||
|
(void *) DLC_Identifier,
|
||
|
(void *) ((((ULONG_PTR) Link_Originator) << 16) | Release_Cause));
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (Packet_Pending != NO_PACKET)
|
||
|
*pending_data = PROTOCOL_CONTROL_DATA;
|
||
|
else
|
||
|
*pending_data = 0;
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* void SCFCall::SendSetup (void);
|
||
|
*
|
||
|
* Functional Description
|
||
|
* This function attempts to send out a SETUP packet. The T303 timer
|
||
|
* is started. If a CONNECT is not received before the timer expires,
|
||
|
* we terminate the link.
|
||
|
*
|
||
|
* Formal Parameters
|
||
|
* None
|
||
|
*
|
||
|
* Return Value
|
||
|
* None
|
||
|
*
|
||
|
* Side Effects
|
||
|
* If this function is able to send a SETUP packet to the lower layer,
|
||
|
* it sets the Packet_Pending variable to NO_PACKET
|
||
|
*
|
||
|
* Caveats
|
||
|
* None
|
||
|
*/
|
||
|
void SCFCall::SendSetup (void)
|
||
|
{
|
||
|
TRACE_OUT(("SCFCall::SendSetup"));
|
||
|
|
||
|
LPBYTE packet_address;
|
||
|
ULONG bytes_accepted;
|
||
|
USHORT total_length;
|
||
|
PMemory memory;
|
||
|
|
||
|
total_length = SETUP_PACKET_SIZE + Lower_Layer_Prepend +
|
||
|
Lower_Layer_Append;
|
||
|
|
||
|
memory = Data_Request_Memory_Manager -> AllocateMemory (
|
||
|
NULL,
|
||
|
total_length);
|
||
|
if (memory == NULL)
|
||
|
return;
|
||
|
|
||
|
packet_address = memory -> GetPointer ();
|
||
|
packet_address += Lower_Layer_Prepend;
|
||
|
|
||
|
*(packet_address++) = Q931_PROTOCOL_DISCRIMINATOR;
|
||
|
*(packet_address++) = 1;
|
||
|
*(packet_address++) = (UChar) Call_Reference;
|
||
|
*(packet_address++) = SETUP;
|
||
|
|
||
|
/*
|
||
|
** Bearer Capability
|
||
|
*/
|
||
|
*(packet_address++) = BEARER_CAPABILITY;
|
||
|
*(packet_address++) = 3;
|
||
|
*(packet_address++) =
|
||
|
EXTENSION | CODING_STANDARD | INFORMATION_TRANSFER_CAPABILITY;
|
||
|
*(packet_address++) = EXTENSION | TRANSFER_MODE;
|
||
|
*(packet_address++) = EXTENSION | LAYER_2_IDENT | USER_INFORMATION_LAYER_2;
|
||
|
|
||
|
/*
|
||
|
** DLCI
|
||
|
*/
|
||
|
*(packet_address++) = DLCI_ELEMENT;
|
||
|
*(packet_address++) = 2;
|
||
|
*(packet_address++) = (DLC_Identifier >> 4);
|
||
|
*(packet_address++) = EXTENSION | ((DLC_Identifier & 0x0f) << 3);
|
||
|
|
||
|
/*
|
||
|
** Link Layer Core Parameters
|
||
|
*/
|
||
|
*(packet_address++) = LINK_LAYER_CORE_PARAMETERS;
|
||
|
*(packet_address++) = 3;
|
||
|
*(packet_address++) = FMIF_SIZE;
|
||
|
*(packet_address++) = (DataLink_Struct.n201 >> 7);
|
||
|
*(packet_address++) = EXTENSION | (DataLink_Struct.n201 & 0x7f);
|
||
|
|
||
|
/*
|
||
|
** Link Layer Protocol Parameters
|
||
|
*/
|
||
|
*(packet_address++) = LINK_LAYER_PROTOCOL_PARAMETERS;
|
||
|
*(packet_address++) = 5;
|
||
|
*(packet_address++) = TRANSMIT_WINDOW_SIZE_IDENTIFIER;
|
||
|
*(packet_address++) = EXTENSION | DataLink_Struct.k_factor;
|
||
|
*(packet_address++) = RETRANSMISSION_TIMER_IDENTIFIER;
|
||
|
*(packet_address++) = (DataLink_Struct.t200 >> 7) & 0x7f;
|
||
|
*(packet_address++) = EXTENSION | (DataLink_Struct.t200 & 0x7f);
|
||
|
|
||
|
/*
|
||
|
** X.213 Priority
|
||
|
*/
|
||
|
*(packet_address++) = X213_PRIORITY;
|
||
|
*(packet_address++) = 2;
|
||
|
*(packet_address++) = (UChar) Priority;
|
||
|
|
||
|
/*
|
||
|
** The next byte contains the lowest priority acceptable, 0
|
||
|
*/
|
||
|
*(packet_address++) = EXTENSION | 0;
|
||
|
|
||
|
/*
|
||
|
** Attempt to send the packet down
|
||
|
*/
|
||
|
Lower_Layer -> DataRequest (
|
||
|
0,
|
||
|
memory,
|
||
|
&bytes_accepted);
|
||
|
if (bytes_accepted == total_length)
|
||
|
{
|
||
|
T303_Count = 0;
|
||
|
Packet_Pending = NO_PACKET;
|
||
|
State = SETUP_SENT;
|
||
|
StartTimerT303 ();
|
||
|
}
|
||
|
Data_Request_Memory_Manager -> FreeMemory (memory);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* void SCFCall::SendConnect (void);
|
||
|
*
|
||
|
* Functional Description
|
||
|
* This function attempts to send out a CONNECT packet. The T313 timer
|
||
|
* is started. If a CONNECT ACK is not received before the timer expires,
|
||
|
* we terminate the link.
|
||
|
*
|
||
|
* Formal Parameters
|
||
|
* None
|
||
|
*
|
||
|
* Return Value
|
||
|
* None
|
||
|
*
|
||
|
* Side Effects
|
||
|
* If this function is able to send a CONNECT packet to the lower layer,
|
||
|
* it sets the Packet_Pending variable to NO_PACKET
|
||
|
*
|
||
|
* Caveats
|
||
|
* None
|
||
|
*
|
||
|
*/
|
||
|
void SCFCall::SendConnect (void)
|
||
|
{
|
||
|
TRACE_OUT(("SCFCall::SendConnect"));
|
||
|
|
||
|
LPBYTE packet_address;
|
||
|
LPBYTE length_address;
|
||
|
ULONG bytes_accepted;
|
||
|
USHORT total_length;
|
||
|
PMemory memory;
|
||
|
|
||
|
total_length = CONNECT_PACKET_BASE_SIZE + Lower_Layer_Prepend +
|
||
|
Lower_Layer_Append;
|
||
|
|
||
|
if (Received_N201)
|
||
|
total_length += 5;
|
||
|
|
||
|
if (Received_K_Factor || Received_T200)
|
||
|
{
|
||
|
total_length += 2;
|
||
|
|
||
|
if (Received_K_Factor)
|
||
|
total_length += 2;
|
||
|
if (Received_T200)
|
||
|
total_length += 3;
|
||
|
}
|
||
|
if (Received_Priority)
|
||
|
total_length += 3;
|
||
|
|
||
|
/*
|
||
|
** Prepare the CONNECT command and send it to the lower layer
|
||
|
*/
|
||
|
memory = Data_Request_Memory_Manager -> AllocateMemory (
|
||
|
NULL,
|
||
|
total_length);
|
||
|
if (memory == NULL)
|
||
|
return;
|
||
|
|
||
|
packet_address = memory -> GetPointer ();
|
||
|
packet_address += Lower_Layer_Prepend;
|
||
|
|
||
|
*(packet_address++) = Q931_PROTOCOL_DISCRIMINATOR;
|
||
|
*(packet_address++) = 1;
|
||
|
*(packet_address++) = REMOTE_CALL_REFERENCE | Call_Reference;
|
||
|
*(packet_address++) = CONNECT;
|
||
|
|
||
|
/*
|
||
|
** DLCI
|
||
|
*/
|
||
|
*(packet_address++) = DLCI_ELEMENT;
|
||
|
*(packet_address++) = 2;
|
||
|
*(packet_address++) = PREFERRED_EXCLUSIVE | (DLC_Identifier >> 4);
|
||
|
*(packet_address++) = EXTENSION | ((DLC_Identifier & 0x0f) << 3);
|
||
|
|
||
|
if (Received_N201)
|
||
|
{
|
||
|
/*
|
||
|
** Link Layer Core Parameters
|
||
|
*/
|
||
|
*(packet_address++) = LINK_LAYER_CORE_PARAMETERS;
|
||
|
*(packet_address++) = 3;
|
||
|
*(packet_address++) = FMIF_SIZE;
|
||
|
*(packet_address++) = (DataLink_Struct.n201 >> 7);
|
||
|
*(packet_address++) = EXTENSION | (DataLink_Struct.n201 & 0x7f);
|
||
|
}
|
||
|
else
|
||
|
DataLink_Struct.n201 = DataLink_Struct.default_n201;
|
||
|
|
||
|
|
||
|
if (Received_K_Factor || Received_T200)
|
||
|
{
|
||
|
/*
|
||
|
** Link Layer Protocol Parameters
|
||
|
*/
|
||
|
*(packet_address++) = LINK_LAYER_PROTOCOL_PARAMETERS;
|
||
|
length_address = packet_address;
|
||
|
*(packet_address++) = 0;
|
||
|
if (Received_K_Factor)
|
||
|
{
|
||
|
*length_address += 2;
|
||
|
*(packet_address++) = TRANSMIT_WINDOW_SIZE_IDENTIFIER;
|
||
|
*(packet_address++) = EXTENSION | DataLink_Struct.k_factor;
|
||
|
}
|
||
|
if (Received_T200)
|
||
|
{
|
||
|
*length_address += 3;
|
||
|
*(packet_address++) = RETRANSMISSION_TIMER_IDENTIFIER;
|
||
|
*(packet_address++) = (DataLink_Struct.t200 >> 7) & 0x7f;
|
||
|
*(packet_address++) = EXTENSION | (DataLink_Struct.t200 & 0x7f);
|
||
|
}
|
||
|
}
|
||
|
if (Received_K_Factor == FALSE)
|
||
|
DataLink_Struct.k_factor = DataLink_Struct.default_k_factor;
|
||
|
if (Received_T200 == FALSE)
|
||
|
DataLink_Struct.t200 = DataLink_Struct.default_t200;
|
||
|
|
||
|
if (Received_Priority)
|
||
|
{
|
||
|
/*
|
||
|
** X.213 Priority
|
||
|
*/
|
||
|
*(packet_address++) = X213_PRIORITY;
|
||
|
*(packet_address++) = 1;
|
||
|
*(packet_address++) = (BYTE) (EXTENSION | Priority);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
** Attempt to send the packet to the lower layer
|
||
|
*/
|
||
|
Lower_Layer -> DataRequest (
|
||
|
0,
|
||
|
memory,
|
||
|
&bytes_accepted);
|
||
|
if (bytes_accepted == total_length)
|
||
|
{
|
||
|
StartTimerT313 ();
|
||
|
Packet_Pending = NO_PACKET;
|
||
|
State = CONNECT_SENT;
|
||
|
}
|
||
|
Data_Request_Memory_Manager -> FreeMemory (memory);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* void SCFCall::SendConnectAcknowledge (void);
|
||
|
*
|
||
|
* Functional Description
|
||
|
* This function attempts to send out a CONNECT ACKNOWLEDGE packet
|
||
|
*
|
||
|
* Formal Parameters
|
||
|
* None
|
||
|
*
|
||
|
* Return Value
|
||
|
* None
|
||
|
*
|
||
|
* Side Effects
|
||
|
* If this function is able to send the packet to the lower layer,
|
||
|
* it sets the Packet_Pending variable to NO_PACKET
|
||
|
*
|
||
|
* Caveats
|
||
|
* None
|
||
|
*
|
||
|
*/
|
||
|
void SCFCall::SendConnectAcknowledge (void)
|
||
|
{
|
||
|
TRACE_OUT(("SCFCall::SendConnectAcknowledge"));
|
||
|
|
||
|
LPBYTE packet_address;
|
||
|
USHORT total_length;
|
||
|
PMemory memory;
|
||
|
ULONG bytes_accepted;
|
||
|
|
||
|
total_length = CONNECT_ACK_PACKET_SIZE + Lower_Layer_Prepend +
|
||
|
Lower_Layer_Append;
|
||
|
/*
|
||
|
** Prepare the command and send it to the lower layer
|
||
|
*/
|
||
|
memory = Data_Request_Memory_Manager -> AllocateMemory (
|
||
|
NULL,
|
||
|
total_length);
|
||
|
if (memory == NULL)
|
||
|
return;
|
||
|
|
||
|
packet_address = memory -> GetPointer ();
|
||
|
packet_address += Lower_Layer_Prepend;
|
||
|
|
||
|
*(packet_address++) = Q931_PROTOCOL_DISCRIMINATOR;
|
||
|
*(packet_address++) = 1;
|
||
|
*(packet_address++) = (UChar) Call_Reference;
|
||
|
*(packet_address++) = CONNECT_ACKNOWLEDGE;
|
||
|
|
||
|
Lower_Layer -> DataRequest (
|
||
|
0,
|
||
|
memory,
|
||
|
&bytes_accepted);
|
||
|
if (bytes_accepted == total_length)
|
||
|
{
|
||
|
State = CALL_ESTABLISHED;
|
||
|
Packet_Pending = NO_PACKET;
|
||
|
}
|
||
|
Data_Request_Memory_Manager -> FreeMemory (memory);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* void SCFCall::SendReleaseComplete (void);
|
||
|
*
|
||
|
* Functional Description
|
||
|
* This function attempts to send out a RELEASE COMPLETE packet
|
||
|
*
|
||
|
* Formal Parameters
|
||
|
* None
|
||
|
*
|
||
|
* Return Value
|
||
|
* None
|
||
|
*
|
||
|
* Side Effects
|
||
|
* If this function is able to send a RELEASE COMPLETE packet to the lower
|
||
|
* layer, it sets the Packet_Pending variable to NO_PACKET
|
||
|
*
|
||
|
* Caveats
|
||
|
* None
|
||
|
*
|
||
|
*/
|
||
|
void SCFCall::SendReleaseComplete (void)
|
||
|
{
|
||
|
TRACE_OUT(("SCFCall::SendReleaseComplete"));
|
||
|
|
||
|
LPBYTE packet_address;
|
||
|
ULONG bytes_accepted;
|
||
|
USHORT total_length;
|
||
|
PMemory memory;
|
||
|
|
||
|
total_length = RELEASE_COMPLETE_PACKET_SIZE + Lower_Layer_Prepend +
|
||
|
Lower_Layer_Append;
|
||
|
/*
|
||
|
** Prepare the command and send it to the lower layer
|
||
|
*/
|
||
|
memory = Data_Request_Memory_Manager -> AllocateMemory (
|
||
|
NULL,
|
||
|
total_length);
|
||
|
if (memory == NULL)
|
||
|
return;
|
||
|
|
||
|
packet_address = memory -> GetPointer ();
|
||
|
packet_address += Lower_Layer_Prepend;
|
||
|
|
||
|
*(packet_address++) = Q931_PROTOCOL_DISCRIMINATOR;
|
||
|
*(packet_address++) = 1;
|
||
|
if (Link_Originator)
|
||
|
*(packet_address++) = (UChar) Call_Reference;
|
||
|
else
|
||
|
*(packet_address++) = 0x80 | Call_Reference;
|
||
|
*(packet_address++) = RELEASE_COMPLETE;
|
||
|
|
||
|
|
||
|
/*
|
||
|
** Append the CAUSE for the link breakup
|
||
|
*/
|
||
|
*(packet_address++) = CAUSE;
|
||
|
*(packet_address++) = 2;
|
||
|
*(packet_address++) = EXTENSION;
|
||
|
*(packet_address++) = EXTENSION | Release_Cause;
|
||
|
|
||
|
Lower_Layer -> DataRequest (
|
||
|
0,
|
||
|
memory,
|
||
|
&bytes_accepted);
|
||
|
if (bytes_accepted == total_length)
|
||
|
{
|
||
|
State = NOT_CONNECTED;
|
||
|
Packet_Pending = NO_PACKET;
|
||
|
}
|
||
|
Data_Request_Memory_Manager -> FreeMemory (memory);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* void SCFCall::StartTimerT303 (void);
|
||
|
*
|
||
|
* Functional Description
|
||
|
* This function Starts the T303 Timer. This is started when we send
|
||
|
* out the SETUP packet. It is stopped when we receive a CONNECT
|
||
|
* packet. If it expires we terminate the link.
|
||
|
*
|
||
|
* Formal Parameters
|
||
|
* None
|
||
|
*
|
||
|
* Return Value
|
||
|
* None
|
||
|
*
|
||
|
* Side Effects
|
||
|
* None
|
||
|
*
|
||
|
* Caveats
|
||
|
* None
|
||
|
*
|
||
|
*/
|
||
|
void SCFCall::StartTimerT303 (void)
|
||
|
{
|
||
|
TRACE_OUT(("SCFCall::StartTimerT303"));
|
||
|
|
||
|
if (T303_Active)
|
||
|
StopTimerT303 ();
|
||
|
|
||
|
T303_Handle = g_pSystemTimer->CreateTimerEvent(
|
||
|
T303_Timeout,
|
||
|
TIMER_EVENT_ONE_SHOT,
|
||
|
this,
|
||
|
(PTimerFunction) &SCFCall::T303Timeout);
|
||
|
|
||
|
T303_Active = TRUE;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* void SCFCall::StopTimerT303 (void);
|
||
|
*
|
||
|
* Functional Description
|
||
|
* This function stops the T303 Timer. This is called when we receive
|
||
|
* the CONNECT packet. As a result, we stop the timer.
|
||
|
*
|
||
|
* Formal Parameters
|
||
|
* None
|
||
|
*
|
||
|
* Return Value
|
||
|
* None
|
||
|
*
|
||
|
* Side Effects
|
||
|
* None
|
||
|
*
|
||
|
* Caveats
|
||
|
* None
|
||
|
*
|
||
|
*/
|
||
|
void SCFCall::StopTimerT303 (void)
|
||
|
{
|
||
|
TRACE_OUT(("SCFCall::StopTimerT303"));
|
||
|
|
||
|
if (T303_Active)
|
||
|
{
|
||
|
g_pSystemTimer->DeleteTimerEvent(T303_Handle);
|
||
|
T303_Active = FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* void SCFCall::T303Timeout (
|
||
|
* TimerEventHandle);
|
||
|
*
|
||
|
* Functional Description
|
||
|
* This function is called by the System timer when the T303 timeout
|
||
|
* expires. As a result, we terminate the link.
|
||
|
*
|
||
|
* Formal Parameters
|
||
|
* None used
|
||
|
*
|
||
|
* Return Value
|
||
|
* None
|
||
|
*
|
||
|
* Side Effects
|
||
|
* None
|
||
|
*
|
||
|
* Caveats
|
||
|
* None
|
||
|
*
|
||
|
*/
|
||
|
void SCFCall::T303Timeout (
|
||
|
TimerEventHandle)
|
||
|
{
|
||
|
TRACE_OUT(("SCFCall: T303Timeout"));
|
||
|
|
||
|
if (T303_Count >= 1)
|
||
|
State = NOT_CONNECTED;
|
||
|
|
||
|
T303_Count++;
|
||
|
|
||
|
Packet_Pending = RELEASE_COMPLETE;
|
||
|
Release_Cause = NORMAL_USER_DISCONNECT;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* void SCFCall::StartTimerT313 (void);
|
||
|
*
|
||
|
* Functional Description
|
||
|
* This function Starts the T313 Timer. This is started when we send
|
||
|
* out the CONNECT packet. It is stopped when we receive a CONNECT ACK
|
||
|
* packet. If it expires we terminate the link.
|
||
|
*
|
||
|
* Formal Parameters
|
||
|
* None
|
||
|
*
|
||
|
* Return Value
|
||
|
* None
|
||
|
*
|
||
|
* Side Effects
|
||
|
* None
|
||
|
*
|
||
|
* Caveats
|
||
|
* None
|
||
|
*
|
||
|
*/
|
||
|
void SCFCall::StartTimerT313 (void)
|
||
|
{
|
||
|
TRACE_OUT(("SCFCall: StartTimerT313"));
|
||
|
|
||
|
if (T313_Active)
|
||
|
StopTimerT313 ();
|
||
|
|
||
|
T313_Handle = g_pSystemTimer->CreateTimerEvent(
|
||
|
T313_Timeout,
|
||
|
TIMER_EVENT_ONE_SHOT,
|
||
|
this,
|
||
|
(PTimerFunction) &SCFCall::T313Timeout);
|
||
|
|
||
|
T313_Active = TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* void SCFCall::StopTimerT313 (void);
|
||
|
*
|
||
|
* Functional Description
|
||
|
* This function stops the T313 Timer. This is called when we receive
|
||
|
* the CONNECT ACK packet. As a result, we stop the timer.
|
||
|
*
|
||
|
* Formal Parameters
|
||
|
* None
|
||
|
*
|
||
|
* Return Value
|
||
|
* None
|
||
|
*
|
||
|
* Side Effects
|
||
|
* None
|
||
|
*
|
||
|
* Caveats
|
||
|
* None
|
||
|
*
|
||
|
*/
|
||
|
void SCFCall::StopTimerT313 (void)
|
||
|
{
|
||
|
TRACE_OUT(("SCFCall: StopTimerT313"));
|
||
|
|
||
|
if (T313_Active)
|
||
|
{
|
||
|
g_pSystemTimer->DeleteTimerEvent(T313_Handle);
|
||
|
T313_Active = FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* void SCFCall::T313Timeout (
|
||
|
* TimerEventHandle);
|
||
|
*
|
||
|
* Functional Description
|
||
|
* This function is called by the System timer when the T313 timeout
|
||
|
* expires. As a result, we terminate the link.
|
||
|
*
|
||
|
* Formal Parameters
|
||
|
* None used
|
||
|
*
|
||
|
* Return Value
|
||
|
* None
|
||
|
*
|
||
|
* Side Effects
|
||
|
* None
|
||
|
*
|
||
|
* Caveats
|
||
|
* None
|
||
|
*
|
||
|
*/
|
||
|
void SCFCall::T313Timeout (
|
||
|
TimerEventHandle)
|
||
|
{
|
||
|
TRACE_OUT(("SCFCall: T313Timeout"));
|
||
|
|
||
|
State = NOT_CONNECTED;
|
||
|
Packet_Pending = RELEASE_COMPLETE;
|
||
|
Release_Cause = NORMAL_USER_DISCONNECT;
|
||
|
}
|