|
|
#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 { ERROR_OUT(("CInvokeSpecifierListContainer::Construc1: Error creating CSessKeyContainer")); specifier_info->session_key->Release(); delete specifier_info; break; } } else { ERROR_OUT(("CInvokeSpecifierListContainer::Construc1: Error creating INVOKE_SPECIFIER")); break; } }
*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(); 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")); specifier_info->session_key->Release(); delete specifier_info; 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; } }
*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; }
|