|
|
//*************************************************************
//
// File name: GccData.c
//
// Description: Contains routines to support GCC
// user data manipulation
//
// Microsoft Confidential
// Copyright (c) Microsoft Corporation 1991-1997
// All rights reserved
//
//*************************************************************
#include <_tgcc.h>
#include <stdio.h>
//gccDecodeUserData must have input data size at least 21
#define GCC_MINIMUM_DATASIZE 21
//*************************************************************
//
// gccDecodeUserData()
//
// Purpose: Decodes BER data into GCCUserData
//
// Parameters: IN [pData] -- Ptr to BER data
// IN [DataLength] -- BER data length
// OUT [pUserData] -- Ptr to GCCUserData
//
// Return: MCSError
//
// History: 08-10-97 BrianTa Created
//
//*************************************************************
MCSError gccDecodeUserData(IN PBYTE pData, IN UINT DataLength, OUT GCCUserData *pUserData) { MCSError mcsError; PBYTE pBerData; UINT UserDataLength, DataLengthValidate;
TRACE((DEBUG_GCC_DBFLOW, "GCC: gccDecodeUserData entry\n"));
TS_ASSERT(pData); TS_ASSERT(DataLength > 0);
mcsError = MCS_NO_ERROR;
// TRACE((DEBUG_GCC_DBDEBUG,
// "GCC: gccDecodeUserData\n"));
// TSMemoryDump(pData, DataLength);
//DataLength must be at least GCC_MINIMUM_DATASIZE
if (DataLength < GCC_MINIMUM_DATASIZE) { TRACE((DEBUG_GCC_DBERROR, "GCC: Send data size is too small\n")); return MCS_SEND_SIZE_TOO_SMALL; } DataLengthValidate = GCC_MINIMUM_DATASIZE;
pBerData = pData;
// T.124 identifier
ASSERT(*pBerData == 0x00); pBerData++;
ASSERT(*pBerData == 0x05); pBerData++;
// Chosen object
pBerData += 5;
// PDU length
if (*pBerData & 0x80) { pBerData++; DataLengthValidate++; }
pBerData++;
// Connect GCC PDU
ASSERT(*pBerData == 0x00); pBerData++;
ASSERT(*pBerData == 0x08); pBerData++;
// Conference name, etc.
pBerData += 6;
// Key
TS_ASSERT(strncmp(pBerData, "Duca", 4) == 0);
pUserData->key.key_type = GCC_H221_NONSTANDARD_KEY; pUserData->key.u.h221_non_standard_id.octet_string_length = 4; pUserData->key.u.h221_non_standard_id.octet_string = pBerData;
// octet_string
pBerData += 4; UserDataLength = *pBerData++; if (UserDataLength & 0x80) { UserDataLength = ((UserDataLength & 0x7f) << 8) + *pBerData++; DataLengthValidate++; }
//Adjust used datalength
DataLengthValidate += UserDataLength;
//Validate the data length
if (DataLengthValidate > DataLength) { TRACE((DEBUG_GCC_DBERROR, "GCC: Send data size is too small\n")); return MCS_SEND_SIZE_TOO_SMALL; }
TS_ASSERT(UserDataLength > 0);
if (UserDataLength) { pUserData->octet_string = TSHeapAlloc(0, sizeof(*pUserData->octet_string), TS_HTAG_GCC_USERDATA_IN);
if (pUserData->octet_string) { pUserData->octet_string->octet_string_length = (USHORT)UserDataLength; pUserData->octet_string->octet_string = pBerData; } else { TRACE((DEBUG_GCC_DBWARN, "GCC: Cannot allocate octet_string buffer\n"));
mcsError = MCS_ALLOCATION_FAILURE; } } else { TRACE((DEBUG_GCC_DBERROR, "GCC: UserDataLength is zero\n")); mcsError = MCS_SEND_SIZE_TOO_SMALL; }
TRACE((DEBUG_GCC_DBFLOW, "GCC: gccDecodeUserData (len=0x%x) exit - 0x%x\n", UserDataLength, mcsError));
return (mcsError); }
//*************************************************************
//
// gccEncodeUserData()
//
// Purpose: Encodes BER data from GCCUserData
//
// Parameters: IN [usMembers] -- Member count
// IN [ppDataList] -- Ptr to GCCUserData array
// OUT [pUserData] -- Ptr to BER data
// OUT [pUserDataLength] -- Ptr to BER data length
//
// Return: MCSError
//
// History: 08-10-97 BrianTa Created
//
//*************************************************************
MCSError gccEncodeUserData(IN USHORT usMembers, IN GCCUserData **ppDataList, OUT PBYTE *pUserData, OUT UINT *pUserDataLength) { MCSError mcsError; PBYTE pBerData; UINT UserDataLength; UINT len;
TRACE((DEBUG_GCC_DBFLOW, "GCC: gccEncodeUserData entry\n"));
mcsError = MCS_NO_ERROR;
*pUserData = NULL; *pUserDataLength = 0;
if (ppDataList) { len = (*ppDataList)->octet_string->octet_string_length;
pBerData = TSHeapAlloc(0, len + 32, TS_HTAG_GCC_USERDATA_OUT);
if (pBerData) { UserDataLength = 0;
pBerData[UserDataLength++] = 0x00; pBerData[UserDataLength++] = 0x05; pBerData[UserDataLength++] = 0x00; pBerData[UserDataLength++] = 0x14; pBerData[UserDataLength++] = 0x7c; pBerData[UserDataLength++] = 0x00; pBerData[UserDataLength++] = 0x01; pBerData[UserDataLength++] = 0x2a; pBerData[UserDataLength++] = 0x14; pBerData[UserDataLength++] = 0x76; pBerData[UserDataLength++] = 0x0a; pBerData[UserDataLength++] = 0x01; pBerData[UserDataLength++] = 0x01; pBerData[UserDataLength++] = 0x00; pBerData[UserDataLength++] = 0x01; pBerData[UserDataLength++] = 0xc0; pBerData[UserDataLength++] = 0x00;
pBerData[UserDataLength++] = (*ppDataList)->key.u.h221_non_standard_id.octet_string[0]; pBerData[UserDataLength++] = (*ppDataList)->key.u.h221_non_standard_id.octet_string[1]; pBerData[UserDataLength++] = (*ppDataList)->key.u.h221_non_standard_id.octet_string[2]; pBerData[UserDataLength++] = (*ppDataList)->key.u.h221_non_standard_id.octet_string[3];
if (len >= 128) pBerData[UserDataLength++] = (0x80 | (len >> 8));
pBerData[UserDataLength++] = ((*ppDataList)->octet_string->octet_string_length) & 0xff;
memcpy(&pBerData[UserDataLength], (*ppDataList)->octet_string->octet_string, len);
*pUserData = (PBYTE) pBerData; *pUserDataLength = len + UserDataLength;
// TRACE((DEBUG_GCC_DBDEBUG,
// "GCC: gccEncodeUserData\n"));
// TSHeapDump(TS_HEAP_DUMP_ALL,
// *pUserData, *pUserDataLength);
mcsError = MCS_NO_ERROR; } else { TRACE((DEBUG_GCC_DBWARN, "GCC: Cannot allocate BER data buffer\n"));
mcsError = MCS_ALLOCATION_FAILURE; } }
TRACE((DEBUG_GCC_DBFLOW, "GCC: gccEncodeUserData exit - 0x%x\n", mcsError));
return (mcsError); }
//*************************************************************
//
// gccFreeUserData()
//
// Purpose: Frees prev allocated GCCUserData
//
// Parameters: IN [pUserData] -- Ptr to GCCUserData
//
// History: 08-10-97 BrianTa Created
//
//*************************************************************
VOID gccFreeUserData(IN GCCUserData *pUserData) { if (pUserData->octet_string) TShareFree(pUserData->octet_string); }
|