You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1190 lines
36 KiB
1190 lines
36 KiB
#include "precomp.h"
|
|
DEBUG_FILEZONE(ZONE_T120_GCCNC);
|
|
/*
|
|
* invoklst.cpp
|
|
*
|
|
* Copyright (c) 1995 by DataBeam Corporation, Lexington, KY
|
|
*
|
|
* Abstract:
|
|
* This is the implementation file for the class
|
|
* CInvokeSpecifierListContainer. This class manages the data associated
|
|
* with an Application Invoke Request or Indication. This includes a list
|
|
* of applications to be invoked. The CInvokeSpecifierListContainer data
|
|
* container utilizes a CSessKeyContainer container to buffer part of the data
|
|
* associated with each application invoke specifier. Each application
|
|
* invoke specifier also includes a capability ID whose data is buffered
|
|
* internally by the using a CCapIDContainer container. The list
|
|
* of application invoke specifiers is maintained internally by the class
|
|
* through the use of a Rogue Wave list container.
|
|
*
|
|
* Protected Instance Variables:
|
|
* m_InvokeSpecifierList
|
|
* List of structures used to hold the container data internally.
|
|
* m_pAPEListPDU
|
|
* Storage for the "PDU" form of the invoke data.
|
|
* m_fValidAPEListPDU
|
|
* Flag indicating that memory has been allocated to hold the internal
|
|
* "PDU" invoke data.
|
|
* m_cbDataSize
|
|
* Variable holding the size of the memory which will be required to
|
|
* hold any data referenced by the "API" structure.
|
|
*
|
|
* Caveats:
|
|
* None.
|
|
*
|
|
* Author:
|
|
* blp/jbo
|
|
*/
|
|
|
|
#include "ms_util.h"
|
|
#include "invoklst.h"
|
|
|
|
/*
|
|
* CInvokeSpecifierListContainer ()
|
|
*
|
|
* Public Function Description:
|
|
* This constructor is used to create an CInvokeSpecifierListContainer
|
|
* object from a list of "API" application protocol entities.
|
|
*/
|
|
CInvokeSpecifierListContainer::CInvokeSpecifierListContainer(
|
|
UINT number_of_protocol_entities,
|
|
PGCCAppProtocolEntity * app_protocol_entity_list,
|
|
PGCCError pRetCode)
|
|
:
|
|
CRefCount(MAKE_STAMP_ID('I','S','L','C')),
|
|
m_fValidAPEListPDU(FALSE),
|
|
m_cbDataSize(0)
|
|
{
|
|
UINT i;
|
|
PGCCAppProtocolEntity ape;
|
|
INVOKE_SPECIFIER *specifier_info;
|
|
|
|
/*
|
|
* Initialize instance variables.
|
|
*/
|
|
GCCError rc = GCC_NO_ERROR;
|
|
|
|
/*
|
|
* Go through the list of application protocol entities (APE's), saving the
|
|
* necessary information in the internal list of info. structures.
|
|
*/
|
|
for (i = 0; i < number_of_protocol_entities; i++)
|
|
{
|
|
/*
|
|
* Create a new INVOKE_SPECIFIER structure to hold the data for this
|
|
* APE. Check to make sure it was successfully created.
|
|
*/
|
|
DBG_SAVE_FILE_LINE
|
|
specifier_info = new INVOKE_SPECIFIER;
|
|
if (specifier_info != NULL)
|
|
{
|
|
/*
|
|
* Get the APE from the list.
|
|
*/
|
|
ape = app_protocol_entity_list[i];
|
|
|
|
/*
|
|
* Create a new CSessKeyContainer object to hold the session key.
|
|
* Check to make sure construction was successful.
|
|
*/
|
|
DBG_SAVE_FILE_LINE
|
|
specifier_info->session_key = new CSessKeyContainer(&ape->session_key, &rc);
|
|
if ((specifier_info->session_key != NULL) && (rc == GCC_NO_ERROR))
|
|
{
|
|
/*
|
|
* Save the startup channel type and "invoke" flag.
|
|
*/
|
|
specifier_info->startup_channel_type =ape->startup_channel_type;
|
|
specifier_info->must_be_invoked = ape->must_be_invoked;
|
|
|
|
/*
|
|
* Save the capabilities list for this APE in the internal info.
|
|
* structure.
|
|
*/
|
|
rc = SaveAPICapabilities(specifier_info,
|
|
ape->number_of_expected_capabilities,
|
|
ape->expected_capabilities_list);
|
|
|
|
/*
|
|
* Insert the new invoke specifier info structure pointer into
|
|
* the internal list if no error condition exists.
|
|
*/
|
|
if (rc == GCC_NO_ERROR)
|
|
{
|
|
m_InvokeSpecifierList.Append(specifier_info);
|
|
}
|
|
else
|
|
{
|
|
ERROR_OUT(("CInvokeSpecifierListContainer::Construc1: Error saving caps"));
|
|
break;
|
|
}
|
|
}
|
|
else if (specifier_info->session_key == NULL)
|
|
{
|
|
ERROR_OUT(("CInvokeSpecifierListContainer::Construc1: Error creating CSessKeyContainer"));
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ERROR_OUT(("CInvokeSpecifierListContainer::Construc1: Error creating INVOKE_SPECIFIER"));
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(rc != GCC_NO_ERROR)
|
|
{
|
|
if(specifier_info)
|
|
{
|
|
ERROR_OUT(("CInvokeSpecifierListContainer::Construc1: Error creating CSessKeyContainer"));
|
|
if(specifier_info->session_key)
|
|
{
|
|
specifier_info->session_key->Release();
|
|
}
|
|
delete specifier_info;
|
|
}
|
|
}
|
|
|
|
*pRetCode = rc;
|
|
}
|
|
|
|
/*
|
|
* CInvokeSpecifierListContainer ()
|
|
*
|
|
* Public Function Description:
|
|
* This constructor is used to create an CInvokeSpecifierListContainer
|
|
* object from a "PDU" ApplicationProtocolEntityList.
|
|
*/
|
|
CInvokeSpecifierListContainer::CInvokeSpecifierListContainer (
|
|
PApplicationProtocolEntityList protocol_entity_list,
|
|
PGCCError pRetCode)
|
|
:
|
|
CRefCount(MAKE_STAMP_ID('I','S','L','C')),
|
|
m_fValidAPEListPDU(FALSE),
|
|
m_cbDataSize(0)
|
|
{
|
|
ApplicationInvokeSpecifier specifier;
|
|
INVOKE_SPECIFIER *specifier_info;
|
|
|
|
GCCError rc = GCC_NO_ERROR;
|
|
|
|
while (protocol_entity_list != NULL)
|
|
{
|
|
/*
|
|
* Create a new INVOKE_SPECIFIER structure to hold the data for this
|
|
* APE. Check to make sure it was successfully created.
|
|
*/
|
|
DBG_SAVE_FILE_LINE
|
|
specifier_info = new INVOKE_SPECIFIER;
|
|
if (specifier_info != NULL)
|
|
{
|
|
specifier = protocol_entity_list->value;
|
|
|
|
/*
|
|
* Create a CSessKeyContainer object to hold the session key
|
|
* internally. Check to make sure the object is successfully
|
|
* created.
|
|
*/
|
|
DBG_SAVE_FILE_LINE
|
|
specifier_info->session_key = new CSessKeyContainer(&specifier.session_key, &rc);
|
|
if ((specifier_info->session_key != NULL) && (rc == GCC_NO_ERROR))
|
|
{
|
|
/*
|
|
* The session key was saved correctly so check to see if a list
|
|
* of expected capabilities is present and save them if so.
|
|
*/
|
|
if (specifier.bit_mask & EXPECTED_CAPABILITY_SET_PRESENT)
|
|
{
|
|
rc = SavePDUCapabilities(specifier_info, specifier.expected_capability_set);
|
|
if (rc != GCC_NO_ERROR)
|
|
{
|
|
specifier_info->session_key->Release();
|
|
specifier_info->ExpectedCapItemList.DeleteList();
|
|
delete specifier_info;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Save the startup channel type. If the channel type is not
|
|
* present in the PDU then set the channel type in the info
|
|
* strucuture equal to MCS_NO_CHANNEL_TYPE_SPECIFIED;
|
|
*/
|
|
if (specifier.bit_mask & INVOKE_STARTUP_CHANNEL_PRESENT)
|
|
{
|
|
switch (specifier.invoke_startup_channel)
|
|
{
|
|
case CHANNEL_TYPE_STATIC:
|
|
specifier_info->startup_channel_type = MCS_STATIC_CHANNEL;
|
|
break;
|
|
case DYNAMIC_MULTICAST:
|
|
specifier_info->startup_channel_type = MCS_DYNAMIC_MULTICAST_CHANNEL;
|
|
break;
|
|
case DYNAMIC_PRIVATE:
|
|
specifier_info->startup_channel_type = MCS_DYNAMIC_PRIVATE_CHANNEL;
|
|
break;
|
|
case DYNAMIC_USER_ID:
|
|
specifier_info->startup_channel_type = MCS_DYNAMIC_USER_ID_CHANNEL;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
specifier_info->startup_channel_type = MCS_NO_CHANNEL_TYPE_SPECIFIED;
|
|
}
|
|
|
|
/*
|
|
* Insert the new invoke specifier info structure pointer into
|
|
* the internal list if no error condition exists.
|
|
*/
|
|
m_InvokeSpecifierList.Append(specifier_info);
|
|
}
|
|
else if (specifier_info->session_key == NULL)
|
|
{
|
|
ERROR_OUT(("CInvokeSpecifierListContainer::Construc2: Error creating CSessKeyContainer"));
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
ERROR_OUT(("CInvokeSpecifierListContainer::Construc2: Error creating CSessKeyContainer"));
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* Retrieve the next APE in the list.
|
|
*/
|
|
protocol_entity_list = protocol_entity_list->next;
|
|
}
|
|
else
|
|
{
|
|
ERROR_OUT(("CInvokeSpecifierListContainer::Construc2: Error creating INVOKE_SPECIFIER"));
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(rc != GCC_NO_ERROR && specifier_info != NULL)
|
|
{
|
|
if(specifier_info->session_key != NULL)
|
|
{
|
|
specifier_info->session_key->Release();
|
|
}
|
|
|
|
specifier_info->ExpectedCapItemList.DeleteList();
|
|
delete specifier_info;
|
|
}
|
|
|
|
*pRetCode = rc;
|
|
}
|
|
|
|
/*
|
|
* ~CInvokeSpecifierListContainer ()
|
|
*
|
|
* Public Function Description
|
|
* The CInvokeSpecifierListContainer destructor is responsible for
|
|
* freeing any memory allocated to hold the invoke data.
|
|
*
|
|
*/
|
|
CInvokeSpecifierListContainer::~CInvokeSpecifierListContainer(void)
|
|
{
|
|
INVOKE_SPECIFIER *lpInvSpecInfo;
|
|
|
|
/*
|
|
* If "PDU" data has been allocated for this object, free it now.
|
|
*/
|
|
if (m_fValidAPEListPDU)
|
|
FreeApplicationInvokeSpecifierListPDU ();
|
|
|
|
/*
|
|
* Delete any data containers held internally in the list of info.
|
|
* structures by iterating through the internal list.
|
|
*/
|
|
m_InvokeSpecifierList.Reset();
|
|
while (NULL != (lpInvSpecInfo = m_InvokeSpecifierList.Iterate()))
|
|
{
|
|
/*
|
|
* Delete any CSessKeyContainer objects in the INVOKE_SPECIFIER list.
|
|
*/
|
|
if (NULL != lpInvSpecInfo->session_key)
|
|
{
|
|
lpInvSpecInfo->session_key->Release();
|
|
}
|
|
|
|
/*
|
|
* Iterate through the capabilities list held in the INVOKE_SPECIFIER
|
|
* structure.
|
|
*/
|
|
lpInvSpecInfo->ExpectedCapItemList.DeleteList();
|
|
|
|
/*
|
|
* Delete the INVOKE_SPECIFIER structure.
|
|
*/
|
|
delete lpInvSpecInfo;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* LockApplicationInvokeSpecifierList ()
|
|
*
|
|
* Public Function Description:
|
|
* This routine locks the invoke specifier data and determines the amount
|
|
* of memory necessary to hold the associated data.
|
|
*/
|
|
UINT CInvokeSpecifierListContainer::LockApplicationInvokeSpecifierList(void)
|
|
{
|
|
/*
|
|
* If this is the first time this routine is called, determine the size of
|
|
* the memory required to hold the data for the application invoke
|
|
* specifier. Otherwise, just increment the lock count.
|
|
*/
|
|
if (Lock() == 1)
|
|
{
|
|
INVOKE_SPECIFIER *lpInvSpecInfo;
|
|
APP_CAP_ITEM *pExpCapData;
|
|
|
|
/*
|
|
* Set aside memory to hold the pointers to the GCCAppProtocolEntity
|
|
* structures as well as the structures themselves. The "sizeof" the
|
|
* structure must be rounded to an even four-byte boundary.
|
|
*/
|
|
m_cbDataSize = m_InvokeSpecifierList.GetCount() *
|
|
(sizeof(PGCCAppProtocolEntity) + ROUNDTOBOUNDARY(sizeof(GCCAppProtocolEntity)));
|
|
|
|
m_InvokeSpecifierList.Reset();
|
|
while (NULL != (lpInvSpecInfo = m_InvokeSpecifierList.Iterate()))
|
|
{
|
|
/*
|
|
* Lock the data for the session keys, adding the amount of memory
|
|
* necessary to hold the session key data to the total memory size.
|
|
*/
|
|
m_cbDataSize += lpInvSpecInfo->session_key->LockSessionKeyData();
|
|
|
|
lpInvSpecInfo->ExpectedCapItemList.Reset();
|
|
|
|
/*
|
|
* Set aside memory to hold the pointers to the
|
|
* GCCApplicationCabability structures as well as the structures
|
|
* themselves. The "sizeof" the structure must be rounded to an
|
|
* even four-byte boundary.
|
|
*/
|
|
m_cbDataSize += lpInvSpecInfo->ExpectedCapItemList.GetCount() *
|
|
( sizeof(PGCCApplicationCapability) + ROUNDTOBOUNDARY (sizeof(GCCApplicationCapability)) );
|
|
|
|
/*
|
|
* Lock the data for the capability ID's, adding the amount of
|
|
* memory necessary to hold the capability ID data to the total
|
|
* memory size.
|
|
*/
|
|
while (NULL != (pExpCapData = lpInvSpecInfo->ExpectedCapItemList.Iterate()))
|
|
{
|
|
m_cbDataSize += pExpCapData->pCapID->LockCapabilityIdentifierData();
|
|
}
|
|
}
|
|
}
|
|
|
|
return m_cbDataSize;
|
|
}
|
|
|
|
/*
|
|
* GetApplicationInvokeSpecifierList ()
|
|
*
|
|
* Public Function Description:
|
|
* This routine retrieves the invoke specifier data in the form of a
|
|
* list of application protocol entities which are written into the memory
|
|
* provided. This routine is called after "locking" the data.
|
|
*/
|
|
UINT CInvokeSpecifierListContainer::GetApplicationInvokeSpecifierList(
|
|
USHORT *number_of_protocol_entities,
|
|
LPBYTE memory)
|
|
{
|
|
PGCCAppProtocolEntity * ape_list_ptr;
|
|
PGCCAppProtocolEntity ape_ptr;
|
|
PGCCApplicationCapability capability_ptr;
|
|
UINT data_length = 0;
|
|
Int ape_counter = 0;
|
|
Int capability_counter = 0;
|
|
UINT cbDataSizeToRet = 0;
|
|
INVOKE_SPECIFIER *lpInvSpecInfo;
|
|
APP_CAP_ITEM *pExpCapData;
|
|
|
|
/*
|
|
* If the object has been locked, fill in the output structure and
|
|
* the data referenced by the structure. Otherwise, report that the object
|
|
* key has yet to be locked into the "API" form.
|
|
*/
|
|
if (GetLockCount() > 0)
|
|
{
|
|
/*
|
|
* Fill in the output length parameter which indicates how much data
|
|
* referenced outside the structure will be written. This value was
|
|
* calculated on the call to "Lock".
|
|
*/
|
|
cbDataSizeToRet = m_cbDataSize;
|
|
|
|
/*
|
|
* Fill in the number of protocol entities and save a pointer to
|
|
* the memory location passed in. This is where the pointers to
|
|
* the GCCAppProtocolEntity structures will be written. The actual
|
|
* structures will be written into memory immediately following the list
|
|
* of pointers.
|
|
*/
|
|
*number_of_protocol_entities = (USHORT) m_InvokeSpecifierList.GetCount();
|
|
|
|
ape_list_ptr = (PGCCAppProtocolEntity *)memory;
|
|
|
|
/*
|
|
* Save the amount of memory needed to hold the list of structure
|
|
* pointers.
|
|
*/
|
|
data_length = m_InvokeSpecifierList.GetCount() * sizeof(PGCCAppProtocolEntity);
|
|
|
|
/*
|
|
* Move the memory pointer past the list of APE pointers. This is where
|
|
* thefirst APE structure will be written.
|
|
*/
|
|
memory += data_length;
|
|
|
|
/*
|
|
* Iterate through the internal list of INVOKE_SPECIFIER structures,
|
|
* building "API" GCCAppProtocolEntity structures in memory.
|
|
*/
|
|
m_InvokeSpecifierList.Reset();
|
|
while (NULL != (lpInvSpecInfo = m_InvokeSpecifierList.Iterate()))
|
|
{
|
|
/*
|
|
* Save the pointer to the APE structure in the list of pointers.
|
|
*/
|
|
ape_ptr = (PGCCAppProtocolEntity)memory;
|
|
ape_list_ptr[ape_counter++] = ape_ptr;
|
|
|
|
/*
|
|
* Move the memory pointer past the APE structure. This is where
|
|
* thesession key data will be written.
|
|
*/
|
|
memory += ROUNDTOBOUNDARY(sizeof(GCCAppProtocolEntity));
|
|
|
|
/*
|
|
* Fill in the APE structure starting with the session key.
|
|
*/
|
|
data_length = lpInvSpecInfo->session_key->GetGCCSessionKeyData(&ape_ptr->session_key, memory);
|
|
|
|
/*
|
|
* Move the memory pointer past the session key data. This is
|
|
* where the list of pointers to the GCCApplicationCapability
|
|
* structures will be written so save the pointer in the APE
|
|
* structure's capabilities list pointer.
|
|
*/
|
|
memory += data_length;
|
|
|
|
ape_ptr->expected_capabilities_list = (PGCCApplicationCapability *)memory;
|
|
|
|
/*
|
|
* Go ahead and fill in the APE's channel type and invoke flag.
|
|
*/
|
|
ape_ptr->must_be_invoked = lpInvSpecInfo->must_be_invoked;
|
|
ape_ptr->startup_channel_type = lpInvSpecInfo->startup_channel_type;
|
|
ape_ptr->number_of_expected_capabilities = (USHORT) lpInvSpecInfo->ExpectedCapItemList.GetCount();
|
|
|
|
/*
|
|
* Move the memory pointer past the list of GCCApplicationCapability
|
|
* pointers. This is where the first GCCApplicationCapability
|
|
* structure will be written.
|
|
*/
|
|
memory += (lpInvSpecInfo->ExpectedCapItemList.GetCount() *
|
|
sizeof(PGCCApplicationCapability));
|
|
|
|
/*
|
|
* Iterate through the list of capabilities, writing the
|
|
* GCCApplicationCapability structures into memory.
|
|
*/
|
|
capability_counter = 0;
|
|
lpInvSpecInfo->ExpectedCapItemList.Reset();
|
|
while (NULL != (pExpCapData = lpInvSpecInfo->ExpectedCapItemList.Iterate()))
|
|
{
|
|
/*
|
|
* Save the pointer to the capability structure in the list of
|
|
* pointers. Move the memory pointer past the capability
|
|
* structure. This is where the data associated with the
|
|
* capability ID will be written.
|
|
*/
|
|
capability_ptr = (PGCCApplicationCapability)memory;
|
|
ape_ptr->expected_capabilities_list[capability_counter++] = capability_ptr;
|
|
|
|
memory += ROUNDTOBOUNDARY(sizeof(GCCApplicationCapability));
|
|
|
|
/*
|
|
* Fill in the capability structure and add the amount of data
|
|
* written into memory to the total data length.
|
|
*/
|
|
data_length = GetApplicationCapability(pExpCapData, capability_ptr, memory);
|
|
|
|
/*
|
|
* Move the memory pointer past the capability data.
|
|
*/
|
|
memory += data_length;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
number_of_protocol_entities = 0;
|
|
ERROR_OUT(("CInvokeSpecifierListContainer::GetAppInvokeSpecList: Error Data Not Locked"));
|
|
}
|
|
|
|
return cbDataSizeToRet;
|
|
}
|
|
|
|
/*
|
|
* UnLockApplicationInvokeSpecifierList ()
|
|
*
|
|
* Public Function Description:
|
|
* This routine decrements the lock count and frees the memory associated
|
|
* with the "API" invoke specifier list once the lock count reaches zero.
|
|
*/
|
|
void CInvokeSpecifierListContainer::UnLockApplicationInvokeSpecifierList(void)
|
|
{
|
|
if (Unlock(FALSE) == 0)
|
|
{
|
|
INVOKE_SPECIFIER *lpInvSpecInfo;
|
|
APP_CAP_ITEM *pExpCapData;
|
|
|
|
/*
|
|
* Unlock any container data held internally in the list of info.
|
|
* structures by iterating through the internal list.
|
|
*/
|
|
m_InvokeSpecifierList.Reset();
|
|
while (NULL != (lpInvSpecInfo = m_InvokeSpecifierList.Iterate()))
|
|
{
|
|
/*
|
|
* Unlock any CSessKeyContainer objects.
|
|
*/
|
|
lpInvSpecInfo->session_key->UnLockSessionKeyData();
|
|
|
|
/*
|
|
* Iterate through the capabilities list held in the
|
|
* INVOKE_SPECIFIER structure.
|
|
*/
|
|
lpInvSpecInfo->ExpectedCapItemList.Reset();
|
|
while (NULL != (pExpCapData = lpInvSpecInfo->ExpectedCapItemList.Iterate()))
|
|
{
|
|
/*
|
|
* Unlock the CCapIDContainer objects.
|
|
*/
|
|
pExpCapData->pCapID->UnLockCapabilityIdentifierData();
|
|
}
|
|
}
|
|
}
|
|
|
|
// we have to call Release() because we used Unlock(FALSE)
|
|
Release();
|
|
}
|
|
|
|
|
|
/*
|
|
* GetApplicationInvokeSpecifierListPDU ()
|
|
*
|
|
* Public Function Description:
|
|
* This routine retrieves the "PDU" form of an
|
|
* ApplicationProtocolEntityList.
|
|
*/
|
|
GCCError CInvokeSpecifierListContainer::GetApplicationInvokeSpecifierListPDU(
|
|
PApplicationProtocolEntityList *protocol_entity_list)
|
|
{
|
|
GCCError rc = GCC_NO_ERROR;
|
|
PApplicationProtocolEntityList new_pdu_ape_list_ptr;
|
|
PApplicationProtocolEntityList old_pdu_ape_list_ptr = NULL;
|
|
|
|
/*
|
|
* If this is the first time that PDU data has been requested then we must
|
|
* fill in the internal PDU structure and copy it into the structure pointed
|
|
* to by the input parameter. On subsequent calls to "GetPDU" we can just
|
|
* copy the internal PDU structure into the structure pointed to by the
|
|
* input parameter.
|
|
*/
|
|
if (m_fValidAPEListPDU == FALSE)
|
|
{
|
|
INVOKE_SPECIFIER *lpInvSpecInfo;
|
|
|
|
m_fValidAPEListPDU = TRUE;
|
|
|
|
/*
|
|
* Initialize the output parameter to NULL so that the first time
|
|
* through the loop it will be set equal to the first new APE list
|
|
* created in the iterator loop.
|
|
*/
|
|
m_pAPEListPDU = NULL;
|
|
|
|
/*
|
|
* Iterate through the list of "INVOKE_SPECIFIER" structures,
|
|
* converting each into "PDU" form and saving the pointers in the
|
|
* "ApplicationProtocolEntityList" which is a linked list of
|
|
* "ApplicationInvokeSpecifiers".
|
|
*/
|
|
m_InvokeSpecifierList.Reset();
|
|
while (NULL != (lpInvSpecInfo = m_InvokeSpecifierList.Iterate()))
|
|
{
|
|
DBG_SAVE_FILE_LINE
|
|
new_pdu_ape_list_ptr = new ApplicationProtocolEntityList;
|
|
|
|
/*
|
|
* If an allocation failure occurs, call the routine which will
|
|
* iterate through the list freeing any data which had been
|
|
* allocated.
|
|
*/
|
|
if (new_pdu_ape_list_ptr == NULL)
|
|
{
|
|
ERROR_OUT(("CInvokeSpecifierListContainer::GetApplicationInvokeSpecifierListPDU: can't allocate ApplicationProtocolEntityList"));
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
FreeApplicationInvokeSpecifierListPDU ();
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* The first time through, set the PDU structure pointer equal
|
|
* to the first ApplicationProtocolEntityList created. On
|
|
* subsequent loops, set the structure's "next" pointer equal to
|
|
* the new structure.
|
|
*/
|
|
if (m_pAPEListPDU == NULL)
|
|
{
|
|
m_pAPEListPDU = new_pdu_ape_list_ptr;
|
|
}
|
|
else
|
|
{
|
|
old_pdu_ape_list_ptr->next = new_pdu_ape_list_ptr;
|
|
}
|
|
|
|
old_pdu_ape_list_ptr = new_pdu_ape_list_ptr;
|
|
|
|
/*
|
|
* Initialize the new "next" pointer to NULL.
|
|
*/
|
|
new_pdu_ape_list_ptr->next = NULL;
|
|
|
|
if (ConvertInvokeSpecifierInfoToPDU (lpInvSpecInfo, new_pdu_ape_list_ptr) !=
|
|
GCC_NO_ERROR)
|
|
{
|
|
ERROR_OUT(("CInvokeSpecifierListContainer::GetApplicationInvokeSpecifierListPDU: can't convert UserDataInfo to PDU"));
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Copy the internal PDU structure into the structure pointed to by the
|
|
* input parameter.
|
|
*/
|
|
*protocol_entity_list = m_pAPEListPDU;
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* FreeApplicationInvokeSpecifierListPDU ()
|
|
*
|
|
* Public Function Description:
|
|
* This routine is used to free the invoke specifier data held internally
|
|
* in the "PDU" form of a "ApplicationProtocolEntityList".
|
|
*/
|
|
void CInvokeSpecifierListContainer::FreeApplicationInvokeSpecifierListPDU(void)
|
|
{
|
|
PApplicationProtocolEntityList pCurr, pNext;
|
|
INVOKE_SPECIFIER *lpInvSpecInfo;
|
|
APP_CAP_ITEM *pExpCapData;
|
|
|
|
if (m_pAPEListPDU != NULL)
|
|
{
|
|
m_fValidAPEListPDU = FALSE;
|
|
|
|
/*
|
|
* Loop through the list, freeing the data associated with
|
|
* each structure contained in the list.
|
|
*/
|
|
for (pCurr = m_pAPEListPDU; NULL != pCurr; pCurr = pNext)
|
|
{
|
|
pNext = pCurr->next;
|
|
delete pCurr;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Iterate through the internal list, telling each data container object
|
|
* to free any PDU data which it has allocated.
|
|
*/
|
|
m_InvokeSpecifierList.Reset();
|
|
while (NULL != (lpInvSpecInfo = m_InvokeSpecifierList.Iterate()))
|
|
{
|
|
if (lpInvSpecInfo->session_key != NULL)
|
|
{
|
|
lpInvSpecInfo->session_key->FreeSessionKeyDataPDU();
|
|
}
|
|
|
|
/*
|
|
* Iterate through the
|
|
* list, freeing the PDU data for the capability ID's.
|
|
*/
|
|
lpInvSpecInfo->ExpectedCapItemList.Reset();
|
|
while (NULL != (pExpCapData = lpInvSpecInfo->ExpectedCapItemList.Iterate()))
|
|
{
|
|
pExpCapData->pCapID->FreeCapabilityIdentifierDataPDU();
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* GCCError CInvokeSpecifierListContainer::SaveAPICapabilities (
|
|
* INVOKE_SPECIFIER *invoke_specifier,
|
|
* UINT number_of_capabilities,
|
|
* PGCCApplicationCapability * capabilities_list)
|
|
*
|
|
* Private member function of CInvokeSpecifierListContainer.
|
|
*
|
|
* Function Description:
|
|
* This routine is used to save the list of application capabilities passed
|
|
* in as "API" data in the internal list of expected capability data
|
|
* which is held in the internal info structure.
|
|
*
|
|
* Formal Parameters:
|
|
* invoke_specifier (i) Internal structure used to hold invoke data.
|
|
* number_of_capabilities (i) Number of capabilities in list.
|
|
* capabilities_list (i) List of API capabilities to save.
|
|
*
|
|
* Return Value:
|
|
* None.
|
|
*
|
|
* Side Effects:
|
|
* None.
|
|
*
|
|
* Caveats:
|
|
* None.
|
|
*/
|
|
GCCError CInvokeSpecifierListContainer::SaveAPICapabilities(
|
|
INVOKE_SPECIFIER *invoke_specifier,
|
|
UINT number_of_capabilities,
|
|
PGCCApplicationCapability * capabilities_list)
|
|
{
|
|
GCCError rc = GCC_NO_ERROR;
|
|
APP_CAP_ITEM *pExpCapData;
|
|
UINT i;
|
|
|
|
for (i = 0; i < number_of_capabilities; i++)
|
|
{
|
|
/*
|
|
* For each capability, create an APP_CAP_ITEM structure
|
|
* to hold all the necessary data. This structure will be inserted into
|
|
* the list held by the internal info. structure.
|
|
*/
|
|
DBG_SAVE_FILE_LINE
|
|
pExpCapData = new APP_CAP_ITEM((GCCCapabilityType) capabilities_list[i]->capability_class.eType);
|
|
if (pExpCapData != NULL)
|
|
{
|
|
/*
|
|
* Create a new CCapIDContainer object to hold the
|
|
* identifier data.
|
|
*/
|
|
DBG_SAVE_FILE_LINE
|
|
pExpCapData->pCapID = new CCapIDContainer(&capabilities_list[i]->capability_id, &rc);
|
|
if ((pExpCapData->pCapID != NULL) && (rc == GCC_NO_ERROR))
|
|
{
|
|
/*
|
|
* The identifier object was successfully created so fill in the
|
|
* rest of the ApplicationCapabilityData structure.
|
|
*/
|
|
switch (pExpCapData->eCapType)
|
|
{
|
|
case GCC_UNSIGNED_MINIMUM_CAPABILITY:
|
|
pExpCapData->nUnsignedMinimum = capabilities_list[i]->capability_class.nMinOrMax;
|
|
break;
|
|
case GCC_UNSIGNED_MAXIMUM_CAPABILITY:
|
|
pExpCapData->nUnsignedMaximum = capabilities_list[i]->capability_class.nMinOrMax;
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* Add this expected capability to the list.
|
|
*/
|
|
invoke_specifier->ExpectedCapItemList.Append(pExpCapData);
|
|
}
|
|
else
|
|
{
|
|
delete pExpCapData;
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* GCCError CInvokeSpecifierListContainer::SavePDUCapabilities (
|
|
* INVOKE_SPECIFIER *invoke_specifier,
|
|
* PSetOfExpectedCapabilities capabilities_set)
|
|
*
|
|
* Private member function of CInvokeSpecifierListContainer.
|
|
*
|
|
* Function Description:
|
|
* This routine is used to save the list of application capabilities passed
|
|
* in as "PDU" data in the internal list of expected capability data
|
|
* which is held in the internal info. structure.
|
|
*
|
|
* Formal Parameters:
|
|
* invoke_specifier (i) Internal structure used to hold invoke data.
|
|
* capabilities_set (i) List of PDU capabilities to save.
|
|
*
|
|
* Return Value:
|
|
* None.
|
|
*
|
|
* Side Effects:
|
|
* None.
|
|
*
|
|
* Caveats:
|
|
* None.
|
|
*/
|
|
GCCError CInvokeSpecifierListContainer::SavePDUCapabilities(
|
|
INVOKE_SPECIFIER *invoke_specifier,
|
|
PSetOfExpectedCapabilities capabilities_set)
|
|
{
|
|
GCCError rc = GCC_NO_ERROR;
|
|
APP_CAP_ITEM *pExpCapData;
|
|
|
|
while ((capabilities_set != NULL) && (rc == GCC_NO_ERROR))
|
|
{
|
|
/*
|
|
* Create and fill in the new expected capability.
|
|
*/
|
|
DBG_SAVE_FILE_LINE
|
|
pExpCapData = new APP_CAP_ITEM((GCCCapabilityType) capabilities_set->value.capability_class.choice);
|
|
if (pExpCapData != NULL)
|
|
{
|
|
/*
|
|
* Create the CCapIDContainer object used to hold the
|
|
* capability ID data internally. Make sure creation is successful.
|
|
*/
|
|
DBG_SAVE_FILE_LINE
|
|
pExpCapData->pCapID = new CCapIDContainer(&capabilities_set->value.capability_id, &rc);
|
|
if (pExpCapData->pCapID == NULL || rc != GCC_NO_ERROR)
|
|
{
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
delete pExpCapData;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
}
|
|
|
|
/*
|
|
* The capability ID was saved successfully, so go ahead and insert
|
|
* the expected capability data structure into the internal list.
|
|
* Fill in the capability class data.
|
|
*/
|
|
if (rc == GCC_NO_ERROR)
|
|
{
|
|
invoke_specifier->ExpectedCapItemList.Append(pExpCapData);
|
|
|
|
/*
|
|
* Save the capability type and value.
|
|
*/
|
|
switch (capabilities_set->value.capability_class.choice)
|
|
{
|
|
case UNSIGNED_MINIMUM_CHOSEN:
|
|
pExpCapData->nUnsignedMinimum = capabilities_set->value.capability_class.u.unsigned_minimum;
|
|
break;
|
|
case UNSIGNED_MAXIMUM_CHOSEN:
|
|
pExpCapData->nUnsignedMaximum = capabilities_set->value.capability_class.u.unsigned_maximum;
|
|
break;
|
|
}
|
|
}
|
|
|
|
capabilities_set = capabilities_set->next;
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* UINT CInvokeSpecifierListContainer::GetApplicationCapability (
|
|
* APP_CAP_ITEM *capability_info_data,
|
|
* PGCCApplicationCapability api_capability,
|
|
* LPSTR memory)
|
|
*
|
|
* Private member function of CInvokeSpecifierListContainer.
|
|
*
|
|
* Function Description:
|
|
* This routine is used to fill in an API GCCApplicationCapability
|
|
* structure from an internal info structure.
|
|
*
|
|
* Formal Parameters:
|
|
* capability_info_data (i) Internal capability data to convert into
|
|
* API data.
|
|
* api_capability (o) Structure to hold data in API form.
|
|
* memory (o) Memory used to hold bulk data referenced by
|
|
* the API structure.
|
|
*
|
|
* Return Value:
|
|
* None.
|
|
*
|
|
* Side Effects:
|
|
* None.
|
|
*
|
|
* Caveats:
|
|
* None.
|
|
*/
|
|
UINT CInvokeSpecifierListContainer::GetApplicationCapability(
|
|
APP_CAP_ITEM *pExpCapData,
|
|
PGCCApplicationCapability api_capability,
|
|
LPBYTE memory)
|
|
{
|
|
UINT data_length = 0;
|
|
|
|
/*
|
|
* Call the CapabilityID object to retrieve the capability ID data.
|
|
*/
|
|
data_length = pExpCapData->pCapID->GetGCCCapabilityIDData(
|
|
&api_capability->capability_id,
|
|
memory);
|
|
|
|
/*
|
|
* Fill in the remaining fields for the GCCApplicationCapability structure.
|
|
*/
|
|
api_capability->capability_class.eType = pExpCapData->eCapType;
|
|
switch (pExpCapData->eCapType)
|
|
{
|
|
case GCC_UNSIGNED_MINIMUM_CAPABILITY:
|
|
api_capability->capability_class.nMinOrMax = pExpCapData->nUnsignedMinimum;
|
|
break;
|
|
case GCC_UNSIGNED_MAXIMUM_CAPABILITY:
|
|
api_capability->capability_class.nMinOrMax = pExpCapData->nUnsignedMaximum;
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* Fill in the number of entities. Note, however, that this field will not
|
|
* be used in this context.
|
|
*/
|
|
api_capability->number_of_entities = 0;
|
|
|
|
return (data_length);
|
|
}
|
|
|
|
/*
|
|
* GCCError CInvokeSpecifierListContainer::ConvertInvokeSpecifierInfoToPDU(
|
|
* INVOKE_SPECIFIER *specifier_info_ptr,
|
|
* PApplicationProtocolEntityList ape_list_ptr)
|
|
*
|
|
* Private member function of CInvokeSpecifierListContainer.
|
|
*
|
|
* Function Description:
|
|
* This routine converts the invoke specifier from the internal form which
|
|
* is an "INVOKE_SPECIFIER" structure into the "PDU" structure form of
|
|
* a "ApplicationInvokeSpecifier".
|
|
*
|
|
* Formal Parameters:
|
|
* specifier_info_ptr (i) Internal structure holding data to convert.
|
|
* ape_list_ptr (o) PDU structure to hold converted data.
|
|
*
|
|
* Return Value:
|
|
* None.
|
|
*
|
|
* Side Effects:
|
|
* None.
|
|
*
|
|
* Caveats:
|
|
* None.
|
|
*/
|
|
GCCError CInvokeSpecifierListContainer::ConvertInvokeSpecifierInfoToPDU (
|
|
INVOKE_SPECIFIER *specifier_info_ptr,
|
|
PApplicationProtocolEntityList ape_list_ptr)
|
|
{
|
|
GCCError rc = GCC_NO_ERROR;
|
|
PSetOfExpectedCapabilities new_capability_set_ptr;
|
|
PSetOfExpectedCapabilities old_capability_set_ptr = NULL;
|
|
|
|
/*
|
|
* Initialize the invoke specifier bit mask to zero.
|
|
*/
|
|
ape_list_ptr->value.bit_mask = 0;
|
|
|
|
/*
|
|
* Fill in the session key PDU data using the CSessKeyContainer object.
|
|
*/
|
|
rc = specifier_info_ptr->session_key->GetSessionKeyDataPDU(&ape_list_ptr->value.session_key);
|
|
|
|
/*
|
|
* Fill in the capabilities list if any exist.
|
|
*/
|
|
if ((rc == GCC_NO_ERROR) && (specifier_info_ptr->ExpectedCapItemList.GetCount() != 0))
|
|
{
|
|
APP_CAP_ITEM *pExpCapData;
|
|
|
|
ape_list_ptr->value.bit_mask |= EXPECTED_CAPABILITY_SET_PRESENT;
|
|
|
|
/*
|
|
* Set the pointer to the capability set to NULL so that it will be
|
|
* set equal to the first SetOfExpectedCapabilities created inside the
|
|
* iterator loop.
|
|
*/
|
|
ape_list_ptr->value.expected_capability_set = NULL;
|
|
|
|
/*
|
|
* Iterate through the list of APP_CAP_ITEM structures,
|
|
* converting each into "PDU" form and saving the pointers in the
|
|
* "SetOfExpectedCapabilities.
|
|
*/
|
|
specifier_info_ptr->ExpectedCapItemList.Reset();
|
|
while (NULL != (pExpCapData = specifier_info_ptr->ExpectedCapItemList.Iterate()))
|
|
{
|
|
DBG_SAVE_FILE_LINE
|
|
new_capability_set_ptr = new SetOfExpectedCapabilities;
|
|
|
|
/*
|
|
* If an allocation failure occurs, call the routine which will
|
|
* iterate through the list freeing any data which had been
|
|
* allocated.
|
|
*/
|
|
if (new_capability_set_ptr == NULL)
|
|
{
|
|
ERROR_OUT(("CInvokeSpecifierListContainer::ConvertToPDU: alloc error, cleaning up"));
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
FreeApplicationInvokeSpecifierListPDU();
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* The first time through, set the PDU structure pointer equal
|
|
* to the first SetOfExpectedCapabilities created. On
|
|
* subsequent loops, set the structure's "next" pointer equal to
|
|
* the new structure.
|
|
*/
|
|
if (ape_list_ptr->value.expected_capability_set == NULL)
|
|
{
|
|
ape_list_ptr->value.expected_capability_set = new_capability_set_ptr;
|
|
}
|
|
else
|
|
{
|
|
old_capability_set_ptr->next = new_capability_set_ptr;
|
|
}
|
|
|
|
old_capability_set_ptr = new_capability_set_ptr;
|
|
|
|
/*
|
|
* Initialize the new "next" pointer to NULL.
|
|
*/
|
|
new_capability_set_ptr->next = NULL;
|
|
|
|
if (ConvertExpectedCapabilityDataToPDU(pExpCapData, new_capability_set_ptr) != GCC_NO_ERROR)
|
|
{
|
|
ERROR_OUT(("CInvokeSpecifierListContainer::ConvertToPDU: Error converting Capability to PDU"));
|
|
rc = GCC_ALLOCATION_FAILURE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Fill in the channel type if one is specified.
|
|
*/
|
|
if (specifier_info_ptr->startup_channel_type != MCS_NO_CHANNEL_TYPE_SPECIFIED)
|
|
{
|
|
ape_list_ptr->value.bit_mask |= INVOKE_STARTUP_CHANNEL_PRESENT;
|
|
|
|
switch (specifier_info_ptr->startup_channel_type)
|
|
{
|
|
case MCS_STATIC_CHANNEL:
|
|
ape_list_ptr->value.invoke_startup_channel = CHANNEL_TYPE_STATIC;
|
|
break;
|
|
case MCS_DYNAMIC_MULTICAST_CHANNEL:
|
|
ape_list_ptr->value.invoke_startup_channel = DYNAMIC_MULTICAST;
|
|
break;
|
|
case MCS_DYNAMIC_PRIVATE_CHANNEL:
|
|
ape_list_ptr->value.invoke_startup_channel = DYNAMIC_PRIVATE;
|
|
break;
|
|
case MCS_DYNAMIC_USER_ID_CHANNEL:
|
|
ape_list_ptr->value.invoke_startup_channel = DYNAMIC_USER_ID;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Fill in the invoke flag.
|
|
*/
|
|
ape_list_ptr->value.invoke_is_mandatory = (ASN1bool_t)specifier_info_ptr->must_be_invoked;
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* GCCError CInvokeSpecifierListContainer::ConvertExpectedCapabilityDataToPDU(
|
|
* APP_CAP_ITEM *info_ptr,
|
|
* PSetOfExpectedCapabilities pdu_ptr)
|
|
*
|
|
* Private member function of CInvokeSpecifierListContainer.
|
|
*
|
|
* Function Description:
|
|
* This routine converts the capability ID from the internal form which
|
|
* is an APP_CAP_ITEM structure into the "PDU" structure form
|
|
* of a "SetOfExpectedCapabilities".
|
|
*
|
|
* Formal Parameters:
|
|
* info_ptr (i) Internal structure holding data to convert.
|
|
* pdu_ptr (o) PDU structure to hold converted data.
|
|
*
|
|
* Return Value:
|
|
* None.
|
|
*
|
|
* Side Effects:
|
|
* None.
|
|
*
|
|
* Caveats:
|
|
* None.
|
|
*/
|
|
GCCError CInvokeSpecifierListContainer::ConvertExpectedCapabilityDataToPDU (
|
|
APP_CAP_ITEM *pExpCapData,
|
|
PSetOfExpectedCapabilities pdu_ptr)
|
|
{
|
|
GCCError rc = GCC_NO_ERROR;
|
|
|
|
/*
|
|
* Retrieve the capability ID data from the internal
|
|
* CCapIDContainer object.
|
|
*/
|
|
rc = pExpCapData->pCapID->GetCapabilityIdentifierDataPDU(&pdu_ptr->value.capability_id);
|
|
|
|
/*
|
|
* Fill in the capability class.
|
|
*/
|
|
if (rc == GCC_NO_ERROR)
|
|
{
|
|
switch (pExpCapData->eCapType)
|
|
{
|
|
case GCC_LOGICAL_CAPABILITY:
|
|
pdu_ptr->value.capability_class.choice = LOGICAL_CHOSEN;
|
|
break;
|
|
case GCC_UNSIGNED_MINIMUM_CAPABILITY:
|
|
pdu_ptr->value.capability_class.choice = UNSIGNED_MINIMUM_CHOSEN;
|
|
pdu_ptr->value.capability_class.u.unsigned_minimum = pExpCapData->nUnsignedMinimum;
|
|
break;
|
|
case GCC_UNSIGNED_MAXIMUM_CAPABILITY:
|
|
pdu_ptr->value.capability_class.choice = UNSIGNED_MAXIMUM_CHOSEN;
|
|
pdu_ptr->value.capability_class.u.unsigned_maximum = pExpCapData->nUnsignedMaximum;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
|