|
|
/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
q931pdu.cpp
Abstract:
Encode/decode/transport routines for Q931/H450 messages.
Author: Nikhil Bobde (NikhilB)
Revision History:
--*/
#include "globals.h"
#include "q931obj.h"
#include "line.h"
#include "q931pdu.h"
#include "ras.h"
//PARSE ROUTINES
//------------------------------------------------------------------------------
// Parse and return a single octet encoded value, See Q931 section 4.5.1.
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// bIdent Pointer to space for field identifier
// Value Pointer to space for field value
//------------------------------------------------------------------------------
HRESULT ParseSingleOctetType1( PBUFFERDESCR pBuf, BYTE * bIdent, BYTE * Value ) { // There has to be at least 1 byte in the stream to be
// able to parse the single octet value
if (((LONG)(pBuf->dwLength)) < 1) { return E_INVALIDARG; }
// low bits (0, 1, 2, 3) of the byte are the value
*Value = (BYTE)(*pBuf->pbBuffer & TYPE1VALUEMASK);
// higher bits (4, 5, 6) are the identifier. bit 7 is always 1,
// and is not returned as part of the id.
*bIdent = (BYTE)((*pBuf->pbBuffer & 0x70) >> 4);
pBuf->pbBuffer++; pBuf->dwLength--;
return S_OK; }
//------------------------------------------------------------------------------
// Parse and return a single octet encoded value, See Q931 section 4.5.1.
// This octet has no value, only an identifier.
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer containing the
// length and a pointer to the raw bytes of the input stream.
// bIdent Pointer to space for field identifier
//------------------------------------------------------------------------------
HRESULT ParseSingleOctetType2( PBUFFERDESCR pBuf, BYTE * bIdent ) { // There has to be at least 1 byte in the stream to be
// able to parse the single octet value
if (((LONG)(pBuf->dwLength)) < 1) { return E_INVALIDARG; }
// low 7 bits of the byte are the identifier
*bIdent = (BYTE)(*pBuf->pbBuffer & 0x7f);
pBuf->pbBuffer++; pBuf->dwLength--;
return S_OK; }
//------------------------------------------------------------------------------
// Parse and return a variable length Q931 field see Q931 section 4.5.1.
//
// Parameters :
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// bIdent Pointer to space for field identifier
// dwLength Pointer to space for the length
// pbContents Pointer to space for the bytes of the field
//------------------------------------------------------------------------------
HRESULT ParseVariableOctet( PBUFFERDESCR pBuf, BYTE * dwLength, BYTE * pbContents ) { // There has to be at least 2 bytes in order just to get
// the length and the identifier
// able to parse the single octet value
if (((LONG)(pBuf->dwLength)) < 2) { return E_INVALIDARG; }
//Increment the ident byte
pBuf->pbBuffer++; pBuf->dwLength--;
// The next byte is the length
*dwLength = *pBuf->pbBuffer; pBuf->pbBuffer++; pBuf->dwLength--;
if (((LONG)(pBuf->dwLength)) < *dwLength) { return E_INVALIDARG; }
if (*dwLength >= MAXVARFIELDLEN) { return E_INVALIDARG; }
CopyMemory( pbContents, pBuf->pbBuffer, *dwLength ); pBuf->pbBuffer += *dwLength; pBuf->dwLength -= *dwLength;
return S_OK; }
//------------------------------------------------------------------------------
// Parse and return a variable length Q931 field see Q931 section 4.5.1.
//------------------------------------------------------------------------------
HRESULT ParseVariableASN( PBUFFERDESCR pBuf, BYTE *bIdent, BYTE *ProtocolDiscriminator, PUSERUSERIE pUserUserIE ) { pUserUserIE -> wUserInfoLen = 0;
// There has to be at least 4 bytes for the IE identifier,
// the contents length, and the protocol discriminator (1 + 2 + 1).
if (((LONG)(pBuf->dwLength)) < 4) { return E_INVALIDARG; }
// low 7 bits of the first byte are the identifier
*bIdent= (BYTE)(*pBuf->pbBuffer & 0x7f); pBuf->pbBuffer++; pBuf->dwLength--;
// The next 2 bytes are the length
pUserUserIE -> wUserInfoLen = *(pBuf->pbBuffer); pBuf->pbBuffer++; pUserUserIE -> wUserInfoLen = (WORD)(((pUserUserIE -> wUserInfoLen) << 8) + *pBuf->pbBuffer); pBuf->pbBuffer++; pBuf->dwLength -= 2;
// The next byte is the protocol discriminator.
*ProtocolDiscriminator = *pBuf->pbBuffer; pBuf->pbBuffer++; pBuf->dwLength--;
if( pUserUserIE -> wUserInfoLen > 0 ) { pUserUserIE -> wUserInfoLen--; }
if (((LONG)(pBuf->dwLength)) < pUserUserIE -> wUserInfoLen ) { return E_INVALIDARG; }
if (pUserUserIE->wUserInfoLen >= MAX_USER_TO_USER_INFO_LEN) { return E_INVALIDARG; }
CopyMemory( pUserUserIE -> pbUserInfo, pBuf->pbBuffer, pUserUserIE -> wUserInfoLen );
pBuf->pbBuffer += pUserUserIE -> wUserInfoLen; pBuf->dwLength -= pUserUserIE -> wUserInfoLen;
return S_OK; }
//------------------------------------------------------------------------------
// Get the identifier of the next field from the buffer and
// return it. The buffer pointer is not incremented, To
// parse the field and extract its values, the above functions
// should be used. See Q931 table 4-3 for the encodings of the
// identifiers.
//
// Parameters:
// pbBuffer Pointer to the buffer space
//------------------------------------------------------------------------------
BYTE GetNextIdent( void *pbBuffer ) { FIELDIDENTTYPE bIdent;
// Extract the first byte from the buffer
bIdent= (*(FIELDIDENTTYPE *)pbBuffer);
// This value can be returned as the identifier as long
// as it is not a single Octet - Type 1 element.
// Those items must have the value removed from them
// before they can be returned.
if ((bIdent & 0x80) && ((bIdent & TYPE1IDENTMASK) != 0xA0)) { return (BYTE)(bIdent & TYPE1IDENTMASK); }
return bIdent; }
//------------------------------------------------------------------------------
// Parse and return a protocol discriminator. See Q931 section 4.2.
// The octet pointed to by **pbBuffer is the protocol Discriminator.
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// Discrim Pointer to space for discriminator
//------------------------------------------------------------------------------
HRESULT ParseProtocolDiscriminator( PBUFFERDESCR pBuf, PDTYPE *Discrim) { // There has to be at least enough bytes left in the
// string for the operation
if (((LONG)(pBuf->dwLength)) < sizeof(PDTYPE)) { return E_INVALIDARG; }
*Discrim = *(PDTYPE *)pBuf->pbBuffer; if (*Discrim != Q931PDVALUE) { return E_INVALIDARG; }
pBuf->pbBuffer += sizeof(PDTYPE); pBuf->dwLength -= sizeof(PDTYPE); return S_OK; }
//------------------------------------------------------------------------------
// Parse and return a variable length Q931 call reference see
// Q931 section 4.3.
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// dwLength Pointer to space for the length
// pbContents Pointer to space for the bytes of the field
//------------------------------------------------------------------------------
HRESULT ParseCallReference( PBUFFERDESCR pBuf, CRTYPE * wCallRef ) { register int indexI; BYTE dwLength;
// There has to be at least enough bytes left in the
// string for the length byte
if( ((LONG)(pBuf->dwLength)) < 1 ) { return E_INVALIDARG; }
// low 4 bits of the first byte are the length.
// the rest of the bits are zeroes.
dwLength = (BYTE)(*pBuf->pbBuffer & 0x0f); if( dwLength != sizeof(WORD) ) { return E_INVALIDARG; }
pBuf->pbBuffer++; pBuf->dwLength--;
// There has to be at least enough bytes left in the
// string for the operation
if (((LONG)(pBuf->dwLength)) < dwLength) { return E_INVALIDARG; }
*wCallRef = 0; // length can be 0, so initialize here first...
for (indexI = 0; indexI < dwLength; indexI++) { if (indexI < sizeof(CRTYPE)) { // Copy the bytes out of the rest of the buffer
*wCallRef = (WORD)((*wCallRef << 8) + *pBuf->pbBuffer); } pBuf->pbBuffer++; pBuf->dwLength--; }
// note: the high order bit of the value represents callee relationship.
return S_OK; }
//------------------------------------------------------------------------------
// Parse and return a message type. See Q931 section 4.4.
// The octet pointed to by **pbBuffer is the message type.
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// MessageType Pointer to space for message type
//------------------------------------------------------------------------------
HRESULT ParseMessageType( PBUFFERDESCR pBuf, MESSAGEIDTYPE * MessageType ) { // There has to be at least enough bytes left in the
// string for the operation
if (((LONG)(pBuf->dwLength)) < sizeof(MESSAGEIDTYPE)) { return E_INVALIDARG; }
*MessageType = (BYTE)(*((MESSAGEIDTYPE *)pBuf->pbBuffer) & MESSAGETYPEMASK);
if( ISVALIDQ931MESSAGE(*MessageType) == FALSE ) { return E_INVALIDARG; }
pBuf->pbBuffer += sizeof(MESSAGEIDTYPE); pBuf->dwLength -= sizeof(MESSAGEIDTYPE); return S_OK; }
//------------------------------------------------------------------------------
// Parse an optional facility ie field
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// pFieldStruct Pointer to space for parsed facility
// information.
//------------------------------------------------------------------------------
HRESULT ParseFacility( PBUFFERDESCR pBuf, PFACILITYIE pFieldStruct ) { HRESULT hr; memset( (PVOID)pFieldStruct, 0, sizeof(FACILITYIE)); pFieldStruct->fPresent = FALSE;
hr = ParseVariableOctet(pBuf, &pFieldStruct->dwLength, &pFieldStruct->pbContents[0]);
if( FAILED(hr) ) { return hr; }
if (pFieldStruct->dwLength > 0) { pFieldStruct->fPresent = TRUE; }
return S_OK; }
//------------------------------------------------------------------------------
// Parse an optional bearer capability field
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// pFieldStruct Pointer to space for parsed bearer capability
// information.
//------------------------------------------------------------------------------
HRESULT ParseBearerCapability( PBUFFERDESCR pBuf, PBEARERCAPIE pFieldStruct) { HRESULT hr; memset( (PVOID)pFieldStruct, 0, sizeof(BEARERCAPIE)); pFieldStruct->fPresent = FALSE; hr = ParseVariableOctet(pBuf, &pFieldStruct->dwLength, &pFieldStruct->pbContents[0]); if( FAILED(hr) ) { return hr; } if (pFieldStruct->dwLength > 0) { pFieldStruct->fPresent = TRUE; }
return S_OK; }
//------------------------------------------------------------------------------
// Parse an optional cause field
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// pFieldStruct Pointer to space for parsed cause
// information.
//------------------------------------------------------------------------------
HRESULT ParseCause( PBUFFERDESCR pBuf, PCAUSEIE pFieldStruct) { HRESULT hr; memset( (PVOID)pFieldStruct, 0, sizeof(CAUSEIE)); pFieldStruct->fPresent = FALSE;
hr = ParseVariableOctet(pBuf, &pFieldStruct->dwLength, &pFieldStruct->pbContents[0]);
if( FAILED(hr) ) { return hr; }
if (pFieldStruct->dwLength > 0) { pFieldStruct->fPresent = TRUE; }
return S_OK; }
//------------------------------------------------------------------------------
// Parse an optional call state field
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// pFieldStruct Pointer to space for parsed call state
// information.
//------------------------------------------------------------------------------
HRESULT ParseCallState( PBUFFERDESCR pBuf, PCALLSTATEIE pFieldStruct) { memset( (PVOID)pFieldStruct, 0, sizeof(CALLSTATEIE)); pFieldStruct->fPresent = FALSE;
HRESULT hr; hr = ParseVariableOctet(pBuf, &pFieldStruct->dwLength, &pFieldStruct->pbContents[0]);
if( FAILED(hr) ) { return hr; }
if (pFieldStruct->dwLength > 0) { pFieldStruct->fPresent = TRUE; } return S_OK; }
//------------------------------------------------------------------------------
// Parse an optional channel identification field
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// pFieldStruct Pointer to space for parsed channel identity
// information.
//------------------------------------------------------------------------------
HRESULT ParseChannelIdentification( PBUFFERDESCR pBuf, PCHANIDENTIE pFieldStruct) { memset( (PVOID)pFieldStruct, 0, sizeof(CHANIDENTIE)); pFieldStruct->fPresent = FALSE;
HRESULT hr; hr = ParseVariableOctet(pBuf, &pFieldStruct->dwLength, &pFieldStruct->pbContents[0]);
if( FAILED(hr) ) { return hr; }
if (pFieldStruct->dwLength > 0) { pFieldStruct->fPresent = TRUE; } return S_OK; }
//------------------------------------------------------------------------------
// Parse an optional progress indication field
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// pFieldStruct Pointer to space for parsed progress
// information.
//------------------------------------------------------------------------------
HRESULT ParseProgress( PBUFFERDESCR pBuf, PPROGRESSIE pFieldStruct) { memset( (PVOID)pFieldStruct, 0, sizeof(PROGRESSIE)); pFieldStruct->fPresent = FALSE; HRESULT hr; hr = ParseVariableOctet(pBuf, &pFieldStruct->dwLength, &pFieldStruct->pbContents[0]); if( FAILED(hr) ) { return hr; }
if (pFieldStruct->dwLength > 0) { pFieldStruct->fPresent = TRUE; }
return S_OK; }
//------------------------------------------------------------------------------
// Parse an optional network specific facilities field
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// pFieldStruct Pointer to space for parsed network facitlities
// information.
//------------------------------------------------------------------------------
HRESULT ParseNetworkSpec( PBUFFERDESCR pBuf, PNETWORKIE pFieldStruct) { memset( (PVOID)pFieldStruct, 0, sizeof(NETWORKIE)); pFieldStruct->fPresent = FALSE; HRESULT hr; hr = ParseVariableOctet(pBuf, &pFieldStruct->dwLength, &pFieldStruct->pbContents[0]);
if( FAILED(hr) ) { return hr; }
if (pFieldStruct->dwLength > 0) { pFieldStruct->fPresent = TRUE; } return S_OK; }
//------------------------------------------------------------------------------
// Parse an optional notification indicator field
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// pFieldStruct Pointer to space for parse notification indicator
// information.
//------------------------------------------------------------------------------
HRESULT ParseNotificationIndicator( PBUFFERDESCR pBuf, PNOTIFICATIONINDIE pFieldStruct) { memset( (PVOID)pFieldStruct, 0, sizeof(NOTIFICATIONINDIE)); pFieldStruct->fPresent = FALSE; if (GetNextIdent(pBuf->pbBuffer) == IDENT_NOTIFICATION) { HRESULT hr; hr = ParseVariableOctet(pBuf, &pFieldStruct->dwLength, &pFieldStruct->pbContents[0]); if( FAILED(hr) ) { return hr; } if (pFieldStruct->dwLength > 0) { pFieldStruct->fPresent = TRUE; } }
return S_OK; }
//------------------------------------------------------------------------------
// Parse an optional display field
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// pFieldStruct Pointer to space for parsed display
// information.
//------------------------------------------------------------------------------
HRESULT ParseDisplay( PBUFFERDESCR pBuf, PDISPLAYIE pFieldStruct) { HRESULT hr; memset( (PVOID)pFieldStruct, 0, sizeof(DISPLAYIE)); pFieldStruct->fPresent = FALSE;
hr = ParseVariableOctet(pBuf, &pFieldStruct->dwLength, &pFieldStruct->pbContents[0]);
if( FAILED(hr) ) { return hr; }
if (pFieldStruct->dwLength > 0) { pFieldStruct->fPresent = TRUE; }
return S_OK; }
HRESULT ParseDate( PBUFFERDESCR pBuf, PDATEIE pFieldStruct) { HRESULT hr; memset( (PVOID)pFieldStruct, 0, sizeof(DATEIE)); pFieldStruct->fPresent = FALSE;
hr = ParseVariableOctet(pBuf, &pFieldStruct->dwLength, &pFieldStruct->pbContents[0]);
if( FAILED(hr) ) { return hr; }
if (pFieldStruct->dwLength > 0) { pFieldStruct->fPresent = TRUE; } return S_OK; }
//------------------------------------------------------------------------------
// Parse an optional keypad field
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// pFieldStruct Pointer to space for parsed keypad
// information.
//------------------------------------------------------------------------------
HRESULT ParseKeypad( PBUFFERDESCR pBuf, PKEYPADIE pFieldStruct) { HRESULT hr; memset( (PVOID)pFieldStruct, 0, sizeof(KEYPADIE)); pFieldStruct->fPresent = FALSE; hr = ParseVariableOctet(pBuf, &pFieldStruct->dwLength, &pFieldStruct->pbContents[0]); if( FAILED(hr) ) { return hr; }
if (pFieldStruct->dwLength > 0) { pFieldStruct->fPresent = TRUE; } return S_OK; }
//------------------------------------------------------------------------------
// Parse an optional signal field
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// pFieldStruct Pointer to space for parsed signal
// information.
//------------------------------------------------------------------------------
HRESULT ParseSignal( PBUFFERDESCR pBuf, PSIGNALIE pFieldStruct) { HRESULT hr; memset( (PVOID)pFieldStruct, 0, sizeof(SIGNALIE)); pFieldStruct->fPresent = FALSE;
hr = ParseVariableOctet(pBuf, &pFieldStruct->dwLength, &pFieldStruct->pbContents[0]);
if( FAILED(hr) ) { return hr; }
if (pFieldStruct->dwLength > 0) { pFieldStruct->fPresent = TRUE; } return S_OK; }
//------------------------------------------------------------------------------
// Parse an optional information rate field
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// pFieldStruct Pointer to space for parsed information rate
// information.
//------------------------------------------------------------------------------
HRESULT ParseInformationRate( PBUFFERDESCR pBuf, PINFORATEIE pFieldStruct) { HRESULT hr; memset( (PVOID)pFieldStruct, 0, sizeof(INFORATEIE)); pFieldStruct->fPresent = FALSE;
hr = ParseVariableOctet(pBuf, &pFieldStruct->dwLength, &pFieldStruct->pbContents[0]); if( FAILED(hr) ) { return hr; }
if (pFieldStruct->dwLength > 0) { pFieldStruct->fPresent = TRUE; } return S_OK; }
//------------------------------------------------------------------------------
// Parse an optional calling party number field
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// pFieldStruct Pointer to space for parsed
// information.
//------------------------------------------------------------------------------
HRESULT ParseCallingPartyNumber( PBUFFERDESCR pBuf, PCALLINGNUMBERIE pFieldStruct) { HRESULT hr; memset( (PVOID)pFieldStruct, 0, sizeof(CALLINGNUMBERIE)); pFieldStruct->fPresent = FALSE; hr = ParseVariableOctet(pBuf, &pFieldStruct->dwLength, &pFieldStruct->pbContents[0]); if( FAILED(hr) ) { return hr; } if (pFieldStruct->dwLength > 0) { pFieldStruct->fPresent = TRUE; }
return S_OK; }
//------------------------------------------------------------------------------
// Parse an optional calling party subaddress field
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// pFieldStruct Pointer to space for parsed
// information.
//------------------------------------------------------------------------------
HRESULT ParseCallingPartySubaddress( PBUFFERDESCR pBuf, PCALLINGSUBADDRIE pFieldStruct) { HRESULT hr; memset( (PVOID)pFieldStruct, 0, sizeof(CALLINGSUBADDRIE)); pFieldStruct->fPresent = FALSE;
hr = ParseVariableOctet(pBuf, &pFieldStruct->dwLength, &pFieldStruct->pbContents[0]); if( FAILED(hr) ) { return hr; } if (pFieldStruct->dwLength > 0) { pFieldStruct->fPresent = TRUE; }
return S_OK; }
//------------------------------------------------------------------------------
// Parse an optional called party number field
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// pFieldStruct Pointer to space for parsed
// information.
//------------------------------------------------------------------------------
HRESULT ParseCalledPartyNumber( PBUFFERDESCR pBuf, PCALLEDNUMBERIE pFieldStruct ) { memset( (PVOID)pFieldStruct, 0, sizeof(PCALLEDNUMBERIE)); pFieldStruct->fPresent = FALSE; if (GetNextIdent(pBuf->pbBuffer) == IDENT_CALLEDNUMBER) { BYTE RemainingLength = 0; // Need 3 bytes for the ident (1), length (1),
// and type + plan (1) fields.
if (((LONG)(pBuf->dwLength)) < 3) { return E_INVALIDARG; }
// skip the ie identifier...
pBuf->pbBuffer++; pBuf->dwLength--;
// Get the length of the contents following the length field.
RemainingLength = *pBuf->pbBuffer; pBuf->pbBuffer++; pBuf->dwLength--;
// Get the type + plan fields.
if (*(pBuf->pbBuffer) & 0x80) { pFieldStruct->NumberType = (BYTE)(*pBuf->pbBuffer & 0xf0); pFieldStruct->NumberingPlan = (BYTE)(*pBuf->pbBuffer & 0x0f); pBuf->pbBuffer++; pBuf->dwLength--; RemainingLength--; }
// make sure we have at least that much length left...
if (((LONG)(pBuf->dwLength)) < RemainingLength) { return E_INVALIDARG; }
if ( RemainingLength >= MAXVARFIELDLEN) { return E_INVALIDARG; }
pFieldStruct->PartyNumberLength = RemainingLength; pFieldStruct->fPresent = TRUE;
CopyMemory( pFieldStruct->PartyNumbers, pBuf->pbBuffer, RemainingLength );
pBuf->pbBuffer += RemainingLength; pBuf->dwLength -= RemainingLength; }
return S_OK; }
//------------------------------------------------------------------------------
// Parse an optional called party subaddress field
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// pFieldStruct Pointer to space for parsed
// information.
//------------------------------------------------------------------------------
HRESULT ParseCalledPartySubaddress( PBUFFERDESCR pBuf, PCALLEDSUBADDRIE pFieldStruct ) { HRESULT hr; memset( (PVOID)pFieldStruct, 0, sizeof(CALLEDSUBADDRIE)); pFieldStruct->fPresent = FALSE;
hr = ParseVariableOctet(pBuf, &pFieldStruct->dwLength, &pFieldStruct->pbContents[0]); if( FAILED(hr) ) { return hr; } if (pFieldStruct->dwLength > 0) { pFieldStruct->fPresent = TRUE; }
return S_OK; }
//------------------------------------------------------------------------------
// Parse an optional redirecting number field
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// pFieldStruct Pointer to space for parsed
// information.
//------------------------------------------------------------------------------
HRESULT ParseRedirectingNumber( PBUFFERDESCR pBuf, PREDIRECTINGIE pFieldStruct ) { HRESULT hr; memset( (PVOID)pFieldStruct, 0, sizeof(REDIRECTINGIE)); pFieldStruct->fPresent = FALSE;
hr = ParseVariableOctet(pBuf, &pFieldStruct->dwLength, &pFieldStruct->pbContents[0]); if( FAILED(hr) ) { return hr; } if (pFieldStruct->dwLength > 0) { pFieldStruct->fPresent = TRUE; } return S_OK; }
//------------------------------------------------------------------------------
// Parse an optional lower layer compatibility field
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// pFieldStruct Pointer to space for parsed
// information.
//------------------------------------------------------------------------------
HRESULT ParseLowLayerCompatibility( PBUFFERDESCR pBuf, PLLCOMPATIBILITYIE pFieldStruct ) { HRESULT hr; memset( (PVOID)pFieldStruct, 0, sizeof(LLCOMPATIBILITYIE)); pFieldStruct->fPresent = FALSE;
hr = ParseVariableOctet(pBuf, &pFieldStruct->dwLength, &pFieldStruct->pbContents[0]); if( FAILED(hr) ) { return hr; } if (pFieldStruct->dwLength > 0) { pFieldStruct->fPresent = TRUE; }
return S_OK; }
//------------------------------------------------------------------------------
// Parse an optional higher layer compatibility field
//
// Parameters:
// pbBuffer Pointer to a descriptor of the buffer
// containing the length and a pointer
// to the raw bytes of the input stream.
// pFieldStruct Pointer to space for parsed
// information.
//------------------------------------------------------------------------------
HRESULT ParseHighLayerCompatibility( PBUFFERDESCR pBuf, PHLCOMPATIBILITYIE pFieldStruct ) { HRESULT hr; memset( (PVOID)pFieldStruct, 0, sizeof(HLCOMPATIBILITYIE)); pFieldStruct->fPresent = FALSE;
hr = ParseVariableOctet(pBuf, &pFieldStruct->dwLength, &pFieldStruct->pbContents[0]);
if( FAILED(hr) ) { return hr; }
if (pFieldStruct->dwLength > 0) { pFieldStruct->fPresent = TRUE; }
return S_OK; }
HRESULT ParseUserToUser( PBUFFERDESCR pBuf, PUSERUSERIE pFieldStruct ) { BYTE bIdent; HRESULT hr; ZeroMemory( (PVOID)pFieldStruct, sizeof(USERUSERIE)); pFieldStruct->fPresent = FALSE; hr = ParseVariableASN( pBuf, &bIdent, &(pFieldStruct->ProtocolDiscriminator), pFieldStruct ); if( FAILED(hr) ) { return hr; }
if (pFieldStruct->wUserInfoLen > 0) { pFieldStruct->fPresent = TRUE; }
return S_OK; }
HRESULT ParseQ931Field( PBUFFERDESCR pBuf, PQ931MESSAGE pMessage ) { FIELDIDENTTYPE bIdent;
bIdent = GetNextIdent(pBuf->pbBuffer); switch (bIdent) { /*case IDENT_REVCHARGE:
case IDENT_TRANSITNET: case IDENT_RESTART: case IDENT_MORE: case IDENT_REPEAT: case IDENT_SEGMENTED: case IDENT_SHIFT: case IDENT_CALLIDENT: case IDENT_CLOSEDUG: case IDENT_SENDINGCOMPLETE: case IDENT_PACKETSIZE: case IDENT_CONGESTION: case IDENT_NETWORKSPEC: case IDENT_PLWINDOWSIZE: case IDENT_TRANSITDELAY: case IDENT_PLBINARYPARAMS: case IDENT_ENDTOENDDELAY: return E_INVALIDARG;*/
case IDENT_FACILITY:
return ParseFacility( pBuf, &pMessage->Facility );
case IDENT_BEARERCAP: return ParseBearerCapability( pBuf, &pMessage->BearerCapability );
case IDENT_CAUSE: return ParseCause(pBuf, &pMessage->Cause);
case IDENT_CALLSTATE: return ParseCallState(pBuf, &pMessage->CallState);
case IDENT_CHANNELIDENT: return ParseChannelIdentification( pBuf, &pMessage->ChannelIdentification );
case IDENT_PROGRESS: return ParseProgress( pBuf, &pMessage->ProgressIndicator );
case IDENT_NOTIFICATION: return ParseNotificationIndicator( pBuf, &pMessage->NotificationIndicator );
case IDENT_DISPLAY: return ParseDisplay( pBuf, &pMessage->Display );
case IDENT_DATE: return ParseDate( pBuf, &pMessage->Date );
case IDENT_KEYPAD: return ParseKeypad( pBuf, &pMessage->Keypad );
case IDENT_SIGNAL: return ParseSignal(pBuf, &pMessage->Signal);
case IDENT_INFORMATIONRATE: return ParseInformationRate( pBuf, &pMessage->InformationRate );
case IDENT_CALLINGNUMBER: return ParseCallingPartyNumber( pBuf, &pMessage->CallingPartyNumber );
case IDENT_CALLINGSUBADDR: return ParseCallingPartySubaddress(pBuf, &pMessage->CallingPartySubaddress);
case IDENT_CALLEDNUMBER: return ParseCalledPartyNumber(pBuf, &pMessage->CalledPartyNumber);
case IDENT_CALLEDSUBADDR: return ParseCalledPartySubaddress( pBuf, &pMessage->CalledPartySubaddress );
case IDENT_REDIRECTING: return ParseRedirectingNumber( pBuf, &pMessage->RedirectingNumber );
case IDENT_LLCOMPATIBILITY: return ParseLowLayerCompatibility( pBuf, &pMessage->LowLayerCompatibility );
case IDENT_HLCOMPATIBILITY: return ParseHighLayerCompatibility( pBuf, &pMessage->HighLayerCompatibility );
case IDENT_USERUSER: return ParseUserToUser(pBuf, &pMessage->UserToUser);
default:
//Increment the ident byte
pBuf->pbBuffer++; pBuf->dwLength--; return S_OK; } }
//------------------------------------------------------------------------------
// Write a Q931 message type. See Q931 section 4.4.
//------------------------------------------------------------------------------
void WriteMessageType( PBUFFERDESCR pBuf, MESSAGEIDTYPE * MessageType, DWORD* pdwPDULen ) { (*pdwPDULen) += sizeof(MESSAGEIDTYPE);
_ASSERTE( pBuf->dwLength > *pdwPDULen );
*(MESSAGEIDTYPE *)(pBuf->pbBuffer) = (BYTE)(*MessageType & MESSAGETYPEMASK); pBuf->pbBuffer += sizeof(MESSAGEIDTYPE); }
void WriteVariableOctet( PBUFFERDESCR pBuf, BYTE bIdent, BYTE dwLength, BYTE *pbContents, DWORD* pdwPDULen ) { if( pbContents == NULL ) { dwLength = 0; }
// space for the length and the identifier bytes and octet array
(*pdwPDULen) += (2 + dwLength); _ASSERTE( pBuf->dwLength > *pdwPDULen );
// the id byte, then the length byte
// low 7 bits of the first byte are the identifier
*pBuf->pbBuffer = (BYTE)(bIdent & 0x7f); pBuf->pbBuffer++; *pBuf->pbBuffer = dwLength; pBuf->pbBuffer++;
CopyMemory( (PVOID)pBuf->pbBuffer, (PVOID)pbContents, dwLength ); pBuf->pbBuffer += dwLength; }
void WriteUserInformation( PBUFFERDESCR pBuf, BYTE bIdent, WORD wUserInfoLen, BYTE * pbUserInfo, DWORD * pdwPDULen ) { WORD ContentsLength = (WORD)(wUserInfoLen + 1);
// There has to be at least 4 bytes for the IE identifier,
// the contents length, and the protocol discriminator (1 + 2 + 1).
(*pdwPDULen) += (4 + wUserInfoLen); _ASSERTE( pBuf->dwLength > *pdwPDULen );
// low 7 bits of the first byte are the identifier
*pBuf->pbBuffer = (BYTE)(bIdent & 0x7f); pBuf->pbBuffer++;
// write the contents length bytes.
*pBuf->pbBuffer = (BYTE)(ContentsLength >> 8); pBuf->pbBuffer++; *pBuf->pbBuffer = (BYTE)ContentsLength; pBuf->pbBuffer++;
// write the protocol discriminator byte.
*(pBuf->pbBuffer) = Q931_PROTOCOL_X209; pBuf->pbBuffer++;
CopyMemory( (PVOID)pBuf->pbBuffer, (PVOID)pbUserInfo, wUserInfoLen);
pBuf->pbBuffer += wUserInfoLen; }
HRESULT WritePartyNumber( PBUFFERDESCR pBuf, BYTE bIdent, BYTE NumberType, BYTE NumberingPlan, BYTE bPartyNumberLength, BYTE *pbPartyNumbers, DWORD * pdwPDULen ) { if (pbPartyNumbers == NULL) { bPartyNumberLength = 1; }
// space for the ident (1), length (1), and type + plan (1) fields.
(*pdwPDULen) += (2 + bPartyNumberLength); _ASSERTE( pBuf->dwLength > *pdwPDULen ); // low 7 bits of byte 1 are the ie identifier
*pBuf->pbBuffer = (BYTE)(bIdent & 0x7f); pBuf->pbBuffer++;
// byte 2 is the ie contents length following the length field.
*pBuf->pbBuffer = (BYTE)(bPartyNumberLength); pBuf->pbBuffer++;
// byte 3 is the type and plan field.
*pBuf->pbBuffer = (BYTE)(NumberType | NumberingPlan); pBuf->pbBuffer++;
if( pbPartyNumbers != NULL ) { CopyMemory( (PVOID)pBuf->pbBuffer, (PVOID)pbPartyNumbers, bPartyNumberLength-1 ); } pBuf->pbBuffer += (bPartyNumberLength-1);
return S_OK; }
//
//ASN Parsing functions
//
BOOL ParseVendorInfo( OUT PH323_VENDORINFO pDestVendorInfo, IN VendorIdentifier* pVendor ) { memset( (PVOID)pDestVendorInfo, 0, sizeof(H323_VENDORINFO) );
pDestVendorInfo ->bCountryCode = (BYTE)pVendor->vendor.t35CountryCode; pDestVendorInfo ->bExtension = (BYTE)pVendor->vendor.t35Extension; pDestVendorInfo ->wManufacturerCode = pVendor->vendor.manufacturerCode;
if( pVendor->bit_mask & (productId_present) ) { pDestVendorInfo ->pProductNumber = new H323_OCTETSTRING; if( pDestVendorInfo ->pProductNumber == NULL ) { goto cleanup; }
pDestVendorInfo ->pProductNumber->wOctetStringLength = (WORD)min(pVendor->productId.length, H323_MAX_PRODUCT_LENGTH - 1);
pDestVendorInfo ->pProductNumber->pOctetString = (BYTE*) new char[pDestVendorInfo ->pProductNumber->wOctetStringLength + 1];
if( pDestVendorInfo ->pProductNumber->pOctetString == NULL ) { goto cleanup; }
CopyMemory( (PVOID)pDestVendorInfo ->pProductNumber->pOctetString, (PVOID)pVendor->productId.value, pDestVendorInfo -> pProductNumber->wOctetStringLength ); pDestVendorInfo ->pProductNumber->pOctetString[ pDestVendorInfo ->pProductNumber->wOctetStringLength] = '\0'; } if( pVendor->bit_mask & versionId_present ) { pDestVendorInfo ->pVersionNumber = new H323_OCTETSTRING;
if( pDestVendorInfo ->pVersionNumber == NULL ) { goto cleanup; } pDestVendorInfo ->pVersionNumber->wOctetStringLength = (WORD)min(pVendor->versionId.length, H323_MAX_VERSION_LENGTH - 1);
pDestVendorInfo ->pVersionNumber->pOctetString = (BYTE*) new char[pDestVendorInfo ->pVersionNumber->wOctetStringLength+1];
if( pDestVendorInfo ->pVersionNumber->pOctetString == NULL ) { goto cleanup; }
CopyMemory( (PVOID)pDestVendorInfo ->pVersionNumber->pOctetString, (PVOID)pVendor->versionId.value, pDestVendorInfo ->pVersionNumber->wOctetStringLength);
pDestVendorInfo ->pVersionNumber->pOctetString[ pDestVendorInfo ->pVersionNumber->wOctetStringLength] = '\0'; }
return TRUE;
cleanup:
FreeVendorInfo( pDestVendorInfo ); return FALSE; }
BOOL ParseNonStandardData( OUT H323NonStandardData * dstNonStdData, IN H225NonStandardParameter * srcNonStdData ) { H221NonStandard & h221NonStdData = srcNonStdData ->nonStandardIdentifier.u.h221NonStandard;
if( srcNonStdData ->nonStandardIdentifier.choice == H225NonStandardIdentifier_h221NonStandard_chosen ) { dstNonStdData ->bCountryCode = (BYTE)(h221NonStdData.t35CountryCode); dstNonStdData ->bExtension = (BYTE)(h221NonStdData.t35Extension); dstNonStdData ->wManufacturerCode = h221NonStdData.manufacturerCode; }
dstNonStdData->sData.wOctetStringLength = (WORD)srcNonStdData->data.length;
dstNonStdData ->sData.pOctetString = (BYTE *)new char[dstNonStdData ->sData.wOctetStringLength];
if( dstNonStdData -> sData.pOctetString == NULL ) { return FALSE; } CopyMemory( (PVOID)dstNonStdData ->sData.pOctetString, (PVOID)srcNonStdData ->data.value, dstNonStdData ->sData.wOctetStringLength );
return TRUE; }
BOOL AliasAddrToAliasNames( OUT PH323_ALIASNAMES *ppTarget, IN Setup_UUIE_sourceAddress *pSource ) { Setup_UUIE_sourceAddress *CurrentNode = NULL; WORD wCount = 0; int indexI = 0; HRESULT hr;
*ppTarget = NULL;
for( CurrentNode = pSource; CurrentNode; CurrentNode = CurrentNode->next ) { wCount++; }
if( wCount == 0 ) { return TRUE; }
*ppTarget = new H323_ALIASNAMES; if (*ppTarget == NULL) { return FALSE; } ZeroMemory( *ppTarget, sizeof(H323_ALIASNAMES) ); (*ppTarget)->pItems = new H323_ALIASITEM[wCount];
if( (*ppTarget)->pItems == NULL ) { goto cleanup; }
for( CurrentNode = pSource; CurrentNode; CurrentNode = CurrentNode->next ) { hr = AliasAddrToAliasItem( &((*ppTarget)->pItems[indexI]), &(CurrentNode->value));
if( hr == E_OUTOFMEMORY ) { WORD indexJ; //Free everything that has been allocated so far...
for (indexJ = 0; indexJ < indexI; indexJ++) { delete (*ppTarget)->pItems[indexJ].pData; } goto cleanup; } else if( SUCCEEDED(hr) ) { indexI++; } }
// any aliases?
if (indexI > 0) { // save number of aliases
(*ppTarget)->wCount = (WORD)indexI; } else { //free everything
delete (*ppTarget)->pItems; delete (*ppTarget); *ppTarget = NULL; return FALSE; }
return TRUE;
cleanup: if( *ppTarget ) { if( (*ppTarget)->pItems ) { delete (*ppTarget)->pItems; }
delete( *ppTarget ); *ppTarget = NULL; }
return FALSE; }
HRESULT AliasAddrToAliasItem( OUT PH323_ALIASITEM pAliasItem, IN AliasAddress * pAliasAddr ) { WORD indexI;
if( pAliasItem == NULL ) { return E_FAIL; }
memset( (PVOID)pAliasItem, 0, sizeof(H323_ALIASITEM) );
switch( pAliasAddr->choice ) { case h323_ID_chosen:
pAliasItem->wType = h323_ID_chosen; if ((pAliasAddr->u.h323_ID.length != 0) && (pAliasAddr->u.h323_ID.value != NULL)) { pAliasItem->wDataLength = (WORD)pAliasAddr->u.h323_ID.length; pAliasItem->pData = (LPWSTR)new char[(pAliasItem->wDataLength+1) * sizeof(WCHAR)]; if (pAliasItem->pData == NULL) { return E_OUTOFMEMORY; }
CopyMemory( (PVOID)pAliasItem->pData, (PVOID)pAliasAddr->u.h323_ID.value, pAliasItem->wDataLength * sizeof(WCHAR) ); pAliasItem->pData[pAliasItem->wDataLength] = L'\0'; } break;
case e164_chosen:
pAliasItem->wType = e164_chosen; pAliasItem->wDataLength = (WORD)strlen(pAliasAddr->u.e164); pAliasItem->pData = (LPWSTR)new char[(pAliasItem->wDataLength + 1) * sizeof(WCHAR)];
if( pAliasItem->pData == NULL ) { return E_OUTOFMEMORY; }
//converting from byte to UNICODE
for (indexI = 0; indexI < pAliasItem->wDataLength; indexI++) { pAliasItem->pData[indexI] = (WCHAR)pAliasAddr->u.e164[indexI]; }
pAliasItem->pData[pAliasItem->wDataLength] = '\0'; break;
default: return E_INVALIDARG; } // switch
return S_OK; }
void FreeFacilityASN( IN Q931_FACILITY_ASN* pFacilityASN ) { //free non standard data
if( pFacilityASN->fNonStandardDataPresent != NULL ) { delete pFacilityASN->nonStandardData.sData.pOctetString; pFacilityASN->nonStandardData.sData.pOctetString =NULL; } if( pFacilityASN->pAlternativeAliasList != NULL ) { FreeAliasNames(pFacilityASN->pAlternativeAliasList ); pFacilityASN->pAlternativeAliasList = NULL; } }
void FreeAlertingASN( IN Q931_ALERTING_ASN* pAlertingASN ) { FreeProceedingASN( (Q931_CALL_PROCEEDING_ASN*)pAlertingASN ); }
void FreeProceedingASN( IN Q931_CALL_PROCEEDING_ASN* pProceedingASN ) { //free non standard data
if( pProceedingASN->fNonStandardDataPresent == TRUE ) { delete pProceedingASN->nonStandardData.sData.pOctetString; pProceedingASN->nonStandardData.sData.pOctetString = NULL; } if( pProceedingASN->fFastStartPresent &&pProceedingASN->pFastStart ) { FreeFastStart( pProceedingASN->pFastStart ); } }
void FreeSetupASN( IN Q931_SETUP_ASN* pSetupASN ) { if( pSetupASN == NULL ) { return; }
if( pSetupASN->pExtensionAliasItem != NULL ) { if( pSetupASN->pExtensionAliasItem -> pData != NULL ) { delete pSetupASN->pExtensionAliasItem -> pData; }
delete pSetupASN->pExtensionAliasItem; }
if( pSetupASN->pExtraAliasList != NULL ) { FreeAliasNames(pSetupASN->pExtraAliasList); pSetupASN->pExtraAliasList = NULL; } if( pSetupASN->pCalleeAliasList != NULL ) { FreeAliasNames(pSetupASN->pCalleeAliasList); pSetupASN->pCalleeAliasList = NULL; }
if( pSetupASN->pCallerAliasList != NULL ) { FreeAliasNames(pSetupASN->pCallerAliasList); pSetupASN->pCallerAliasList = NULL; }
if( pSetupASN->fNonStandardDataPresent == TRUE ) { delete pSetupASN->nonStandardData.sData.pOctetString; }
if( pSetupASN->EndpointType.pVendorInfo != NULL ) { FreeVendorInfo( pSetupASN->EndpointType.pVendorInfo ); }
if( pSetupASN->fFastStartPresent == TRUE ) { if( pSetupASN->pFastStart != NULL ) { FreeFastStart( pSetupASN->pFastStart ); } } }
void FreeConnectASN( IN Q931_CONNECT_ASN *pConnectASN ) { if( pConnectASN != NULL ) { // Cleanup any dynamically allocated fields within SetupASN
if (pConnectASN->nonStandardData.sData.pOctetString) { delete pConnectASN->nonStandardData.sData.pOctetString; pConnectASN->nonStandardData.sData.pOctetString = NULL; }
if( pConnectASN->EndpointType.pVendorInfo != NULL ) { FreeVendorInfo( pConnectASN->EndpointType.pVendorInfo ); }
if( pConnectASN->fFastStartPresent == TRUE ) { if( pConnectASN->pFastStart != NULL ) { FreeFastStart( pConnectASN->pFastStart ); } } } }
void FreeFastStart( IN PH323_FASTSTART pFastStart ) { PH323_FASTSTART pTempFastStart;
while( pFastStart ) { pTempFastStart = pFastStart -> next;
if(pFastStart -> value) { delete pFastStart -> value; }
delete pFastStart;
pFastStart = pTempFastStart; } }
//FastStart is a plain linked list because it is exactly the same struct
//as defined by ASN.1. This allows to pass on the m_pFastStart member to
//the ASN encoder directly without any conversons
PH323_FASTSTART CopyFastStart( IN PSetup_UUIE_fastStart pSrcFastStart ) { PH323_FASTSTART pCurr, pHead = NULL, pTail = NULL; H323DBG(( DEBUG_LEVEL_TRACE, "CopyFastStart entered." )); while( pSrcFastStart ) { pCurr = new H323_FASTSTART; if( pCurr == NULL ) { FreeFastStart( pHead ); return NULL; }
pCurr -> next = NULL; if( pHead == NULL ) { pHead = pCurr; } else { pTail -> next = pCurr; } pTail = pCurr;
pCurr -> length = pSrcFastStart -> value.length; pCurr -> value = (BYTE*)new char[pCurr -> length]; if( pCurr -> value == NULL ) { FreeFastStart( pHead ); return NULL; }
CopyMemory( (PVOID)pCurr -> value, (PVOID)pSrcFastStart -> value.value, pCurr -> length );
pSrcFastStart = pSrcFastStart->next; } H323DBG(( DEBUG_LEVEL_TRACE, "CopyFastStart exited." )); return pHead; }
void FreeVendorInfo( IN PH323_VENDORINFO pVendorInfo ) { H323DBG(( DEBUG_LEVEL_TRACE, "FreeVendorInfo entered." ));
if( pVendorInfo != NULL ) { if( pVendorInfo ->pProductNumber != NULL ) { if( pVendorInfo ->pProductNumber->pOctetString != NULL ) { delete pVendorInfo ->pProductNumber->pOctetString; }
delete pVendorInfo ->pProductNumber; }
if( pVendorInfo ->pVersionNumber != NULL ) { if( pVendorInfo ->pVersionNumber->pOctetString != NULL ) { delete pVendorInfo ->pVersionNumber->pOctetString; }
delete pVendorInfo ->pVersionNumber; }
memset( (PVOID) pVendorInfo, 0, sizeof(H323_VENDORINFO) ); } H323DBG(( DEBUG_LEVEL_TRACE, "FreeVendorInfo exited." )); }
void FreeAliasNames( IN PH323_ALIASNAMES pSource ) { H323DBG(( DEBUG_LEVEL_TRACE, "FreeAliasNames entered." ));
if( pSource != NULL ) { if( pSource->wCount != 0 ) { // Free everything that has been allocated so far...
int indexI; for( indexI = 0; indexI < pSource->wCount; indexI++ ) { if( pSource->pItems[indexI].pPrefix != NULL ) { H323DBG(( DEBUG_LEVEL_TRACE, "delete prefix:%d.", indexI )); delete pSource->pItems[indexI].pPrefix; } if( pSource->pItems[indexI].pData != NULL ) { H323DBG(( DEBUG_LEVEL_TRACE, "delete pdata:%d.", indexI )); delete pSource->pItems[indexI].pData; } } if( pSource->pItems != NULL ) { H323DBG(( DEBUG_LEVEL_TRACE, "delete pitems." )); delete pSource->pItems; } } H323DBG(( DEBUG_LEVEL_TRACE, "outta loop." )); delete pSource; }
H323DBG(( DEBUG_LEVEL_TRACE, "FreeAliasNames exited." )); }
void FreeAliasItems( IN PH323_ALIASNAMES pSource ) { H323DBG(( DEBUG_LEVEL_TRACE, "FreeAliasItems entered." ));
if( pSource != NULL ) { if( pSource->wCount != 0 ) { // Free everything that has been allocated so far...
int indexI; for( indexI = 0; indexI < pSource->wCount; indexI++ ) { if( pSource->pItems[indexI].pPrefix ) { delete pSource->pItems[indexI].pPrefix; } if( pSource->pItems[indexI].pData ) { delete pSource->pItems[indexI].pData; } } if( pSource->pItems != NULL ) { delete pSource->pItems; pSource->pItems = NULL; } pSource->wCount = 0; } }
H323DBG(( DEBUG_LEVEL_TRACE, "FreeAliasItems exited." )); }
void SetupTPKTHeader( OUT BYTE * pbTpktHeader, IN DWORD dwLength ) { dwLength += TPKT_HEADER_SIZE;
// TPKT requires that the packet size fit in two bytes.
_ASSERTE( dwLength < (1L << 16));
pbTpktHeader[0] = TPKT_VERSION; pbTpktHeader[1] = 0; pbTpktHeader[2] = (BYTE)(dwLength >> 8); pbTpktHeader[3] = (BYTE)dwLength; }
int GetTpktLength( IN char * pTpktHeader ) { BYTE * pbTempPtr = (BYTE*)pTpktHeader; return (pbTempPtr[2] << 8) + pbTempPtr[3]; }
BOOL AddAliasItem( IN OUT PH323_ALIASNAMES pAliasNames, IN BYTE* pbAliasName, IN DWORD dwAliasSize, IN WORD wType ) { H323DBG(( DEBUG_LEVEL_TRACE, "AddAliasItem entered." )); PH323_ALIASITEM pAliasItem; PH323_ALIASITEM tempPtr;
tempPtr = (PH323_ALIASITEM)realloc( pAliasNames -> pItems, sizeof(H323_ALIASITEM) * (pAliasNames->wCount+1) );
if( tempPtr == NULL ) { //restore the old pointer in case enough memory was not available to
//expand the memory block
return FALSE; } pAliasNames -> pItems = tempPtr;
pAliasItem = &(pAliasNames -> pItems[pAliasNames->wCount]);
pAliasItem->pData = (WCHAR*)new char[dwAliasSize];
if( pAliasItem ->pData == NULL ) { return FALSE; } pAliasNames->wCount++;
// transfer memory
CopyMemory((PVOID)pAliasItem ->pData, pbAliasName, dwAliasSize );
// complete alias
pAliasItem ->wType = wType; pAliasItem ->wPrefixLength = 0; pAliasItem ->pPrefix = NULL; pAliasItem ->wDataLength = (WORD)wcslen(pAliasItem -> pData); _ASSERTE( ((pAliasItem->wDataLength+1)*2) == (WORD)dwAliasSize );
H323DBG(( DEBUG_LEVEL_TRACE, "AddAliasItem exited." )); return TRUE; }
void FreeAddressAliases( IN PSetup_UUIE_destinationAddress pAddr ) { PSetup_UUIE_destinationAddress pTempAddr;
while( pAddr ) { pTempAddr = pAddr -> next; if( pAddr ->value.choice == h323_ID_chosen ) { if( pAddr -> value.u.h323_ID.value ) { delete pAddr -> value.u.h323_ID.value; } }
delete pAddr; pAddr = pTempAddr; } }
void CopyTransportAddress( OUT TransportAddress& transportAddress, IN PH323_ADDR pCalleeAddr ) { DWORD dwAddr = pCalleeAddr->Addr.IP_Binary.dwAddr;
transportAddress.choice = ipAddress_chosen; transportAddress.u.ipAddress.ip.length = 4; transportAddress.u.ipAddress.port = pCalleeAddr->Addr.IP_Binary.wPort; *(DWORD*)transportAddress.u.ipAddress.ip.value = htonl( pCalleeAddr->Addr.IP_Binary.dwAddr ); //ReverseAddressAndCopy( transportAddress.u.ipAddress.ip.value, dwAddr);
}
void AddressReverseAndCopy( OUT DWORD * pdwAddr, IN BYTE * addrValue ) { BYTE *addr = (BYTE *)(pdwAddr); addr[3] = addrValue[0]; addr[2] = addrValue[1]; addr[1] = addrValue[2]; addr[0] = addrValue[3]; }
Setup_UUIE_sourceAddress * SetMsgAddressAlias( IN PH323_ALIASNAMES pAliasNames ) { PH323_ALIASITEM pAliasItem; Setup_UUIE_sourceAddress *addressAlias, *currHead = NULL; WORD wCount; int indexI;
for( wCount=0; wCount < pAliasNames->wCount; wCount++ ) { addressAlias = new Setup_UUIE_sourceAddress;
if( addressAlias == NULL ) { goto cleanup; }
ZeroMemory( (PVOID)addressAlias, sizeof(Setup_UUIE_sourceAddress) ); addressAlias -> next = currHead; currHead = addressAlias; pAliasItem = &(pAliasNames->pItems[wCount]);
// then do the required memory copying.
if( pAliasItem -> wType == h323_ID_chosen ) { addressAlias ->value.choice = h323_ID_chosen; addressAlias ->value.u.h323_ID.length = pAliasItem -> wDataLength;
_ASSERTE( pAliasItem -> wDataLength );
addressAlias->value.u.h323_ID.value = new WCHAR[pAliasItem -> wDataLength]; if( addressAlias->value.u.h323_ID.value == NULL ) { goto cleanup; }
CopyMemory((PVOID)addressAlias->value.u.h323_ID.value, (PVOID)pAliasItem->pData, pAliasItem -> wDataLength * sizeof(WCHAR) ); } else if( pAliasItem -> wType == e164_chosen ) { addressAlias ->value.choice = e164_chosen;
for( indexI =0; indexI < pAliasItem->wDataLength; indexI++ ) { addressAlias->value.u.e164[indexI] = (BYTE)pAliasItem->pData[indexI]; }
addressAlias->value.u.e164[ pAliasItem->wDataLength ] = '\0'; } else { continue; } }
return currHead;
cleanup:
FreeAddressAliases( (PSetup_UUIE_destinationAddress)currHead ); return NULL; }
/*BOOL
SetSetupMsgAddressAliasWithPrefix( PH323_ALIASITEM pCallerAlias, Setup_UUIE_sourceAddress *addressAlias ) {
UINT indexI; addressAlias -> next = NULL; UINT uPrefixLength = pCallerAlias -> wPrefixLength; UINT uDataLength = pCallerAlias -> wDataLength;
if(pCallerAlias->wType == h323_ID_chosen) { addressAlias->value.choice = h323_ID_chosen;
addressAlias->value.u.h323_ID.length = (WORD)(uPrefixLength + uDataLength);
if(!addressAlias->value.u.h323_ID.length) { addressAlias->value.u.h323_ID.value = NULL; //no data to copy
return TRUE; }
addressAlias->value.u.h323_ID.value = (WCHAR*)new char[(uPrefixLength + uDataLength) * sizeof(WCHAR)]; if( addressAlias->value.u.h323_ID.value == NULL ) { return FALSE; } addressAlias->value.u.h323_ID.length = (WORD)(uDataLength+uPrefixLength); if( uPrefixLength != 0 ) { CopyMemory((PVOID)addressAlias->value.u.h323_ID.value, (PVOID)pCallerAlias->pPrefix, uPrefixLength * sizeof(WCHAR) ); }
if( uDataLength != 0 ) { CopyMemory((PVOID)&addressAlias->value.u.h323_ID.value[uPrefixLength], (PVOID)pCallerAlias->pData, uDataLength * sizeof(WCHAR) ); } } else if(pCallerAlias->wType == e164_chosen ) { addressAlias->value.choice = e164_chosen; for (indexI = 0; indexI < uPrefixLength; ++indexI) { addressAlias->value.u.e164[indexI] = (BYTE)(pCallerAlias->pPrefix[indexI]); } for (indexI = 0; indexI < uDataLength; ++indexI) { addressAlias->value.u.e164[uPrefixLength + indexI] = (BYTE)(pCallerAlias->pData[indexI]); } for (indexI = uDataLength + uPrefixLength; indexI < sizeof(addressAlias->value.u.e164); ++indexI) { addressAlias->value.u.e164[indexI] = 0; } } else { //un identified alias type
return FALSE; }
return TRUE; }*/
void CopyVendorInfo( OUT VendorIdentifier* vendor ) { H323_VENDORINFO* pVendorInfo = g_pH323Line -> GetVendorInfo();
vendor->bit_mask = 0; vendor->vendor.t35CountryCode = pVendorInfo ->bCountryCode; vendor->vendor.t35Extension = pVendorInfo ->bExtension; vendor->vendor.manufacturerCode = pVendorInfo ->wManufacturerCode; if (pVendorInfo ->pProductNumber && pVendorInfo ->pProductNumber->pOctetString && pVendorInfo ->pProductNumber->wOctetStringLength) { vendor->bit_mask |= productId_present; vendor->productId.length = pVendorInfo ->pProductNumber->wOctetStringLength; CopyMemory( (PVOID)&vendor->productId.value, (PVOID)pVendorInfo ->pProductNumber->pOctetString, pVendorInfo ->pProductNumber->wOctetStringLength); } if (pVendorInfo ->pVersionNumber && pVendorInfo ->pVersionNumber->pOctetString && pVendorInfo ->pVersionNumber->wOctetStringLength) { vendor->bit_mask |= versionId_present; vendor->versionId.length = pVendorInfo ->pVersionNumber->wOctetStringLength; CopyMemory( (PVOID)&vendor->versionId.value, (PVOID)pVendorInfo ->pVersionNumber->pOctetString, pVendorInfo ->pVersionNumber->wOctetStringLength); } }
// check to see if entry is in list
BOOL IsInList( IN LIST_ENTRY * List, IN LIST_ENTRY * Entry ) { LIST_ENTRY * Pos;
for( Pos = List -> Flink; Pos != List; Pos = Pos -> Flink ) { if( Pos == Entry ) { return TRUE; } }
return FALSE; }
void WriteProtocolDiscriminator( PBUFFERDESCR pBuf, DWORD * dwPDULen ) { // space for the length byte
(*dwPDULen)++;
_ASSERTE( pBuf->dwLength > *dwPDULen );
*(PDTYPE *)pBuf->pbBuffer = Q931PDVALUE; pBuf->pbBuffer += sizeof(PDTYPE); }
//------------------------------------------------------------------------------
// Write a variable length Q931 call reference. See Q931 section 4.3.
//------------------------------------------------------------------------------
void WriteCallReference( PBUFFERDESCR pBuf, WORD * pwCallReference, DWORD * pdwPDULen ) { int indexI;
// space for the length byte
(*pdwPDULen) += 1+ sizeof(WORD);
_ASSERTE( pBuf->dwLength > *pdwPDULen );
// the length byte
*pBuf->pbBuffer = (BYTE)sizeof(WORD); pBuf->pbBuffer++;
for (indexI = 0; indexI < sizeof(WORD); indexI++) { // Copy the value bytes to the buffer
*pBuf->pbBuffer = (BYTE)(((*pwCallReference) >> ((sizeof(WORD) - 1 -indexI) * 8)) & 0xff); pBuf->pbBuffer++; } }
void FreeCallForwardParams( IN PCALLFORWARDPARAMS pCallForwardParams ) { LPFORWARDADDRESS pForwardedAddress, pTemp;
if( pCallForwardParams != NULL ) { if( pCallForwardParams->divertedToAlias.pData != NULL ) { delete pCallForwardParams->divertedToAlias.pData; }
pForwardedAddress = pCallForwardParams->pForwardedAddresses; while( pForwardedAddress ) { pTemp = pForwardedAddress->next; FreeForwardAddress( pForwardedAddress ); pForwardedAddress = pTemp; }
delete pCallForwardParams; } }
void FreeForwardAddress( IN LPFORWARDADDRESS pForwardAddress ) { if( pForwardAddress != NULL ) { if( pForwardAddress->callerAlias.pData != NULL ) { delete pForwardAddress->callerAlias.pData; }
if( pForwardAddress->divertedToAlias.pData != NULL ) { delete pForwardAddress->divertedToAlias.pData; }
delete pForwardAddress; } }
//Replaces first alias item in the alias list with the alias address passed.
BOOL MapAliasItem( IN PH323_ALIASNAMES pCalleeAliasNames, IN AliasAddress* pAliasAddress ) { int iIndex;
_ASSERTE( pCalleeAliasNames && pCalleeAliasNames->pItems );
if( pCalleeAliasNames != NULL ) { switch( pAliasAddress->choice ) { case e164_chosen:
pCalleeAliasNames->pItems[0].wType = pAliasAddress->choice; if( pCalleeAliasNames->pItems[0].pData != NULL ) { delete pCalleeAliasNames->pItems[0].pData; } pCalleeAliasNames->pItems[0].wDataLength = (WORD)strlen( pAliasAddress->u.e164 );
pCalleeAliasNames->pItems[0].pData = new WCHAR[pCalleeAliasNames->pItems[0].wDataLength];
if( pCalleeAliasNames->pItems[0].pData == NULL ) { return FALSE; }
for( iIndex=0; iIndex < pCalleeAliasNames->pItems[0].wDataLength; iIndex++ ) { pCalleeAliasNames->pItems[0].pData[iIndex] = pAliasAddress->u.e164[iIndex]; } break;
case h323_ID_chosen:
pCalleeAliasNames->pItems[0].wType = pAliasAddress->choice; if( pCalleeAliasNames->pItems[0].pData != NULL ) { delete pCalleeAliasNames->pItems[0].pData; }
pCalleeAliasNames->pItems[0].wDataLength = (WORD)pAliasAddress->u.h323_ID.length;
pCalleeAliasNames->pItems[0].pData = new WCHAR[pCalleeAliasNames->pItems[0].wDataLength];
if( pCalleeAliasNames->pItems[0].pData == NULL ) { return FALSE; }
CopyMemory( (PVOID)pCalleeAliasNames->pItems[0].pData, (PVOID)pAliasAddress->u.h323_ID.value, pCalleeAliasNames->pItems[0].wDataLength );
break; } } return TRUE; }
//
//creates a new alias list and copies the first alias item from the given list.
//
PH323_ALIASNAMES DuplicateAliasName( PH323_ALIASNAMES pSrcAliasNames ) { PH323_ALIASNAMES pDestAliasNames = new H323_ALIASNAMES; if( pDestAliasNames == NULL ) { return NULL; }
ZeroMemory( pDestAliasNames, sizeof(H323_ALIASNAMES) );
if( !AddAliasItem( pDestAliasNames, pSrcAliasNames->pItems[0].pData, pSrcAliasNames->pItems[0].wType ) ) { delete pDestAliasNames; return NULL; }
return pDestAliasNames; }
|