/****************************************************************************** * * INTEL Corporation Proprietary Information * Copyright (c) 1994, 1995, 1996 Intel Corporation. * * This listing is supplied under the terms of a license agreement * with INTEL Corporation and may not be used, copied, nor disclosed * except in accordance with the terms of that agreement. * *****************************************************************************/ /****************************************************************************** * * AUTHOR: cjutzi (Curt Jutzi) * * $Workfile: api_util.c $ * $Revision: 1.35 $ * $Modtime: 25 Feb 1997 10:36:12 $ * $Log: S:/STURGEON/SRC/H245/SRC/VCS/api_util.c_v $ * * Rev 1.35 25 Feb 1997 11:18:44 MANDREWS * * Fixed dynamic term cap ID generation; dynamic term cap IDs now * start at 32K + 1 and increase from there. Static term cap IDs * (specified by the client) are now restricted to the range of 1..32K. * * Rev 1.34 29 Jan 1997 16:25:06 EHOWARDX * Changed del_cap_descriptor() to match changes to set_cap_descriptor(). * * Rev 1.33 29 Jan 1997 14:44:36 MANDREWS * Fixed warning that occured in release mode build. * * Rev 1.32 28 Jan 1997 14:46:58 EHOWARDX * Potential fix for capability descriptor problem. * * Rev 1.31 14 Oct 1996 14:01:20 EHOWARDX * Unicode changes. * * Rev 1.30 16 Sep 1996 19:46:18 EHOWARDX * Added del_mux_cap for local and remote multiplex capability * to api_deinit to (hopefully) fix memory leak. * * Rev 1.29 11 Oct 1996 15:19:42 EHOWARDX * Fixed H245CopyCap() bug. * * Rev 1.28 28 Aug 1996 11:37:22 EHOWARDX * const changes. * * Rev 1.27 05 Aug 1996 15:31:42 EHOWARDX * * Fixed error in CopyH2250Cap. * * Rev 1.26 02 Aug 1996 21:10:42 EHOWARDX * * H.225.0 Mux cap bug second pass - see if this works. * * Rev 1.25 02 Aug 1996 20:34:20 EHOWARDX * First pass at H.225.0 Mux cap bug. * * Rev 1.24 19 Jul 1996 12:16:30 EHOWARDX * * Rewrite of api_fsm_event() debug routine. * * Rev 1.23 16 Jul 1996 11:47:18 EHOWARDX * * Eliminated H245_ERROR_MUX_CAPS_ALREADY_SET from debug error text function. * * Rev 1.22 09 Jul 1996 17:10:24 EHOWARDX * Fixed pointer offset bug in processing DataType from received * OpenLogicalChannel. * * Rev 1.21 01 Jul 1996 22:12:42 EHOWARDX * * Added Conference and CommunicationMode structures and functions. * * Rev 1.20 24 Jun 1996 12:27:02 EHOWARDX * * Same as 1.17.1.0. * * Rev 1.19 17 Jun 1996 18:10:06 EHOWARDX * * Changed first argument to build_totcap_cap_n_client_from_capability() * from VOID to struct capability *. * * Rev 1.18 14 Jun 1996 18:57:56 EHOWARDX * Geneva update. * * Rev 1.17 10 Jun 1996 16:56:56 EHOWARDX * Removed #include "h245init.x" * * Rev 1.16 06 Jun 1996 18:48:36 EHOWARDX * Fine-tuning tracker functions. * * Rev 1.15 04 Jun 1996 13:56:40 EHOWARDX * Fixed Release build warnings. * * Rev 1.14 31 May 1996 18:21:08 EHOWARDX * Changed map_api_error to reflect updated error codes. * * Rev 1.13 30 May 1996 23:39:02 EHOWARDX * Cleanup. * * Rev 1.12 29 May 1996 15:20:10 EHOWARDX * Change to use HRESULT. * * Rev 1.11 28 May 1996 14:25:28 EHOWARDX * Tel Aviv update. * * Rev 1.10 20 May 1996 22:15:46 EHOWARDX * Completed NonStandard Message and H.225.0 Maximum Skew indication * implementation. Added ASN.1 validation to H245SetLocalCap and * H245SetCapDescriptor. Check-in from Microsoft drop on 17-May-96. * * Rev 1.9 20 May 1996 14:35:16 EHOWARDX * Got rid of asynchronous H245EndConnection/H245ShutDown stuff... * * Rev 1.8 16 May 1996 19:40:48 EHOWARDX * Fixed multiplex capability bug. * * Rev 1.7 16 May 1996 16:53:58 EHOWARDX * Fixed bug in set_capability() - need to set capability entry number * AFTER doing load_cap(). * * Rev 1.6 16 May 1996 15:59:26 EHOWARDX * Fine-tuning H245SetLocalCap/H245DelLocalCap/H245SetCapDescriptor/ * H245DelCapDescriptor behaviour. * * Rev 1.5 15 May 1996 19:53:28 unknown * Fixed H245SetCapDescriptor. * * Rev 1.4 14 May 1996 13:58:04 EHOWARDX * Fixed capability list order (made fifo). * Added support for NonStandard and H.222 mux capabilities to set_cap_descrip * * Rev 1.3 14 May 1996 12:27:24 EHOWARDX * Check-in for integration. * Still need to fix non-standard and H.222 mux capabilities. * * Rev 1.2 13 May 1996 23:16:46 EHOWARDX * Fixed remote terminal capability handling. * * Rev 1.1 11 May 1996 20:33:08 EHOWARDX * Checking in for the night... * * Rev 1.0 09 May 1996 21:06:10 EHOWARDX * Initial revision. * * Rev 1.23.1.8 09 May 1996 19:30:56 EHOWARDX * Redesigned thread locking logic. * Added new API functions. * * Rev 1.23.1.7 27 Apr 1996 21:09:46 EHOWARDX * Changed Channel Numbers to words, added H.225.0 support. * * Rev 1.23.1.6 26 Apr 1996 15:53:52 EHOWARDX * Added H.225.0 Capability support; Changed Capability indication * to only callback once with PDU. * * Rev 1.23.1.5 24 Apr 1996 20:54:36 EHOWARDX * Added new OpenLogicalChannelAck/OpenLogicalChannelReject support. * * Rev 1.23.1.4 23 Apr 1996 14:47:20 EHOWARDX * Disabled dump_pdu. * * Rev 1.23.1.3 19 Apr 1996 12:54:18 EHOWARDX * Updated to 1.28. * * Rev 1.23.1.2 15 Apr 1996 15:10:52 EHOWARDX * Updated to match Curt's current version. * * Rev 1.23.1.1 03 Apr 1996 17:14:56 EHOWARDX * Integrated latest H.323 changes. * * Rev 1.23.1.0 03 Apr 1996 15:54:26 cjutzi * Branched for H.323. * * Rev 1.22 01 Apr 1996 16:43:18 cjutzi * * - Completed ENdConnection, and made asynch.. rather * than sync.. as before * - Changed H245ShutDown to be sync rather than async.. * * Rev 1.21 29 Mar 1996 09:35:16 cjutzi * * - * - fixed ring3 build error message for check_pdu * * Rev 1.20 27 Mar 1996 08:37:28 cjutzi * * - removed error from routine .. was unreferenced variable.. * * Rev 1.19 19 Mar 1996 20:31:06 cjutzi * * - added bi-directional channel stuff * * Rev 1.18 13 Mar 1996 14:12:52 cjutzi * * - clean up.. * * Rev 1.17 13 Mar 1996 09:25:34 cjutzi * * - removed LPCRITICIAL -> CRITICAL SECTION * * * Rev 1.16 12 Mar 1996 16:40:50 cjutzi * * - removed deadlock.. * * Rev 1.15 12 Mar 1996 15:51:08 cjutzi * * - added locking * - implented End Session * - fixed callback bug for deleting caps on cleanup.. * * Rev 1.14 08 Mar 1996 14:04:48 cjutzi * * - added mux table entry code. * - parse all mux table entries.. (as much as needed at this point) * * Rev 1.13 06 Mar 1996 12:35:02 cjutzi * * - typeo.. :-).. for ANS1 error .. * * Rev 1.12 06 Mar 1996 08:49:42 cjutzi * * - added H245_ERROR_ASN1 * - #ifdef'ed the call to check pdu.. in api_fsm * * Rev 1.11 05 Mar 1996 17:37:14 cjutzi * * - implemented Send Local Mux Table.. * - removed bzero/bcopy and changed free api * * * Rev 1.10 01 Mar 1996 13:49:00 cjutzi * * - added hani's new fsm id's * - added debug print for events. * * Rev 1.9 29 Feb 1996 08:38:14 cjutzi * * - added error messages .. * * Rev 1.8 26 Feb 1996 16:33:28 cjutzi * * - fixed GP for tracker. p_prev was not initialized to NULL * * * Rev 1.7 26 Feb 1996 11:06:18 cjutzi * * - added simltanious caps.. and fixed bugs.. * lot's o-changes.. * * Rev 1.6 16 Feb 1996 13:02:34 cjutzi * * - got open / close / request close working in both directions. * * Rev 1.5 15 Feb 1996 10:53:10 cjutzi * * - termcaps working * - changed API interface for MUX_T * - modifed H223 stuff * - cleaned up open * * Rev 1.4 09 Feb 1996 16:58:40 cjutzi * * - cleanup.. and some fixes.. * - added and or changed headers to reflect the log of changes * *****************************************************************************/ /****************************************************************************/ /****************************************************************************/ /****************************************************************************/ /**** *****/ /**** NOTES TO THE READER *****/ /**** *****/ /**** This program has been put together using a a screen which is *****/ /**** wider than 80 characters.. It is best if a similar screen size is *****/ /**** used.. Of course emacs is my preference but 80 col screens will *****/ /**** cause you much frustration.. *****/ /**** *****/ /**** Tabs are set to 8 *****/ /**** *****/ /****************************************************************************/ /****************************************************************************/ /****************************************************************************/ #undef UNICODE #ifndef STRICT #define STRICT #endif #include "precomp.h" /***********************/ /* H245 INCLUDES */ /***********************/ #include "h245api.h" #include "h245com.h" #include "h245sys.x" #include "fsmexpor.h" #include "api_util.x" #include "api_debu.x" #include "h245deb.x" // This array is used to map user-specified Client Type into correct Data Type BYTE DataTypeMap[] = { H245_DATA_DONTCARE, // H245_CLIENT_DONTCARE, H245_DATA_NONSTD, // H245_CLIENT_NONSTD, H245_DATA_VIDEO, // H245_CLIENT_VID_NONSTD, H245_DATA_VIDEO, // H245_CLIENT_VID_H261, H245_DATA_VIDEO, // H245_CLIENT_VID_H262, H245_DATA_VIDEO, // H245_CLIENT_VID_H263, H245_DATA_VIDEO, // H245_CLIENT_VID_IS11172, H245_DATA_AUDIO, // H245_CLIENT_AUD_NONSTD, H245_DATA_AUDIO, // H245_CLIENT_AUD_G711_ALAW64, H245_DATA_AUDIO, // H245_CLIENT_AUD_G711_ALAW56, H245_DATA_AUDIO, // H245_CLIENT_AUD_G711_ULAW64, H245_DATA_AUDIO, // H245_CLIENT_AUD_G711_ULAW56, H245_DATA_AUDIO, // H245_CLIENT_AUD_G722_64, H245_DATA_AUDIO, // H245_CLIENT_AUD_G722_56, H245_DATA_AUDIO, // H245_CLIENT_AUD_G722_48, H245_DATA_AUDIO, // H245_CLIENT_AUD_G723, H245_DATA_AUDIO, // H245_CLIENT_AUD_G728, H245_DATA_AUDIO, // H245_CLIENT_AUD_G729, H245_DATA_AUDIO, // H245_CLIENT_AUD_GDSVD, H245_DATA_AUDIO, // H245_CLIENT_AUD_IS11172, H245_DATA_AUDIO, // H245_CLIENT_AUD_IS13818, H245_DATA_DATA, // H245_CLIENT_DAT_NONSTD, H245_DATA_DATA, // H245_CLIENT_DAT_T120, H245_DATA_DATA, // H245_CLIENT_DAT_DSMCC, H245_DATA_DATA, // H245_CLIENT_DAT_USERDATA, H245_DATA_DATA, // H245_CLIENT_DAT_T84, H245_DATA_DATA, // H245_CLIENT_DAT_T434, H245_DATA_DATA, // H245_CLIENT_DAT_H224, H245_DATA_DATA, // H245_CLIENT_DAT_NLPID, H245_DATA_DATA, // H245_CLIENT_DAT_DSVD, H245_DATA_DATA, // H245_CLIENT_DAT_H222, H245_DATA_ENCRYPT_D, // H245_CLIENT_ENCRYPTION_TX, H245_DATA_ENCRYPT_D, // H245_CLIENT_ENCRYPTION_RX, H245_DATA_CONFERENCE, // H245_CLIENT_CONFERENCE, // Multiplex capabilities H245_DATA_MUX, // H245_CLIENT_MUX_NONSTD, H245_DATA_MUX, // H245_CLIENT_MUX_H222, H245_DATA_MUX, // H245_CLIENT_MUX_H223, H245_DATA_MUX, // H245_CLIENT_MUX_VGMUX, H245_DATA_MUX, // H245_CLIENT_MUX_H2250 }; unsigned ObjectIdLength (const NonStandardIdentifier *pIdentifier) { register unsigned uLength = 0; register POBJECTID pObject = pIdentifier->u.object; ASSERT(pIdentifier->choice == object_chosen); while (pObject) { ++uLength; pObject = pObject->next; } return uLength; } // ObjectIdLength() void FreeNonStandardIdentifier(NonStandardIdentifier *pFree) { register POBJECTID pObject; if (pFree->choice == object_chosen) { // Free Object Identifier while (pFree->u.object) { pObject = pFree->u.object; pFree->u.object = pObject->next; MemFree(pObject); } } } // FreeNonStandardIdentifier() HRESULT CopyNonStandardIdentifier(NonStandardIdentifier *pNew, const NonStandardIdentifier *pOld) { // Copy the base structure *pNew = *pOld; if (pOld->choice == object_chosen) { // Copy Object Identifier POBJECTID pObjectList; POBJECTID pObjectOld; POBJECTID pObjectNew; pNew->u.object = NULL; pObjectList = NULL; pObjectOld = pOld->u.object; while (pObjectOld) { // Allocate new structure pObjectNew = MemAlloc(sizeof(*pObjectNew)); if (pObjectNew == NULL) { H245TRACE(0,1,"API:CopyNonStandardIdentifier - malloc failed"); FreeNonStandardIdentifier(pNew); return H245_ERROR_NOMEM; } // Copy old structure to new structure pObjectNew->value = pObjectOld->value; // Add new structure to list pObjectNew->next = NULL; if (pNew->u.object == NULL) { pNew->u.object = pObjectNew; } else { pObjectList->next = pObjectNew; } pObjectList = pObjectNew; // Get next old structure to copy pObjectOld = pObjectOld->next; } } return H245_ERROR_OK; } // CopyNonStandardIdentifier() void FreeNonStandardParameter(NonStandardParameter *pFree) { FreeNonStandardIdentifier(&pFree->nonStandardIdentifier); if (pFree->data.value) { MemFree(pFree->data.value); pFree->data.value = NULL; } } // FreeNonStandardParameter() HRESULT CopyNonStandardParameter(NonStandardParameter *pNew, const NonStandardParameter *pOld) { // Copy the base structure *pNew = *pOld; if (pOld->nonStandardIdentifier.choice == object_chosen) { HRESULT lResult = CopyNonStandardIdentifier(&pNew->nonStandardIdentifier, &pOld->nonStandardIdentifier); if (lResult != H245_ERROR_OK) { pNew->data.value = NULL; return lResult; } } if (pOld->data.length && pOld->data.value) { // Copy value pNew->data.value = MemAlloc(pOld->data.length); if (pNew->data.value == NULL) { H245TRACE(0,1,"API:CopyNonStandardParameter - malloc failed"); return H245_ERROR_NOMEM; } memcpy(pNew->data.value, pOld->data.value, pOld->data.length); } return H245_ERROR_OK; } // CopyNonStandardParameter() void FreeH222Cap(H222Capability *pFree) { register VCCapabilityLink pVC; while (pFree->vcCapability) { pVC = pFree->vcCapability; pFree->vcCapability = pVC->next; MemFree(pVC); } } // FreeH222Cap() HRESULT CopyH222Cap(H222Capability *pNew, const H222Capability *pOld) { VCCapabilityLink pVcNew; VCCapabilityLink pVcOld; VCCapabilityLink pVcList; pNew->numberOfVCs = pOld->numberOfVCs; pNew->vcCapability = NULL; pVcList = NULL; pVcOld = pOld->vcCapability; while (pVcOld) { // Allocate new structure pVcNew = MemAlloc(sizeof(*pVcNew)); if (pVcNew == NULL) { H245TRACE(0,1,"API:CopyH222Cap - malloc failed"); FreeH222Cap(pNew); return H245_ERROR_NOMEM; } // Copy old structure to new structure *pVcNew = *pVcOld; // Add new structure to list pVcNew->next = NULL; if (pNew->vcCapability == NULL) { pNew->vcCapability = pVcNew; } else if (NULL != pVcList) { pVcList->next = pVcNew; } pVcList = pVcNew; // Get next old structure to copy pVcOld = pVcOld->next; } return H245_ERROR_OK; } // CopyH222Cap() void FreeMediaDistributionCap(MediaDistributionCapability *pFree) { if (pFree->bit_mask & centralizedData_present) { register CentralizedDataLink pLink; while (pFree->centralizedData) { pLink = pFree->centralizedData; pFree->centralizedData = pLink->next; switch (pLink->value.application.choice) { case DACy_applctn_nnStndrd_chosen: FreeNonStandardParameter(&pLink->value.application.u.DACy_applctn_nnStndrd); break; case DACy_applctn_nlpd_chosen: if (pLink->value.application.u.DACy_applctn_nlpd.nlpidData.value != NULL) { MemFree(pLink->value.application.u.DACy_applctn_nlpd.nlpidData.value); } // Fall-through to next case case DACy_applctn_t120_chosen: case DACy_applctn_dsm_cc_chosen: case DACy_applctn_usrDt_chosen: case DACy_applctn_t84_chosen: case DACy_applctn_t434_chosen: case DACy_applctn_h224_chosen: case DACy_an_h222DtPrttnng_chosen : if (pLink->value.application.u.DACy_applctn_t120.choice == DtPrtclCpblty_nnStndrd_chosen) { FreeNonStandardParameter(&pLink->value.application.u.DACy_applctn_t120.u.DtPrtclCpblty_nnStndrd); } break; case DACy_applctn_dsvdCntrl_chosen: // Do nothing break; } // switch MemFree(pLink); } } if (pFree->bit_mask & distributedData_present) { register DistributedDataLink pLink; while (pFree->distributedData) { pLink = pFree->distributedData; pFree->distributedData = pLink->next; switch (pLink->value.application.choice) { case DACy_applctn_nnStndrd_chosen: FreeNonStandardParameter(&pLink->value.application.u.DACy_applctn_nnStndrd); break; case DACy_applctn_nlpd_chosen: if (pLink->value.application.u.DACy_applctn_nlpd.nlpidData.value != NULL) { MemFree(pLink->value.application.u.DACy_applctn_nlpd.nlpidData.value); } // Fall-through to next case case DACy_applctn_t120_chosen: case DACy_applctn_dsm_cc_chosen: case DACy_applctn_usrDt_chosen: case DACy_applctn_t84_chosen: case DACy_applctn_t434_chosen: case DACy_applctn_h224_chosen: case DACy_an_h222DtPrttnng_chosen : if (pLink->value.application.u.DACy_applctn_t120.choice == DtPrtclCpblty_nnStndrd_chosen) { FreeNonStandardParameter(&pLink->value.application.u.DACy_applctn_t120.u.DtPrtclCpblty_nnStndrd); } break; case DACy_applctn_dsvdCntrl_chosen: // Do nothing break; } // switch MemFree(pLink); } } } // FreeMediaDistributionCap() HRESULT CopyMediaDistributionCap(MediaDistributionCapability *pNew, const MediaDistributionCapability *pOld) { HRESULT lResult = H245_ERROR_OK; *pNew = *pOld; pNew->centralizedData = NULL; pNew->distributedData = NULL; if (pOld->bit_mask & centralizedData_present) { CentralizedDataLink pLinkList = NULL; CentralizedDataLink pLinkOld = pOld->centralizedData; CentralizedDataLink pLinkNew; while (pLinkOld) { // Allocate new structure pLinkNew = MemAlloc(sizeof(*pLinkNew)); if (pLinkNew == NULL) { H245TRACE(0,1,"API:CopyMediaDistributionCap - malloc failed"); FreeMediaDistributionCap(pNew); return H245_ERROR_NOMEM; } // Copy old structure to new structure *pLinkNew = *pLinkOld; // Add new structure to list pLinkNew->next = NULL; if (pNew->centralizedData == NULL) { pNew->centralizedData = pLinkNew; } else { pLinkList->next = pLinkNew; } pLinkList = pLinkNew; // Allocate new memory for each pointer in new structure switch (pLinkOld->value.application.choice) { case DACy_applctn_nnStndrd_chosen: lResult = CopyNonStandardParameter(&pLinkNew->value.application.u.DACy_applctn_nnStndrd, &pLinkOld->value.application.u.DACy_applctn_nnStndrd); break; case DACy_applctn_nlpd_chosen: if (pLinkOld->value.application.u.DACy_applctn_nlpd.nlpidData.value != NULL) { pLinkNew->value.application.u.DACy_applctn_nlpd.nlpidData.value = MemAlloc(pLinkNew->value.application.u.DACy_applctn_nlpd.nlpidData.length); if (pLinkNew->value.application.u.DACy_applctn_nlpd.nlpidData.value == NULL) { H245TRACE(0,1,"API:CopyMediaDistributionCap - malloc failed"); FreeMediaDistributionCap(pNew); return H245_ERROR_NOMEM; } memcpy(pLinkNew->value.application.u.DACy_applctn_nlpd.nlpidData.value, pLinkOld->value.application.u.DACy_applctn_nlpd.nlpidData.value, pLinkNew->value.application.u.DACy_applctn_nlpd.nlpidData.length); } // Fall-through to next case case DACy_applctn_t120_chosen: case DACy_applctn_dsm_cc_chosen: case DACy_applctn_usrDt_chosen: case DACy_applctn_t84_chosen: case DACy_applctn_t434_chosen: case DACy_applctn_h224_chosen: case DACy_an_h222DtPrttnng_chosen : if (pLinkOld->value.application.u.DACy_applctn_t120.choice == DtPrtclCpblty_nnStndrd_chosen) { lResult = CopyNonStandardParameter(&pLinkNew->value.application.u.DACy_applctn_t120.u.DtPrtclCpblty_nnStndrd, &pLinkOld->value.application.u.DACy_applctn_t120.u.DtPrtclCpblty_nnStndrd); } break; case DACy_applctn_dsvdCntrl_chosen: // Do nothing break; } // switch if (lResult != H245_ERROR_OK) { FreeMediaDistributionCap(pNew); return lResult; } // Get next old structure to copy pLinkOld = pLinkOld->next; } } if (pOld->bit_mask & distributedData_present) { DistributedDataLink pLinkList = NULL; DistributedDataLink pLinkOld = pOld->distributedData; DistributedDataLink pLinkNew; while (pLinkOld) { // Allocate new structure pLinkNew = MemAlloc(sizeof(*pLinkNew)); if (pLinkNew == NULL) { H245TRACE(0,1,"API:CopyMediaDistributionCap - malloc failed"); FreeMediaDistributionCap(pNew); return H245_ERROR_NOMEM; } // Copy old structure to new structure *pLinkNew = *pLinkOld; // Add new structure to list pLinkNew->next = NULL; if (pNew->distributedData == NULL) { pNew->distributedData = pLinkNew; } else { pLinkList->next = pLinkNew; } pLinkList = pLinkNew; // Allocate new memory for each pointer in new structure switch (pLinkOld->value.application.choice) { case DACy_applctn_nnStndrd_chosen: lResult = CopyNonStandardParameter(&pLinkNew->value.application.u.DACy_applctn_nnStndrd, &pLinkOld->value.application.u.DACy_applctn_nnStndrd); break; case DACy_applctn_nlpd_chosen: if (pLinkOld->value.application.u.DACy_applctn_nlpd.nlpidData.value != NULL) { pLinkNew->value.application.u.DACy_applctn_nlpd.nlpidData.value = MemAlloc(pLinkNew->value.application.u.DACy_applctn_nlpd.nlpidData.length); if (pLinkNew->value.application.u.DACy_applctn_nlpd.nlpidData.value == NULL) { H245TRACE(0,1,"API:CopyMediaDistributionCap - malloc failed"); FreeMediaDistributionCap(pNew); return H245_ERROR_NOMEM; } memcpy(pLinkNew->value.application.u.DACy_applctn_nlpd.nlpidData.value, pLinkOld->value.application.u.DACy_applctn_nlpd.nlpidData.value, pLinkNew->value.application.u.DACy_applctn_nlpd.nlpidData.length); } // Fall-through to next case case DACy_applctn_t120_chosen: case DACy_applctn_dsm_cc_chosen: case DACy_applctn_usrDt_chosen: case DACy_applctn_t84_chosen: case DACy_applctn_t434_chosen: case DACy_applctn_h224_chosen: case DACy_an_h222DtPrttnng_chosen : if (pLinkOld->value.application.u.DACy_applctn_t120.choice == DtPrtclCpblty_nnStndrd_chosen) { lResult = CopyNonStandardParameter(&pLinkNew->value.application.u.DACy_applctn_t120.u.DtPrtclCpblty_nnStndrd, &pLinkOld->value.application.u.DACy_applctn_t120.u.DtPrtclCpblty_nnStndrd); } break; case DACy_applctn_dsvdCntrl_chosen: // Do nothing break; } // switch if (lResult != H245_ERROR_OK) { FreeMediaDistributionCap(pNew); return lResult; } // Get next old structure to copy pLinkOld = pLinkOld->next; } } return H245_ERROR_OK; } // CopyMediaDistributionCap() void FreeH2250Cap(H2250Capability *pFree) { register MediaDistributionCapabilityLink pLink; while (pFree->receiveMultipointCapability.mediaDistributionCapability) { pLink = pFree->receiveMultipointCapability.mediaDistributionCapability; pFree->receiveMultipointCapability.mediaDistributionCapability = pLink->next; FreeMediaDistributionCap(&pLink->value); MemFree(pLink); } while (pFree->transmitMultipointCapability.mediaDistributionCapability) { pLink = pFree->transmitMultipointCapability.mediaDistributionCapability; pFree->transmitMultipointCapability.mediaDistributionCapability = pLink->next; FreeMediaDistributionCap(&pLink->value); MemFree(pLink); } while (pFree->rcvAndTrnsmtMltpntCpblty.mediaDistributionCapability) { pLink = pFree->rcvAndTrnsmtMltpntCpblty.mediaDistributionCapability; pFree->rcvAndTrnsmtMltpntCpblty.mediaDistributionCapability = pLink->next; FreeMediaDistributionCap(&pLink->value); MemFree(pLink); } } // FreeH2250Cap() HRESULT CopyH2250Cap(H2250Capability *pNew, const H2250Capability *pOld) { MediaDistributionCapabilityLink pLinkList; MediaDistributionCapabilityLink pLinkOld; MediaDistributionCapabilityLink pLinkNew; HRESULT lResult; // Copy base structure *pNew = *pOld; pNew->receiveMultipointCapability.mediaDistributionCapability = NULL; pNew->transmitMultipointCapability.mediaDistributionCapability = NULL; pNew->rcvAndTrnsmtMltpntCpblty.mediaDistributionCapability = NULL; pLinkList = NULL; pLinkOld = pOld->receiveMultipointCapability.mediaDistributionCapability; while (pLinkOld) { // Allocate new structure pLinkNew = MemAlloc(sizeof(*pLinkNew)); if (pLinkNew == NULL) { H245TRACE(0,1,"API:CopyH2250Cap - malloc failed"); FreeH2250Cap(pNew); return H245_ERROR_NOMEM; } // Add new structure to list pLinkNew->next = NULL; if (pNew->receiveMultipointCapability.mediaDistributionCapability == NULL) { pNew->receiveMultipointCapability.mediaDistributionCapability = pLinkNew; } else { pLinkList->next = pLinkNew; } pLinkList = pLinkNew; // Copy old structure to new lResult = CopyMediaDistributionCap(&pLinkNew->value, &pLinkOld->value); if (lResult != H245_ERROR_OK) { FreeH2250Cap(pNew); return lResult; } // Get next old structure to copy pLinkOld = pLinkOld->next; } pLinkList = NULL; pLinkOld = pOld->transmitMultipointCapability.mediaDistributionCapability; while (pLinkOld) { // Allocate new structure pLinkNew = MemAlloc(sizeof(*pLinkNew)); if (pLinkNew == NULL) { H245TRACE(0,1,"API:CopyH2250Cap - malloc failed"); FreeH2250Cap(pNew); return H245_ERROR_NOMEM; } // Add new structure to list pLinkNew->next = NULL; if (pNew->transmitMultipointCapability.mediaDistributionCapability == NULL) { pNew->transmitMultipointCapability.mediaDistributionCapability = pLinkNew; } else { pLinkList->next = pLinkNew; } pLinkList = pLinkNew; // Copy old structure to new lResult = CopyMediaDistributionCap(&pLinkNew->value, &pLinkOld->value); if (lResult != H245_ERROR_OK) { FreeH2250Cap(pNew); return lResult; } // Get next old structure to copy pLinkOld = pLinkOld->next; } pLinkList = NULL; pLinkOld = pOld->rcvAndTrnsmtMltpntCpblty.mediaDistributionCapability; while (pLinkOld) { // Allocate new structure pLinkNew = MemAlloc(sizeof(*pLinkNew)); if (pLinkNew == NULL) { H245TRACE(0,1,"API:CopyH2250Cap - malloc failed"); FreeH2250Cap(pNew); return H245_ERROR_NOMEM; } // Add new structure to list pLinkNew->next = NULL; if (pNew->rcvAndTrnsmtMltpntCpblty.mediaDistributionCapability == NULL) { pNew->rcvAndTrnsmtMltpntCpblty.mediaDistributionCapability = pLinkNew; } else { pLinkList->next = pLinkNew; } pLinkList = pLinkNew; // Copy old structure to new lResult = CopyMediaDistributionCap(&pLinkNew->value, &pLinkOld->value); if (lResult != H245_ERROR_OK) { FreeH2250Cap(pNew); return lResult; } // Get next old structure to copy pLinkOld = pLinkOld->next; } return H245_ERROR_OK; } // CopyH2250Cap() HRESULT set_cap_descriptor( struct InstanceStruct *pInstance, H245_CAPDESC_T *pCapDesc, H245_CAPDESCID_T *pCapDescId, struct TerminalCapabilitySet *pTermCapSet) { CapabilityDescriptor *p_cap_desc; unsigned int uId; BOOL bNewDescriptor; unsigned int sim_cap; SmltnsCpbltsLink p_sim_cap; SmltnsCpbltsLink p_sim_cap_lst = NULL; unsigned int alt_cap; H245TRACE(pInstance->dwInst,10,"API:set_cap_descriptor"); ASSERT(*pCapDescId < 256); /* Check if capability descriptor already exists */ p_cap_desc = NULL; for (uId = 0; uId < pTermCapSet->capabilityDescriptors.count; ++uId) { if (pTermCapSet->capabilityDescriptors.value[uId].capabilityDescriptorNumber == *pCapDescId) { p_cap_desc = &pTermCapSet->capabilityDescriptors.value[uId]; break; } } if (p_cap_desc == NULL) { ASSERT(pTermCapSet->capabilityDescriptors.count < 256); p_cap_desc = &pTermCapSet->capabilityDescriptors.value[pTermCapSet->capabilityDescriptors.count]; p_cap_desc->capabilityDescriptorNumber = (CapabilityDescriptorNumber) *pCapDescId; bNewDescriptor = TRUE; } else { bNewDescriptor = FALSE; } if (p_cap_desc->smltnsCpblts) dealloc_simultaneous_cap (p_cap_desc); /* for every entry in the altcap list */ for (sim_cap = 0; sim_cap < pCapDesc->Length; ++sim_cap) { /* check for out of bounds error or memory allocation failure */ if ((pCapDesc->SimCapArray[sim_cap].Length > 256) || (!(p_sim_cap = (SmltnsCpbltsLink)alloc_link(sizeof(*p_sim_cap))))) { if (p_cap_desc->smltnsCpblts) dealloc_simultaneous_cap (p_cap_desc); H245TRACE(pInstance->dwInst,1,"API:set_cap_descriptor - no memory"); return H245_ERROR_NOMEM; } if (!p_cap_desc->smltnsCpblts) { /* first time through */ p_cap_desc->smltnsCpblts = p_sim_cap; } else { /* every other time through */ ASSERT (p_sim_cap_lst); p_sim_cap_lst->next = p_sim_cap; } /* setup for next time through */ p_sim_cap_lst = p_sim_cap; /* load up the new simultanoius cap */ for (alt_cap = 0; alt_cap < pCapDesc->SimCapArray[sim_cap].Length; ++alt_cap) { if (!(find_capid_by_entrynumber (&pInstance->API.PDU_LocalTermCap.TERMCAPSET, pCapDesc->SimCapArray[sim_cap].AltCaps[alt_cap]))) { if (p_cap_desc->smltnsCpblts) dealloc_simultaneous_cap (p_cap_desc); return H245_ERROR_INVALID_CAPID; } /* assign Altcap */ p_sim_cap->value.value[alt_cap] = (unsigned short)pCapDesc->SimCapArray[sim_cap].AltCaps[alt_cap]; } /* for C*/ /* set count */ p_sim_cap->value.count = (unsigned short)pCapDesc->SimCapArray[sim_cap].Length; } /* for */ /* Success! */ /* Set the simultaneous capabilities present bit */ /* Increment the capability descriptor count */ /* Set the descriptors present bit even though it may already be set */ p_cap_desc->bit_mask |= smltnsCpblts_present; if (bNewDescriptor) pTermCapSet->capabilityDescriptors.count++; pTermCapSet->bit_mask |= capabilityDescriptors_present; return H245_ERROR_OK; } HRESULT del_cap_descriptor (struct InstanceStruct *pInstance, H245_CAPDESCID_T CapDescId, struct TerminalCapabilitySet *pTermCapSet) { CapabilityDescriptor *p_cap_desc; unsigned int uId; /* Check if capability descriptor already exists and if it is valid */ p_cap_desc = NULL; for (uId = 0; uId < pTermCapSet->capabilityDescriptors.count; ++uId) { if (pTermCapSet->capabilityDescriptors.value[uId].capabilityDescriptorNumber == CapDescId) { p_cap_desc = &pTermCapSet->capabilityDescriptors.value[uId]; break; } } if (p_cap_desc == NULL || p_cap_desc->smltnsCpblts == NULL || (p_cap_desc->bit_mask & smltnsCpblts_present) == 0) { H245TRACE(pInstance->dwInst,1,"API:del_cap_descriptor - invalid cap descriptor"); return H245_ERROR_INVALID_CAPDESCID; } /* free up the list */ dealloc_simultaneous_cap (p_cap_desc); pTermCapSet->capabilityDescriptors.count--; pTermCapSet->capabilityDescriptors.value[uId] = pTermCapSet->capabilityDescriptors.value[pTermCapSet->capabilityDescriptors.count]; if (pTermCapSet->capabilityDescriptors.count == 0) pTermCapSet->bit_mask &= ~capabilityDescriptors_present; return H245_ERROR_OK; } /***************************************************************************** * * TYPE: Local * * PROCEDURE: free_object_id * * DESCRIPTION * * RETURN: none * * ASSUMES: none * *****************************************************************************/ void free_object_id (POBJECTID p_obj_id) { register POBJECTID p_obj_tmp; /* free all the objects */ while (p_obj_id != NULL) { p_obj_tmp = p_obj_id; p_obj_id = p_obj_id->next; MemFree (p_obj_tmp); } } /***************************************************************************** * * TYPE: GLOBAL * * PROCEDURE: free_mux_element * * DESCRIPTION * free mux element desciptor list * * RETURN: * * ASSUME: List is Locked * *****************************************************************************/ void free_mux_element (MultiplexElement *p_ASN_mux_el) { int count = 0; if (p_ASN_mux_el->type.choice == subElementList_chosen) { if (p_ASN_mux_el->type.u.subElementList) { for (count = p_ASN_mux_el->type.u.subElementList->count; count; count--) { free_mux_element (&(p_ASN_mux_el->type.u.subElementList->value[count])); } MemFree (p_ASN_mux_el->type.u.subElementList); } } } /***************************************************************************** * * TYPE: GLOBAL * * PROCEDURE: free_mux_desc_list * * DESCRIPTION * free mux element desciptor list * * RETURN: * * ASSUME: List is Locked * *****************************************************************************/ void free_mux_desc_list (MultiplexEntryDescriptorLink p_ASN_med_link) { MultiplexEntryDescriptorLink p_ASN_med_link_tofree; /* free all entries on descriptor list */ while (p_ASN_med_link) { int count = 0; for (count = p_ASN_med_link->value.elementList.count; count; count--) { free_mux_element (&(p_ASN_med_link->value.elementList.value[count])); } p_ASN_med_link_tofree = p_ASN_med_link; p_ASN_med_link = p_ASN_med_link->next; MemFree (p_ASN_med_link_tofree); } } /***************************************************************************** * * TYPE: * * PROCEDURE: alloc_link * * DESCRIPTION: * * RETURN: * *****************************************************************************/ H245_LINK_T * alloc_link (int size) { H245_LINK_T *p_link = (H245_LINK_T *)MemAlloc (size); if (p_link) p_link->p_next = NULL; return p_link; } /***************************************************************************** * * TYPE: * * PROCEDURE: alloc_new_capid - * * DESCRIPTION: * * ASSUMES: Capability Table is locked before call * Caller marks the bit_mask indicating when * the table entry can be used. * * RETURN: NULL if not found * pCapLink if found * *****************************************************************************/ CapabilityTableLink alloc_link_cap_entry ( struct TerminalCapabilitySet *pTermCapSet) { register CapabilityTableLink pCapLink; register CapabilityTableLink pCapLinkSearch; ASSERT(pTermCapSet != NULL); pCapLink = (CapabilityTableLink)MemAlloc(sizeof(*pCapLink)); if (pCapLink) { pCapLink->next = NULL; pCapLink->value.bit_mask = 0; pCapLinkSearch = pTermCapSet->capabilityTable; // Insert at END of linked list if (pCapLinkSearch) { while (pCapLinkSearch->next) { pCapLinkSearch = pCapLinkSearch->next; } pCapLinkSearch->next = pCapLink; } else { pTermCapSet->capabilityTable = pCapLink; } } return pCapLink; } // alloc_link_cap_entry() /***************************************************************************** * * TYPE: GLOBAL * * PROCEDURE: dealloc_simultaneous_cap - deallocate alternative Cap Set * * DESCRIPTION * * RETURN: N/A * * ASSUME: List is Locked * *****************************************************************************/ void dealloc_simultaneous_cap (CapabilityDescriptor *pCapdes) { SmltnsCpbltsLink p_sim_cap; SmltnsCpbltsLink p_sim_cap_tmp; pCapdes->bit_mask &= ~smltnsCpblts_present; for (p_sim_cap = pCapdes->smltnsCpblts; p_sim_cap; ) { p_sim_cap_tmp = p_sim_cap->next; MemFree (p_sim_cap); p_sim_cap = p_sim_cap_tmp; } /* for */ pCapdes->smltnsCpblts = NULL; } /* procedrue */ /***************************************************************************** * * TYPE: local * * PROCEDURE: find_capid_by_entrynumber - * * DESCRIPTION: * * RETURN: NULL - if error * capabiliytTableLink if ok * * ASSUME: List is Locked * *****************************************************************************/ CapabilityTableLink find_capid_by_entrynumber ( struct TerminalCapabilitySet *pTermCapSet, H245_CAPID_T cap_id ) { register CapabilityTableLink pCapLink; ASSERT (pTermCapSet != NULL); for (pCapLink = pTermCapSet->capabilityTable; pCapLink; pCapLink = pCapLink->next) { if (pCapLink->value.capabilityTableEntryNumber == cap_id && pCapLink->value.bit_mask == capability_present) { return pCapLink; } } return NULL; } /***************************************************************************** * * TYPE: Global * * PROCEDURE: load_cap * * DESCRIPTION: Takes a totcap and loads a capability structure * i.e. Input is the total capability * Output is the *pCapability * NOTE: Non Standard Capabilities.. allocate memory * which needs to be free'd later.. * * RETURN: * *****************************************************************************/ HRESULT load_cap (struct Capability *pCapability, /* output */ const H245_TOTCAP_T *pTotCap ) /* input */ { HRESULT lError = H245_ERROR_OK; H245TRACE(0,10,"API:laod_cap <-"); switch (pTotCap->ClientType) { /* General NON Standard Cap */ case H245_CLIENT_NONSTD: H245TRACE(0,20,"API:load_cap - H245_CLIENT_NONSTD"); lError = CopyNonStandardParameter(&pCapability->u.Capability_nonStandard, &pTotCap->Cap.H245_NonStd); break; /* VIDEO */ case H245_CLIENT_VID_NONSTD: H245TRACE(0,20,"API:load_cap - H245_CLIENT_VID_NONSTD"); lError = CopyNonStandardParameter(&pCapability->u.receiveVideoCapability.u.VdCpblty_nonStandard, &pTotCap->Cap.H245Vid_NONSTD); pCapability->u.receiveVideoCapability.choice = VdCpblty_nonStandard_chosen; break; case H245_CLIENT_VID_H261: H245TRACE(0,20,"API:load_cap - H245_CLIENT_VID_H261"); pCapability->u.receiveVideoCapability.u.h261VideoCapability = pTotCap->Cap.H245Vid_H261; pCapability->u.receiveVideoCapability.choice = h261VideoCapability_chosen; break; case H245_CLIENT_VID_H262: H245TRACE(0,20,"API:load_cap - H245_CLIENT_VID_H262"); pCapability->u.receiveVideoCapability.u.h262VideoCapability = pTotCap->Cap.H245Vid_H262; pCapability->u.receiveVideoCapability.choice = h262VideoCapability_chosen; break; case H245_CLIENT_VID_H263: H245TRACE(0,20,"API:load_cap - H245_CLIENT_VID_H263"); pCapability->u.receiveVideoCapability.u.h263VideoCapability = pTotCap->Cap.H245Vid_H263; pCapability->u.receiveVideoCapability.choice = h263VideoCapability_chosen; break; case H245_CLIENT_VID_IS11172: H245TRACE(0,20,"API:load_cap - H245_CLIENT_VID_IS11172"); pCapability->u.receiveVideoCapability.u.is11172VideoCapability = pTotCap->Cap.H245Vid_IS11172; pCapability->u.receiveVideoCapability.choice = is11172VideoCapability_chosen; break; /* AUDIO */ case H245_CLIENT_AUD_NONSTD: H245TRACE(0,20,"API:load_cap - H245_CLIENT_AUD_NONSTD"); lError = CopyNonStandardParameter(&pCapability->u.receiveAudioCapability.u.AdCpblty_nonStandard, &pTotCap->Cap.H245Aud_NONSTD); pCapability->u.receiveAudioCapability.choice = AdCpblty_nonStandard_chosen; break; case H245_CLIENT_AUD_G711_ALAW64: H245TRACE(0,20,"API:load_cap - H245_CLIENT_AUD_G711_ALAW64"); pCapability->u.receiveAudioCapability.u.AdCpblty_g711Alaw64k = pTotCap->Cap.H245Aud_G711_ALAW64; pCapability->u.receiveAudioCapability.choice = AdCpblty_g711Alaw64k_chosen; break; case H245_CLIENT_AUD_G711_ALAW56: H245TRACE(0,20,"API:load_cap - H245_CLIENT_AUD_G711_ALAW56"); pCapability->u.receiveAudioCapability.u.AdCpblty_g711Alaw56k = pTotCap->Cap.H245Aud_G711_ALAW56; pCapability->u.receiveAudioCapability.choice = AdCpblty_g711Alaw56k_chosen; break; case H245_CLIENT_AUD_G711_ULAW64: H245TRACE(0,20,"API:load_cap - H245_CLIENT_AUD_G711_ULAW64"); pCapability->u.receiveAudioCapability.u.AdCpblty_g711Ulaw64k = pTotCap->Cap.H245Aud_G711_ULAW64; pCapability->u.receiveAudioCapability.choice = AdCpblty_g711Ulaw64k_chosen; break; case H245_CLIENT_AUD_G711_ULAW56: H245TRACE(0,20,"API:load_cap - H245_CLIENT_AUD_G711_ULAW56"); pCapability->u.receiveAudioCapability.u.AdCpblty_g711Ulaw56k = pTotCap->Cap.H245Aud_G711_ULAW56; pCapability->u.receiveAudioCapability.choice = AdCpblty_g711Ulaw56k_chosen; break; case H245_CLIENT_AUD_G722_64: H245TRACE(0,20,"API:load_cap - H245_CLIENT_AUD_G722_64"); pCapability->u.receiveAudioCapability.u.AudioCapability_g722_64k = pTotCap->Cap.H245Aud_G722_64; pCapability->u.receiveAudioCapability.choice = AudioCapability_g722_64k_chosen; break; case H245_CLIENT_AUD_G722_56: H245TRACE(0,20,"API:load_cap - H245_CLIENT_AUD_G722_56"); pCapability->u.receiveAudioCapability.u.AudioCapability_g722_56k = pTotCap->Cap.H245Aud_G722_56; pCapability->u.receiveAudioCapability.choice = AudioCapability_g722_56k_chosen; break; case H245_CLIENT_AUD_G722_48: H245TRACE(0,20,"API:load_cap - H245_CLIENT_AUD_G722_48"); pCapability->u.receiveAudioCapability.u.AudioCapability_g722_48k = pTotCap->Cap.H245Aud_G722_48; pCapability->u.receiveAudioCapability.choice = AudioCapability_g722_48k_chosen; break; case H245_CLIENT_AUD_G723: H245TRACE(0,20,"API:load_cap - H245_CLIENT_AUD_G723"); pCapability->u.receiveAudioCapability.u.AudioCapability_g7231 = pTotCap->Cap.H245Aud_G723; pCapability->u.receiveAudioCapability.choice = AudioCapability_g7231_chosen; break; case H245_CLIENT_AUD_G728: H245TRACE(0,20,"API:load_cap - H245_CLIENT_AUD_G728"); pCapability->u.receiveAudioCapability.u.AudioCapability_g728 = pTotCap->Cap.H245Aud_G728; pCapability->u.receiveAudioCapability.choice = AudioCapability_g728_chosen; break; case H245_CLIENT_AUD_G729: H245TRACE(0,20,"API:load_cap - H245_CLIENT_AUD_G729"); pCapability->u.receiveAudioCapability.u.AudioCapability_g729 = pTotCap->Cap.H245Aud_G729; pCapability->u.receiveAudioCapability.choice = AudioCapability_g729_chosen; break; case H245_CLIENT_AUD_GDSVD: H245TRACE(0,20,"API:load_cap - H245_CLIENT_AUD_GDSVD"); pCapability->u.receiveAudioCapability.u.AdCpblty_g729AnnexA = pTotCap->Cap.H245Aud_GDSVD; pCapability->u.receiveAudioCapability.choice = AdCpblty_g729AnnexA_chosen; break; case H245_CLIENT_AUD_IS11172: H245TRACE(0,20,"API:load_cap - H245_CLIENT_AUD_IS11172"); pCapability->u.receiveAudioCapability.u.is11172AudioCapability = pTotCap->Cap.H245Aud_IS11172; pCapability->u.receiveAudioCapability.choice = is11172AudioCapability_chosen; break; case H245_CLIENT_AUD_IS13818: H245TRACE(0,20,"API:load_cap - H245_CLIENT_AUD_IS13818"); pCapability->u.receiveAudioCapability.u.is13818AudioCapability = pTotCap->Cap.H245Aud_IS13818; pCapability->u.receiveAudioCapability.choice = is13818AudioCapability_chosen; break; /* DATA */ case H245_CLIENT_DAT_NONSTD: H245TRACE(0,20,"API:load_cap - H245_CLIENT_DAT_NONSTD"); pCapability->u.rcvDtApplctnCpblty = pTotCap->Cap.H245Dat_NONSTD; lError = CopyNonStandardParameter(&pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_nnStndrd, &pTotCap->Cap.H245Dat_NONSTD.application.u.DACy_applctn_nnStndrd); pCapability->u.rcvDtApplctnCpblty.application.choice = DACy_applctn_nnStndrd_chosen; break; case H245_CLIENT_DAT_T120: H245TRACE(0,20,"API:load_cap - H245_CLIENT_DAT_T120"); pCapability->u.rcvDtApplctnCpblty = pTotCap->Cap.H245Dat_T120; if (pTotCap->Cap.H245Dat_T120.application.u.DACy_applctn_t120.choice == DtPrtclCpblty_nnStndrd_chosen) { lError = CopyNonStandardParameter(&pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_t120.u.DtPrtclCpblty_nnStndrd, &pTotCap->Cap.H245Dat_T120.application.u.DACy_applctn_t120.u.DtPrtclCpblty_nnStndrd); } pCapability->u.rcvDtApplctnCpblty.application.choice = DACy_applctn_t120_chosen; break; case H245_CLIENT_DAT_DSMCC: H245TRACE(0,20,"API:load_cap - H245_CLIENT_DAT_DSMCC"); pCapability->u.rcvDtApplctnCpblty = pTotCap->Cap.H245Dat_DSMCC; if (pTotCap->Cap.H245Dat_DSMCC.application.u.DACy_applctn_dsm_cc.choice == DtPrtclCpblty_nnStndrd_chosen) { lError = CopyNonStandardParameter(&pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_dsm_cc.u.DtPrtclCpblty_nnStndrd, &pTotCap->Cap.H245Dat_DSMCC.application.u.DACy_applctn_dsm_cc.u.DtPrtclCpblty_nnStndrd); } pCapability->u.rcvDtApplctnCpblty.application.choice = DACy_applctn_dsm_cc_chosen; break; case H245_CLIENT_DAT_USERDATA: H245TRACE(0,20,"API:load_cap - H245_CLIENT_DAT_USERDATA"); pCapability->u.rcvDtApplctnCpblty = pTotCap->Cap.H245Dat_USERDATA; if (pTotCap->Cap.H245Dat_USERDATA.application.u.DACy_applctn_usrDt.choice == DtPrtclCpblty_nnStndrd_chosen) { lError = CopyNonStandardParameter(&pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_usrDt.u.DtPrtclCpblty_nnStndrd, &pTotCap->Cap.H245Dat_USERDATA.application.u.DACy_applctn_usrDt.u.DtPrtclCpblty_nnStndrd); } pCapability->u.rcvDtApplctnCpblty.application.choice = DACy_applctn_usrDt_chosen; break; case H245_CLIENT_DAT_T84: H245TRACE(0,20,"API:load_cap - H245_CLIENT_DAT_T84"); pCapability->u.rcvDtApplctnCpblty = pTotCap->Cap.H245Dat_T84; if (pTotCap->Cap.H245Dat_T84.application.u.DACy_applctn_t84.t84Protocol.choice == DtPrtclCpblty_nnStndrd_chosen) { lError = CopyNonStandardParameter(&pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_t84.t84Protocol.u.DtPrtclCpblty_nnStndrd, &pTotCap->Cap.H245Dat_T84.application.u.DACy_applctn_t84.t84Protocol.u.DtPrtclCpblty_nnStndrd); } pCapability->u.rcvDtApplctnCpblty.application.choice = DACy_applctn_t84_chosen; break; case H245_CLIENT_DAT_T434: H245TRACE(0,20,"API:load_cap - H245_CLIENT_DAT_T434"); pCapability->u.rcvDtApplctnCpblty = pTotCap->Cap.H245Dat_T434; if (pTotCap->Cap.H245Dat_T434.application.u.DACy_applctn_t434.choice == DtPrtclCpblty_nnStndrd_chosen) { lError = CopyNonStandardParameter(&pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_t434.u.DtPrtclCpblty_nnStndrd, &pTotCap->Cap.H245Dat_T434.application.u.DACy_applctn_t434.u.DtPrtclCpblty_nnStndrd); } pCapability->u.rcvDtApplctnCpblty.application.choice = DACy_applctn_t434_chosen; break; case H245_CLIENT_DAT_H224: H245TRACE(0,20,"API:load_cap - H245_CLIENT_DAT_H224"); pCapability->u.rcvDtApplctnCpblty = pTotCap->Cap.H245Dat_H224; if (pTotCap->Cap.H245Dat_H224.application.u.DACy_applctn_h224.choice == DtPrtclCpblty_nnStndrd_chosen) { lError = CopyNonStandardParameter(&pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_h224.u.DtPrtclCpblty_nnStndrd, &pTotCap->Cap.H245Dat_H224.application.u.DACy_applctn_h224.u.DtPrtclCpblty_nnStndrd); } pCapability->u.rcvDtApplctnCpblty.application.choice = DACy_applctn_h224_chosen; break; case H245_CLIENT_DAT_NLPID: H245TRACE(0,20,"API:load_cap - H245_CLIENT_DAT_NLPID"); pCapability->u.rcvDtApplctnCpblty = pTotCap->Cap.H245Dat_NLPID; if (pTotCap->Cap.H245Dat_NLPID.application.u.DACy_applctn_nlpd.nlpidProtocol.choice == DtPrtclCpblty_nnStndrd_chosen) { lError = CopyNonStandardParameter(&pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_nlpd.nlpidProtocol.u.DtPrtclCpblty_nnStndrd, &pTotCap->Cap.H245Dat_NLPID.application.u.DACy_applctn_nlpd.nlpidProtocol.u.DtPrtclCpblty_nnStndrd); } if (lError == H245_ERROR_OK && pTotCap->Cap.H245Dat_NLPID.application.u.DACy_applctn_nlpd.nlpidData.length != 0) { pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_nlpd.nlpidData.value = MemAlloc(pTotCap->Cap.H245Dat_NLPID.application.u.DACy_applctn_nlpd.nlpidData.length); if (pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_nlpd.nlpidData.value) { memcpy(pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_nlpd.nlpidData.value, pTotCap->Cap.H245Dat_NLPID.application.u.DACy_applctn_nlpd.nlpidData.value, pTotCap->Cap.H245Dat_NLPID.application.u.DACy_applctn_nlpd.nlpidData.length); } else lError = H245_ERROR_NOMEM; } else pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_nlpd.nlpidData.value = NULL; pCapability->u.rcvDtApplctnCpblty.application.choice = DACy_applctn_nlpd_chosen; break; case H245_CLIENT_DAT_DSVD: H245TRACE(0,20,"API:load_cap - H245_CLIENT_DAT_DSVD"); pCapability->u.rcvDtApplctnCpblty = pTotCap->Cap.H245Dat_DSMCC; pCapability->u.rcvDtApplctnCpblty.application.choice = DACy_applctn_dsvdCntrl_chosen; break; case H245_CLIENT_DAT_H222: H245TRACE(0,20,"API:load_cap - H245_CLIENT_DAT_H222"); pCapability->u.rcvDtApplctnCpblty = pTotCap->Cap.H245Dat_H222; if (pTotCap->Cap.H245Dat_H222.application.u.DACy_an_h222DtPrttnng.choice == DtPrtclCpblty_nnStndrd_chosen) { lError = CopyNonStandardParameter(&pCapability->u.rcvDtApplctnCpblty.application.u.DACy_an_h222DtPrttnng.u.DtPrtclCpblty_nnStndrd, &pTotCap->Cap.H245Dat_H222.application.u.DACy_an_h222DtPrttnng.u.DtPrtclCpblty_nnStndrd); } pCapability->u.rcvDtApplctnCpblty.application.choice = DACy_an_h222DtPrttnng_chosen ; break; default: H245TRACE(0,20,"API:load_cap - default"); lError = H245_ERROR_NOSUP; } /* switch */ if (lError != H245_ERROR_OK) H245TRACE(0,1,"API:load_cap -> %s",map_api_error(lError)); else H245TRACE(0,10,"API:load_cap -> OK"); return lError; } void free_cap (struct Capability * pCapability, // input, output const H245_TOTCAP_T *pTotCap) // input { ASSERT(!IsBadWritePtr(pCapability, sizeof(*pCapability))); switch (pTotCap->ClientType) { case H245_CLIENT_NONSTD: FreeNonStandardParameter(&pCapability->u.Capability_nonStandard); break; case H245_CLIENT_VID_NONSTD: FreeNonStandardParameter(&pCapability->u.receiveVideoCapability.u.VdCpblty_nonStandard); break; case H245_CLIENT_AUD_NONSTD: FreeNonStandardParameter(&pCapability->u.receiveAudioCapability.u.AdCpblty_nonStandard); break; case H245_CLIENT_DAT_NONSTD: FreeNonStandardParameter(&pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_nnStndrd); break; case H245_CLIENT_DAT_T120: if (pTotCap->Cap.H245Dat_T120.application.u.DACy_applctn_t120.choice == DtPrtclCpblty_nnStndrd_chosen) { FreeNonStandardParameter(&pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_t120.u.DtPrtclCpblty_nnStndrd); } else { if (pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_t120.u.DtPrtclCpblty_nnStndrd.data.value) { WARNING_OUT(("H245_CLIENT_DAT_T120 no non-standard parameter to free")); } } break; case H245_CLIENT_DAT_DSMCC: if (pTotCap->Cap.H245Dat_DSMCC.application.u.DACy_applctn_dsm_cc.choice == DtPrtclCpblty_nnStndrd_chosen) { FreeNonStandardParameter(&pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_dsm_cc.u.DtPrtclCpblty_nnStndrd); } break; case H245_CLIENT_DAT_USERDATA: if (pTotCap->Cap.H245Dat_USERDATA.application.u.DACy_applctn_usrDt.choice == DtPrtclCpblty_nnStndrd_chosen) { FreeNonStandardParameter(&pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_usrDt.u.DtPrtclCpblty_nnStndrd); } break; case H245_CLIENT_DAT_T84: if (pTotCap->Cap.H245Dat_T84.application.u.DACy_applctn_t84.t84Protocol.choice == DtPrtclCpblty_nnStndrd_chosen) { FreeNonStandardParameter(&pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_t84.t84Protocol.u.DtPrtclCpblty_nnStndrd); } break; case H245_CLIENT_DAT_T434: if (pTotCap->Cap.H245Dat_T434.application.u.DACy_applctn_t434.choice == DtPrtclCpblty_nnStndrd_chosen) { FreeNonStandardParameter(&pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_t434.u.DtPrtclCpblty_nnStndrd); } break; case H245_CLIENT_DAT_H224: if (pTotCap->Cap.H245Dat_H224.application.u.DACy_applctn_h224.choice == DtPrtclCpblty_nnStndrd_chosen) { FreeNonStandardParameter(&pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_h224.u.DtPrtclCpblty_nnStndrd); } break; case H245_CLIENT_DAT_NLPID: if (pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_nlpd.nlpidData.value) { MemFree(pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_nlpd.nlpidData.value); } if (pTotCap->Cap.H245Dat_NLPID.application.u.DACy_applctn_nlpd.nlpidProtocol.choice == DtPrtclCpblty_nnStndrd_chosen) { FreeNonStandardParameter(&pCapability->u.rcvDtApplctnCpblty.application.u.DACy_applctn_nlpd.nlpidProtocol.u.DtPrtclCpblty_nnStndrd); } break; case H245_CLIENT_DAT_H222: if (pTotCap->Cap.H245Dat_H222.application.u.DACy_an_h222DtPrttnng.choice == DtPrtclCpblty_nnStndrd_chosen) { FreeNonStandardParameter(&pCapability->u.rcvDtApplctnCpblty.application.u.DACy_an_h222DtPrttnng.u.DtPrtclCpblty_nnStndrd); } break; } } /***************************************************************************** * * TYPE: Global * * PROCEDURE: build_totcap_from_mux * * DESCRIPTION: * called by both top down , and bottom up.. * * RETURN: * * ASSUMES: * *****************************************************************************/ HRESULT build_totcap_from_mux(H245_TOTCAP_T *pTotCap, MultiplexCapability *pMuxCap, H245_CAPDIR_T Dir) { H245TRACE(0,10,"API:build_totcap_from_mux <-"); /* initialize TotCap */ pTotCap->Dir = Dir; pTotCap->DataType = H245_DATA_MUX; pTotCap->ClientType = H245_CLIENT_DONTCARE; pTotCap->CapId = 0; switch (pMuxCap->choice) { case MltplxCpblty_nonStandard_chosen: H245TRACE(0,20,"API:build_totcap_from_mux - MltplxCpblty_nonStandard_chosen"); pTotCap->Cap.H245Mux_NONSTD = pMuxCap->u.MltplxCpblty_nonStandard; pTotCap->ClientType = H245_CLIENT_MUX_NONSTD; // TBD - copy nonstandard parameter H245PANIC(); break; case h222Capability_chosen: H245TRACE(0,20,"API:build_totcap_from_mux - h222Capability_chosen"); pTotCap->Cap.H245Mux_H222 = pMuxCap->u.h222Capability; pTotCap->ClientType = H245_CLIENT_MUX_H222; break; case h223Capability_chosen: H245TRACE(0,20,"API:build_totcap_from_mux - h223Capability_chosen"); pTotCap->Cap.H245Mux_H223 = pMuxCap->u.h223Capability; pTotCap->ClientType = H245_CLIENT_MUX_H223; break; case v76Capability_chosen: H245TRACE(0,20,"API:build_totcap_from_mux - v76Capability_chosen"); pTotCap->Cap.H245Mux_VGMUX = pMuxCap->u.v76Capability; pTotCap->ClientType = H245_CLIENT_MUX_VGMUX; break; case h2250Capability_chosen: H245TRACE(0,20,"API:build_totcap_from_mux - h2250Capability_chosen"); pTotCap->Cap.H245Mux_H2250 = pMuxCap->u.h2250Capability; pTotCap->ClientType = H245_CLIENT_MUX_H2250; break; default: H245TRACE(0,20,"API:build_totcap_from_mux - unrecogized choice %d", pMuxCap->choice); return H245_ERROR_NOSUP; } H245TRACE(0,10,"API:build_totcap_from_mux -> OK"); return H245_ERROR_OK; } /***************************************************************************** * * TYPE: Global * * PROCEDURE: build_totcap_from_captbl * * DESCRIPTION: * called by both top down , and bottom up.. * * RETURN: * * ASSUMES: * *****************************************************************************/ HRESULT build_totcap_from_captbl (H245_TOTCAP_T *pTotCap, CapabilityTableLink pCapLink, int lcl_rmt) { unsigned short choice; DWORD error; H245TRACE(0,10,"API:build_totcap_from_captbl <-"); /* initialize TotCap */ pTotCap->Dir = H245_CAPDIR_DONTCARE; pTotCap->DataType = H245_DATA_DONTCARE; pTotCap->ClientType = H245_CLIENT_DONTCARE; pTotCap->CapId = 0; /* note.. this has to come first if using for deleted caps */ /* capability entry number will be present, however if */ /* the capability is not present that indicates that the */ /* capability should be deleted */ pTotCap->CapId = pCapLink->value.capabilityTableEntryNumber; if (!(pCapLink->value.bit_mask & capability_present)) return H245_ERROR_OK; switch (pCapLink->value.capability.choice) { case Capability_nonStandard_chosen: H245TRACE(0,20,"API:build_totcap_from_captbl - Capability_nonStandard_chosen"); pTotCap->DataType = H245_DATA_NONSTD; pTotCap->Dir = lcl_rmt==H245_LOCAL?H245_CAPDIR_LCLRX:H245_CAPDIR_RMTRX; choice = Capability_nonStandard_chosen; break; case receiveVideoCapability_chosen: H245TRACE(0,20,"API:build_totcap_from_captbl - receiveVideoCapability_chosen"); pTotCap->DataType = H245_DATA_VIDEO; pTotCap->Dir = lcl_rmt==H245_LOCAL?H245_CAPDIR_LCLRX:H245_CAPDIR_RMTRX; choice = pCapLink->value.capability.u.receiveVideoCapability.choice; break; case transmitVideoCapability_chosen: H245TRACE(0,20,"API:build_totcap_from_captbl - transmitVideoCapability_chosen"); pTotCap->DataType = H245_DATA_VIDEO; pTotCap->Dir = lcl_rmt==H245_LOCAL?H245_CAPDIR_LCLTX:H245_CAPDIR_RMTTX; choice = pCapLink->value.capability.u.transmitVideoCapability.choice; break; case rcvAndTrnsmtVdCpblty_chosen: H245TRACE(0,20,"API:build_totcap_from_captbl - rcvAndTrnsmtVdCpblty_chosen"); pTotCap->DataType = H245_DATA_VIDEO; pTotCap->Dir = lcl_rmt==H245_LOCAL?H245_CAPDIR_LCLRXTX:H245_CAPDIR_RMTRXTX; choice = pCapLink->value.capability.u.rcvAndTrnsmtVdCpblty.choice; break; case receiveAudioCapability_chosen: H245TRACE(0,20,"API:build_totcap_from_captbl - receiveAudioCapability_chosen"); pTotCap->DataType = H245_DATA_AUDIO; pTotCap->Dir = lcl_rmt==H245_LOCAL?H245_CAPDIR_LCLRX:H245_CAPDIR_RMTRX; choice = pCapLink->value.capability.u.receiveAudioCapability.choice; break; case transmitAudioCapability_chosen: H245TRACE(0,20,"API:build_totcap_from_captbl - transmitAudioCapability_chosen"); pTotCap->DataType = H245_DATA_AUDIO; pTotCap->Dir = lcl_rmt==H245_LOCAL?H245_CAPDIR_LCLTX:H245_CAPDIR_RMTTX; choice = pCapLink->value.capability.u.transmitAudioCapability.choice; break; case rcvAndTrnsmtAdCpblty_chosen: H245TRACE(0,20,"API:build_totcap_from_captbl - rcvAndTrnsmtAdCpblty_chosen"); pTotCap->DataType = H245_DATA_AUDIO; pTotCap->Dir = lcl_rmt==H245_LOCAL?H245_CAPDIR_LCLRXTX:H245_CAPDIR_RMTRXTX; choice = pCapLink->value.capability.u.rcvAndTrnsmtAdCpblty.choice; break; case rcvDtApplctnCpblty_chosen: H245TRACE(0,20,"API:build_totcap_from_captbl - rcvDtApplctnCpblty_chosen"); pTotCap->DataType = H245_DATA_DATA; pTotCap->Dir = lcl_rmt==H245_LOCAL?H245_CAPDIR_LCLRX:H245_CAPDIR_RMTRX; choice = pCapLink->value.capability.u.rcvDtApplctnCpblty.application.choice; break; case trnsmtDtApplctnCpblty_chosen: H245TRACE(0,20,"API:build_totcap_from_captbl - trnsmtDtApplctnCpblty_chosen"); pTotCap->DataType = H245_DATA_DATA; pTotCap->Dir = lcl_rmt==H245_LOCAL?H245_CAPDIR_LCLTX:H245_CAPDIR_RMTTX; choice = pCapLink->value.capability.u.trnsmtDtApplctnCpblty.application.choice; break; case rATDACy_chosen: H245TRACE(0,20,"API:build_totcap_from_captbl - rATDACy_chosen"); pTotCap->DataType = H245_DATA_DATA; pTotCap->Dir = lcl_rmt==H245_LOCAL?H245_CAPDIR_LCLRX:H245_CAPDIR_RMTRX; choice = pCapLink->value.capability.u.rATDACy.application.choice; break; case h233EncryptnTrnsmtCpblty_chosen: H245TRACE(0,20,"API:build_totcap_from_captbl - h233EncryptnTrnsmtCpblty_chosen"); pTotCap->DataType = H245_DATA_ENCRYPT_D; pTotCap->Dir = lcl_rmt==H245_LOCAL?H245_CAPDIR_LCLRXTX:H245_CAPDIR_RMTRXTX; /* (TBC) */ return H245_ERROR_NOSUP; break; case h233EncryptnRcvCpblty_chosen: H245TRACE(0,20,"API:build_totcap_from_captbl - h233EncryptnRcvCpblty_chosen"); pTotCap->DataType = H245_DATA_ENCRYPT_D; pTotCap->Dir = lcl_rmt==H245_LOCAL?H245_CAPDIR_LCLRXTX:H245_CAPDIR_RMTRXTX; /* (TBC) */ return H245_ERROR_NOSUP; break; default: H245TRACE(0,20,"API:build_totcap_from_captbl - default"); /* TBC .. */ return H245_ERROR_NOSUP; break; } /* load the tot cap's capability and client from capability */ if ((error = build_totcap_cap_n_client_from_capability (&pCapLink->value.capability, pTotCap->DataType, choice, pTotCap)) != H245_ERROR_OK) { H245TRACE(0,1,"API:build_totcap_from_captbl -> %s",map_api_error(error)); return error; } H245TRACE(0,10,"API:build_totcap_from_captbl -> OK"); return H245_ERROR_OK; } /***************************************************************************** * * TYPE: Global * * PROCEDURE: build_totcap_n_client_from_capbility * * DESCRIPTION: * Take a capability structure (pCapability), * data type (audio/video/data) choice... * Which is found in the pdu . and the totcap; * NOTE: does not handle H245_DATA_MUX_T * * RETURN: * * ASSUMES: * ONLY HANDLES Terminal Caps.. Does not handle MUX Caps. * * totcap.DataType is defined * totcap.CapId is defined * totcap.Cap is non NULL * *****************************************************************************/ HRESULT build_totcap_cap_n_client_from_capability (struct Capability *pCapability, H245_DATA_T data_type, unsigned short choice, H245_TOTCAP_T *pTotCap) { H245TRACE(0,10,"API:build_totcap_cap_n_client_from_capability <-"); switch (data_type) { case H245_DATA_NONSTD: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - H245_DATA_NONSTD"); pTotCap->ClientType = H245_CLIENT_NONSTD; pTotCap->Cap.H245_NonStd = pCapability->u.Capability_nonStandard; break; case H245_DATA_AUDIO: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - H245_DATA_AUDIO"); switch (choice) { case AdCpblty_nonStandard_chosen: H245TRACE(0,20, "API:build_totcap_cap_n_client_from_capability - choice - AdCpblty_nonStandard_chosen"); pTotCap->ClientType = H245_CLIENT_AUD_NONSTD; pTotCap->Cap.H245Aud_NONSTD = pCapability->u.receiveAudioCapability.u.AdCpblty_nonStandard; break; case AdCpblty_g711Alaw64k_chosen: H245TRACE(0,20, "API:build_totcap_cap_n_client_from_capability - choice - AdCpblty_g711Alaw64k_chosen"); pTotCap->ClientType = H245_CLIENT_AUD_G711_ALAW64; pTotCap->Cap.H245Aud_G711_ALAW64 = pCapability->u.receiveAudioCapability.u.AdCpblty_g711Alaw64k; break; case AdCpblty_g711Alaw56k_chosen: H245TRACE(0,20, "API:build_totcap_cap_n_client_from_capability - choice - AdCpblty_g711Alaw56k_chosen"); pTotCap->ClientType = H245_CLIENT_AUD_G711_ALAW56; pTotCap->Cap.H245Aud_G711_ALAW56 = pCapability->u.receiveAudioCapability.u.AdCpblty_g711Alaw56k; break; case AdCpblty_g711Ulaw64k_chosen: H245TRACE(0,20, "API:build_totcap_cap_n_client_from_capability - choice - AdCpblty_g711Ulaw64k_chosen"); pTotCap->ClientType = H245_CLIENT_AUD_G711_ULAW64; pTotCap->Cap.H245Aud_G711_ULAW64 = pCapability->u.receiveAudioCapability.u.AdCpblty_g711Ulaw64k; break; case AdCpblty_g711Ulaw56k_chosen: H245TRACE(0,20, "API:build_totcap_cap_n_client_from_capability - choice - AdCpblty_g711Ulaw56k_chosen"); pTotCap->ClientType = H245_CLIENT_AUD_G711_ULAW56; pTotCap->Cap.H245Aud_G711_ULAW56 = pCapability->u.receiveAudioCapability.u.AdCpblty_g711Ulaw56k; break; case AudioCapability_g722_64k_chosen: H245TRACE(0,20, "API:build_totcap_cap_n_client_from_capability - choice - AudioCapability_g722_64k_chosen"); pTotCap->ClientType = H245_CLIENT_AUD_G722_64; pTotCap->Cap.H245Aud_G722_64 = pCapability->u.receiveAudioCapability.u.AudioCapability_g722_64k; break; case AudioCapability_g722_56k_chosen: H245TRACE(0,20, "API:build_totcap_cap_n_client_from_capability - choice - AudioCapability_g722_56k_chosen"); pTotCap->ClientType = H245_CLIENT_AUD_G722_56; pTotCap->Cap.H245Aud_G722_56 = pCapability->u.receiveAudioCapability.u.AudioCapability_g722_56k; break; case AudioCapability_g722_48k_chosen: H245TRACE(0,20, "API:build_totcap_cap_n_client_from_capability - choice - AudioCapability_g722_48k_chosen"); pTotCap->ClientType = H245_CLIENT_AUD_G722_48; pTotCap->Cap.H245Aud_G722_48 = pCapability->u.receiveAudioCapability.u.AudioCapability_g722_48k; break; case AudioCapability_g7231_chosen: H245TRACE(0,20, "API:build_totcap_cap_n_client_from_capability - choice - AudioCapability_g7231_chosen"); pTotCap->ClientType = H245_CLIENT_AUD_G723; pTotCap->Cap.H245Aud_G723 = pCapability->u.receiveAudioCapability.u.AudioCapability_g7231; break; case AudioCapability_g728_chosen: H245TRACE(0,20, "API:build_totcap_cap_n_client_from_capability - choice - AudioCapability_g728_chosen"); pTotCap->ClientType = H245_CLIENT_AUD_G728; pTotCap->Cap.H245Aud_G728 = pCapability->u.receiveAudioCapability.u.AudioCapability_g728; break; case AudioCapability_g729_chosen: H245TRACE(0,20, "API:build_totcap_cap_n_client_from_capability - choice - AudioCapability_g729_chosen"); pTotCap->ClientType = H245_CLIENT_AUD_G729; pTotCap->Cap.H245Aud_G729 = pCapability->u.receiveAudioCapability.u.AudioCapability_g729; break; case AdCpblty_g729AnnexA_chosen: H245TRACE(0,20, "API:build_totcap_cap_n_client_from_capability - choice - AdCpblty_g729AnnexA_chosen"); pTotCap->ClientType = H245_CLIENT_AUD_GDSVD; pTotCap->Cap.H245Aud_GDSVD = pCapability->u.receiveAudioCapability.u.AdCpblty_g729AnnexA; break; case is11172AudioCapability_chosen: H245TRACE(0,20, "API:build_totcap_cap_n_client_from_capability - choice - is11172AudioCapability_chosen"); pTotCap->ClientType = H245_CLIENT_AUD_IS11172; pTotCap->Cap.H245Aud_IS11172 = pCapability->u.receiveAudioCapability.u.is11172AudioCapability; break; case is13818AudioCapability_chosen: H245TRACE(0,20, "API:build_totcap_cap_n_client_from_capability - choice - is13818AudioCapability_chosen"); pTotCap->ClientType = H245_CLIENT_AUD_IS13818; pTotCap->Cap.H245Aud_IS13818 = pCapability->u.receiveAudioCapability.u.is13818AudioCapability; break; default: pTotCap->ClientType = 0; H245TRACE(0,20, "API:build_totcap_cap_n_client_from_capability - choice - default"); return H245_ERROR_NOSUP; break; } break; case H245_DATA_VIDEO: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - H245_DATA_VIDEO"); switch (choice) { case VdCpblty_nonStandard_chosen: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - choice - VdCpblty_nonStandard_chosen"); pTotCap->ClientType = H245_CLIENT_VID_NONSTD; pTotCap->Cap.H245Vid_NONSTD = pCapability->u.receiveVideoCapability.u.VdCpblty_nonStandard; break; case h261VideoCapability_chosen: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - choice - h261VideoCapability_chosen"); pTotCap->ClientType = H245_CLIENT_VID_H261; pTotCap->Cap.H245Vid_H261 = pCapability->u.receiveVideoCapability.u.h261VideoCapability; break; case h262VideoCapability_chosen: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - choice - h262VideoCapability_chosen"); pTotCap->ClientType = H245_CLIENT_VID_H262; pTotCap->Cap.H245Vid_H262 = pCapability->u.receiveVideoCapability.u.h262VideoCapability; break; case h263VideoCapability_chosen: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - choice - h263VideoCapability_chosen"); pTotCap->ClientType = H245_CLIENT_VID_H263; pTotCap->Cap.H245Vid_H263 = pCapability->u.receiveVideoCapability.u.h263VideoCapability; break; case is11172VideoCapability_chosen: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - choice - is11172VideoCapability_chosen"); pTotCap->ClientType = H245_CLIENT_VID_IS11172; pTotCap->Cap.H245Vid_IS11172 = pCapability->u.receiveVideoCapability.u.is11172VideoCapability; break; default: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - choice - default"); pTotCap->ClientType = 0; return H245_ERROR_NOSUP; break; } break; case H245_DATA_DATA: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - H245_DATA_DATA"); pTotCap->Cap.H245Dat_NONSTD = pCapability->u.rcvDtApplctnCpblty; switch (choice) { case DACy_applctn_nnStndrd_chosen: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - choice - DACy_applctn_nnStndrd_chosen"); pTotCap->ClientType = H245_CLIENT_DAT_NONSTD; break; case DACy_applctn_t120_chosen: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - choice - DACy_applctn_t120_chosen"); pTotCap->ClientType = H245_CLIENT_DAT_T120; break; case DACy_applctn_dsm_cc_chosen: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - choice - DACy_applctn_dsm_cc_chosen"); pTotCap->ClientType = H245_CLIENT_DAT_DSMCC; break; case DACy_applctn_usrDt_chosen: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - choice - DACy_applctn_usrDt_chosen"); pTotCap->ClientType = H245_CLIENT_DAT_USERDATA; break; case DACy_applctn_t84_chosen: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - choice - DACy_applctn_t84_chosen"); pTotCap->ClientType = H245_CLIENT_DAT_T84; break; case DACy_applctn_t434_chosen: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - choice - DACy_applctn_t434_chosen"); pTotCap->ClientType = H245_CLIENT_DAT_T434; break; case DACy_applctn_h224_chosen: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - choice - DACy_applctn_h224_chosen"); pTotCap->ClientType = H245_CLIENT_DAT_H224; break; case DACy_applctn_nlpd_chosen: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - choice - DACy_applctn_nlpd_chosen"); pTotCap->ClientType = H245_CLIENT_DAT_NLPID; break; case DACy_applctn_dsvdCntrl_chosen: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - choice - DACy_applctn_dsvdCntrl_chosen"); pTotCap->ClientType = H245_CLIENT_DAT_DSVD; break; case DACy_an_h222DtPrttnng_chosen: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - choice - DACy_an_h222DtPrttnng_chosen"); pTotCap->ClientType = H245_CLIENT_DAT_H222; break; default: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - choice - default"); pTotCap->ClientType = 0; return H245_ERROR_NOSUP; break; } break; case H245_DATA_ENCRYPT_D: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - H245_DATA_ENCRYPT_D"); pTotCap->ClientType = 0; H245PANIC(); return H245_ERROR_NOSUP; break; case H245_DATA_MUX: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - H245_DATA_MUX"); pTotCap->ClientType = 0; H245PANIC(); return H245_ERROR_NOSUP; break; default: H245TRACE(0,20,"API:build_totcap_cap_n_client_from_capability - default"); pTotCap->ClientType = 0; H245PANIC(); return H245_ERROR_NOSUP; } H245TRACE(0,10,"API:build_totcap_cap_n_client_from_capability -> OK"); return H245_ERROR_OK; } /***************************************************************************** * * TYPE: * * PROCEDURE: del_link * * DESCRIPTION: * * RETURN: * * ASSUME: List is Locked * *****************************************************************************/ HRESULT del_link ( H245_LINK_T **pp_link_start, H245_LINK_T *p_link ) { struct H245_LINK_T *p_link_look = NULL; struct H245_LINK_T *p_link_lst = NULL; H245TRACE(0,10,"API:del_link <-"); /* get current count on table */ for (p_link_look = *pp_link_start; p_link_look && (p_link_look != p_link); p_link_lst = p_link_look, p_link_look = p_link_look->p_next ); /* cap was not in list */ if (!p_link_look) { H245TRACE(0,1,"API:del_link -> link not found!"); return H245_ERROR_PARAM; } /* modify entry in table */ if (!p_link_lst) *pp_link_start = p_link_look->p_next; else p_link_lst->p_next = p_link_look->p_next; MemFree (p_link_look); H245TRACE(0,10,"API:del_link -> OK"); return H245_ERROR_OK; } /***************************************************************************** * * TYPE: * * PROCEDURE: del_cap_link * * DESCRIPTION: * * ASSUMES: Capability Table is locked before call * * RETURN: None * * ASSUME: List is Locked * * *****************************************************************************/ HRESULT del_cap_link ( struct TerminalCapabilitySet *pTermCapSet, /* capabilty set */ CapabilityTableLink pCapLink ) { CapabilityTableLink pCapLink_look = NULL; CapabilityTableLink pCapLink_lst = NULL; CapabilityTableEntry *pCap_entry = NULL; unsigned char *p_char_to_free = NULL; POBJECTID p_objid_to_free = NULL; H245TRACE(0,10,"API:del_cap_link <-"); ASSERT (pTermCapSet); ASSERT (pCapLink); /************************************************/ /* BEGIN : Non Standard Capability Special Case */ /************************************************/ switch (pCapLink->value.capability.choice) { case Capability_nonStandard_chosen: /* free nonstandard data value */ p_char_to_free = pCapLink->value.capability.u.Capability_nonStandard.data.value; /* free the object id */ if (pCapLink->value.capability.u.Capability_nonStandard.nonStandardIdentifier.choice == object_chosen) p_objid_to_free = pCapLink->value.capability.u.Capability_nonStandard.nonStandardIdentifier.u.object; break; case receiveVideoCapability_chosen: case transmitVideoCapability_chosen: case rcvAndTrnsmtVdCpblty_chosen: /* free nonstandard data value */ if (pCapLink->value.capability.u.receiveVideoCapability.choice == VdCpblty_nonStandard_chosen) { /* nonstd value */ p_char_to_free = pCapLink->value.capability.u.receiveVideoCapability.u.VdCpblty_nonStandard.data.value; /* free the object id */ if (pCapLink->value.capability.u.receiveVideoCapability.u.VdCpblty_nonStandard.nonStandardIdentifier.choice == object_chosen) p_objid_to_free = pCapLink->value.capability.u.receiveVideoCapability.u.VdCpblty_nonStandard.nonStandardIdentifier.u.object; } break; case receiveAudioCapability_chosen: case transmitAudioCapability_chosen: case rcvAndTrnsmtAdCpblty_chosen: /* free nonstandard data value */ if (pCapLink->value.capability.u.receiveAudioCapability.choice == AdCpblty_nonStandard_chosen) { /* nonstd value */ p_char_to_free = pCapLink->value.capability.u.receiveAudioCapability.u.AdCpblty_nonStandard.data.value; /* free the object id */ if (pCapLink->value.capability.u.receiveAudioCapability.u.AdCpblty_nonStandard.nonStandardIdentifier.choice == object_chosen) p_objid_to_free = pCapLink->value.capability.u.receiveAudioCapability.u.AdCpblty_nonStandard.nonStandardIdentifier.u.object; } break; case rcvDtApplctnCpblty_chosen: case trnsmtDtApplctnCpblty_chosen: case rATDACy_chosen : if (pCapLink->value.capability.u.rcvDtApplctnCpblty.application.choice == DACy_applctn_nnStndrd_chosen) { /* free nonstandard data value */ p_char_to_free = pCapLink->value.capability.u.rcvDtApplctnCpblty.application.u.DACy_applctn_nnStndrd.data.value; /* free the object id */ if (pCapLink->value.capability.u.rcvDtApplctnCpblty.application.u.DACy_applctn_nnStndrd.nonStandardIdentifier.choice == object_chosen) p_objid_to_free = pCapLink->value.capability.u.rcvDtApplctnCpblty.application.u.DACy_applctn_nnStndrd.nonStandardIdentifier.u.object; } break; case h233EncryptnTrnsmtCpblty_chosen: case h233EncryptnRcvCpblty_chosen: default: break; } /* free the value if there is one */ if (p_char_to_free) { H245TRACE(0,0,"TMPMSG: Free NonStandard Value"); MemFree(p_char_to_free); } /* free the objectid */ if (p_objid_to_free) { H245TRACE(0,0,"TMPMSG: Free NonStandard ID"); free_object_id (p_objid_to_free); } /************************************************/ /* END : Non Standard Capability Special Case */ /************************************************/ H245TRACE(0,10,"API:del_cap_link -> OK"); return del_link(&((H245_LINK_T *) pTermCapSet->capabilityTable), (H245_LINK_T *) pCapLink); } /***************************************************************************** * * TYPE: * * PROCEDURE: dealloc_link_cap_list * * DESCRIPTION: deallocs the entire list of capabilities from a capabiltiy * set * * ASSUMES: Capability Table is locked before call * del_cap_link updates pTermCapSet->capabilityTable * correctly. * *****************************************************************************/ void dealloc_link_cap_list ( struct TerminalCapabilitySet *pTermCapSet) { while (pTermCapSet->capabilityTable) del_cap_link (pTermCapSet, pTermCapSet->capabilityTable); } /***************************************************************************** * * TYPE: * * PROCEDURE: clean_cap_table - clean out all unused cap entries * * DESCRIPTION: * * RETURN: * * ASSUMES: on entry.. table locked * *****************************************************************************/ void clean_cap_table( struct TerminalCapabilitySet *pTermCapSet ) { CapabilityTableLink pCapLink; CapabilityTableLink pCap_nxt; H245TRACE(0,10,"API:clean_cap_table <-"); /* traverse through the list.. delete all where capabilities are not set */ for (pCapLink = pTermCapSet->capabilityTable; pCapLink;) { pCap_nxt = pCapLink->next; if (!(pCapLink->value.bit_mask & capability_present)) { H245TRACE(0,20,"API:clean_cap_table - deleting CapId = %d", pCapLink->value.capabilityTableEntryNumber); del_cap_link ( pTermCapSet, pCapLink ); } pCapLink = pCap_nxt; } /* if no tercaps present unset flag */ if (!pTermCapSet->capabilityTable) pTermCapSet->bit_mask &= ~capabilityTable_present; H245TRACE(0,10,"API:clean_cap_table -> OK"); } /***************************************************************************** * * TYPE: Global * * PROCEDURE: alloc_link_tracker * * DESCRIPTION: * * RETURN: * * ASSUME: List is Locked * *****************************************************************************/ Tracker_T * alloc_link_tracker (struct InstanceStruct * pInstance, API_TRACKER_T TrackerType, DWORD_PTR dwTransId, API_TRACKER_STATE_T State, API_TRACKER_CH_ALLOC_T ChannelAlloc, API_TRACKER_CH_T ChannelType, H245_DATA_T DataType, H245_CHANNEL_T wTxChannel, H245_CHANNEL_T wRxChannel, DWORD MuxEntryCount ) { Tracker_T *p_tracker; H245TRACE(pInstance->dwInst,10,"API:alloc_link_tracker <-"); /* allocate tracker object */ if (!(p_tracker = (Tracker_T *)MemAlloc(sizeof(Tracker_T)))) { H245TRACE(pInstance->dwInst,1,"API:alloc_link_trakcer -> No memory"); return NULL; } p_tracker->TrackerType = TrackerType; p_tracker->TransId = dwTransId; p_tracker->State = State; switch (TrackerType) { case API_OPEN_CHANNEL_T: case API_CLOSE_CHANNEL_T: p_tracker->u.Channel.ChannelAlloc = ChannelAlloc; p_tracker->u.Channel.ChannelType = ChannelType; p_tracker->u.Channel.DataType = DataType; p_tracker->u.Channel.TxChannel = wTxChannel; p_tracker->u.Channel.RxChannel = wRxChannel; break; case API_SEND_MUX_T: case API_RECV_MUX_T: p_tracker->u.MuxEntryCount = MuxEntryCount; break; default: break; } // switch p_tracker->p_next = pInstance->API.pTracker; if (p_tracker->p_next) { p_tracker->p_prev = p_tracker->p_next->p_prev; p_tracker->p_next->p_prev = p_tracker; } else { p_tracker->p_prev = NULL; } pInstance->API.pTracker = p_tracker; H245TRACE(pInstance->dwInst,10,"API:alloc_link_tracker -> %x", p_tracker); return p_tracker; } /***************************************************************************** * * TYPE: Global * * PROCEDURE: * * DESCRIPTION: * * RETURN: * * ASSUME: List is Locked * *****************************************************************************/ void unlink_dealloc_tracker (struct InstanceStruct *pInstance, Tracker_T *p_tracker) { H245TRACE(pInstance->dwInst,4,"API:unlink_dealloc_tracker - type = %s",map_tracker_type (p_tracker->TrackerType)); if (p_tracker->p_next) p_tracker->p_next->p_prev = p_tracker->p_prev; /* if not first on the list */ if (p_tracker->p_prev) p_tracker->p_prev->p_next = p_tracker->p_next; else pInstance->API.pTracker = p_tracker->p_next; MemFree (p_tracker); } /***************************************************************************** * * TYPE: Global * * PROCEDURE: find_tracker_by_txchannel * * DESCRIPTION: * * RETURN: * * ASSUME: List is Locked * *****************************************************************************/ Tracker_T * find_tracker_by_txchannel (struct InstanceStruct *pInstance, DWORD dwChannel, API_TRACKER_CH_ALLOC_T ChannelAlloc) { register Tracker_T *p_tracker; ASSERT (pInstance != NULL); for (p_tracker = pInstance->API.pTracker;p_tracker;p_tracker = p_tracker->p_next) { if (p_tracker->u.Channel.TxChannel == dwChannel && p_tracker->u.Channel.ChannelAlloc == ChannelAlloc) { return p_tracker; } } return NULL; } /***************************************************************************** * * TYPE: Global * * PROCEDURE: find_tracker_by_rxchannel * * DESCRIPTION: * * RETURN: * * ASSUME: List is Locked * *****************************************************************************/ Tracker_T * find_tracker_by_rxchannel (struct InstanceStruct *pInstance, DWORD dwChannel, API_TRACKER_CH_ALLOC_T ChannelAlloc) { register Tracker_T *p_tracker; ASSERT (pInstance != NULL); for (p_tracker = pInstance->API.pTracker;p_tracker;p_tracker = p_tracker->p_next) { if (p_tracker->u.Channel.RxChannel == dwChannel && p_tracker->u.Channel.ChannelAlloc == ChannelAlloc) { return p_tracker; } } return NULL; } /***************************************************************************** * * TYPE: Global * * PROCEDURE: find_tracker_by_pointer * * DESCRIPTION: * * RETURN: * * ASSUME: List is Locked * *****************************************************************************/ Tracker_T * find_tracker_by_pointer (struct InstanceStruct *pInstance, Tracker_T *p_tracker_look) { Tracker_T *p_tracker; ASSERT (pInstance != NULL); for (p_tracker = pInstance->API.pTracker; ((p_tracker) && (p_tracker != p_tracker_look)); p_tracker = p_tracker->p_next); return p_tracker; } /***************************************************************************** * * TYPE: Global * * PROCEDURE: find_tracker_by_type * * DESCRIPTION: * * RETURN: * * ASSUMES: table MUST be locked before this call on this call .. * *****************************************************************************/ Tracker_T * find_tracker_by_type (struct InstanceStruct *pInstance, API_TRACKER_T tracker_type, Tracker_T *p_tracker_start) { Tracker_T *p_tracker; ASSERT (pInstance != NULL); if (p_tracker_start) p_tracker = p_tracker_start; else p_tracker = pInstance->API.pTracker; for (; ((p_tracker) && (p_tracker->TrackerType != tracker_type)); p_tracker = p_tracker->p_next); return p_tracker; } /***************************************************************************** * * TYPE: Global * * PROCEDURE: set_capability - * * DESCRIPTION: * NOTE: capid in the TotCap structure is * ignored. * * RETURN: * NewCapId if no error * H245_INVALID_CAPID if error * * ASSUMES: * Assumes the H245_INST_T is valid and has been checked * *****************************************************************************/ void del_mux_cap(struct TerminalCapabilitySet *pTermCapSet) { if (pTermCapSet->bit_mask & multiplexCapability_present) { switch (pTermCapSet->multiplexCapability.choice) { case MltplxCpblty_nonStandard_chosen: FreeNonStandardParameter(&pTermCapSet->multiplexCapability.u.MltplxCpblty_nonStandard); break; case h222Capability_chosen: FreeH222Cap(&pTermCapSet->multiplexCapability.u.h222Capability); break; case h2250Capability_chosen: FreeH2250Cap(&pTermCapSet->multiplexCapability.u.h2250Capability); break; } // switch pTermCapSet->bit_mask &= ~multiplexCapability_present; } } // del_mux_cap() HRESULT set_mux_cap(struct InstanceStruct *pInstance, struct TerminalCapabilitySet *pTermCapSet, H245_TOTCAP_T *pTotCap) { HRESULT lError; switch (pTotCap->ClientType) { case H245_CLIENT_MUX_NONSTD: H245TRACE(pInstance->dwInst,4,"API:set_mux_cap - NONSTD"); lError = CopyNonStandardParameter(&pTermCapSet->multiplexCapability.u.MltplxCpblty_nonStandard, &pTotCap->Cap.H245Mux_NONSTD); if (lError != H245_ERROR_OK) return lError; pTermCapSet->multiplexCapability.choice = MltplxCpblty_nonStandard_chosen; break; case H245_CLIENT_MUX_H222: H245TRACE(pInstance->dwInst,4,"API:set_mux_cap - H222"); lError = CopyH222Cap(&pTermCapSet->multiplexCapability.u.h222Capability, &pTotCap->Cap.H245Mux_H222); if (lError != H245_ERROR_OK) return lError; pTermCapSet->multiplexCapability.choice = h222Capability_chosen; break; case H245_CLIENT_MUX_H223: H245TRACE(pInstance->dwInst,4,"API:set_mux_cap - H223"); pTermCapSet->multiplexCapability.u.h223Capability = pTotCap->Cap.H245Mux_H223; pTermCapSet->multiplexCapability.choice = h223Capability_chosen; break; case H245_CLIENT_MUX_VGMUX: H245TRACE(pInstance->dwInst,4,"API:set_mux_cap - VGMUX"); pTermCapSet->multiplexCapability.u.v76Capability = pTotCap->Cap.H245Mux_VGMUX; pTermCapSet->multiplexCapability.choice = v76Capability_chosen; break; case H245_CLIENT_MUX_H2250: H245TRACE(pInstance->dwInst,4,"API:set_mux_cap - H2250"); lError = CopyH2250Cap(&pTermCapSet->multiplexCapability.u.h2250Capability, &pTotCap->Cap.H245Mux_H2250); if (lError != H245_ERROR_OK) return lError; pTermCapSet->multiplexCapability.choice = h2250Capability_chosen; break; default: H245TRACE(pInstance->dwInst,1,"API:set_mux_cap - Unrecognized Client Type %d", pTotCap->ClientType); return H245_ERROR_NOSUP; } pTermCapSet->bit_mask |= multiplexCapability_present; return H245_ERROR_OK; } // set_mux_cap() HRESULT set_capability ( struct InstanceStruct *pInstance, struct TerminalCapabilitySet *pTermCapSet, H245_TOTCAP_T *pTotCap /* tot capability for update*/ ) { CapabilityTableEntry *pCapEntry; Capability *pCapability; CapabilityTableLink pCapLink; HRESULT lError; ASSERT(pInstance != NULL); ASSERT(pTermCapSet != NULL); ASSERT(pTotCap != NULL); /* if the table entry is currently in the table, */ /* then delete it and add a new entry with the same entry number */ pCapLink = find_capid_by_entrynumber (pTermCapSet, pTotCap->CapId); if (pCapLink) { del_cap_link (pTermCapSet, pCapLink); } /* if pCapLink */ /* allocate an entry for the new terminal capbaility */ pCapLink = alloc_link_cap_entry (pTermCapSet); if (pCapLink == NULL) { return H245_ERROR_NOMEM; } /* make it easier to deal with the Asn1 structures */ pCapEntry = &pCapLink->value; pCapability = &pCapEntry->capability; pCapability->choice = 0; switch (pTotCap->DataType) { case H245_DATA_NONSTD: pCapability->choice = Capability_nonStandard_chosen; break; case H245_DATA_VIDEO: switch (pTotCap->Dir) { case H245_CAPDIR_RMTTX: case H245_CAPDIR_LCLTX: pCapability->choice = transmitVideoCapability_chosen; break; case H245_CAPDIR_RMTRX: case H245_CAPDIR_LCLRX: pCapability->choice = receiveVideoCapability_chosen; break; case H245_CAPDIR_RMTRXTX: case H245_CAPDIR_LCLRXTX: pCapability->choice = rcvAndTrnsmtVdCpblty_chosen; break; } // switch (Dir) break; case H245_DATA_AUDIO: switch (pTotCap->Dir) { case H245_CAPDIR_RMTTX: case H245_CAPDIR_LCLTX: pCapability->choice = transmitAudioCapability_chosen; break; case H245_CAPDIR_RMTRX: case H245_CAPDIR_LCLRX: pCapability->choice = receiveAudioCapability_chosen; break; case H245_CAPDIR_RMTRXTX: case H245_CAPDIR_LCLRXTX: pCapability->choice = rcvAndTrnsmtAdCpblty_chosen; break; } // switch (Dir) break; case H245_DATA_DATA: switch (pTotCap->Dir) { case H245_CAPDIR_RMTTX: case H245_CAPDIR_LCLTX: pCapability->choice = trnsmtDtApplctnCpblty_chosen; break; case H245_CAPDIR_RMTRX: case H245_CAPDIR_LCLRX: pCapability->choice = rcvDtApplctnCpblty_chosen; break; case H245_CAPDIR_RMTRXTX: case H245_CAPDIR_LCLRXTX: pCapability->choice = rATDACy_chosen; break; } // switch (Dir) break; case H245_DATA_ENCRYPT_D: switch (pTotCap->Dir) { case H245_CAPDIR_RMTTX: case H245_CAPDIR_LCLTX: pCapability->choice = h233EncryptnTrnsmtCpblty_chosen; break; case H245_CAPDIR_RMTRX: case H245_CAPDIR_LCLRX: pCapability->choice = h233EncryptnRcvCpblty_chosen; break; } // switch (Dir) break; case H245_DATA_CONFERENCE: pCapability->choice = conferenceCapability_chosen; break; } // switch (DataType) /* if error occured, free cap, unlock, and return */ if (pCapability->choice == 0) { H245TRACE(pInstance->dwInst,1,"API:set_capability -> Invalid capability"); del_cap_link (pTermCapSet, pCapLink); return H245_ERROR_PARAM; } /* load total cap into Capability Set */ /* if load cap returns error, free cap, unlock, and return */ lError = load_cap(pCapability, pTotCap); if (lError != H245_ERROR_OK) { del_cap_link (pTermCapSet, pCapLink); return lError; } /* mark the entry as in use */ pCapEntry->bit_mask = capability_present; pCapEntry->capabilityTableEntryNumber = pTotCap->CapId; /* set termcapTable present */ pTermCapSet->bit_mask |= capabilityTable_present; return H245_ERROR_OK; } /***************************************************************************** * * TYPE: Local * * PROCEDURE: build_object_id * * DESCRIPTION * * RETURN: linked list of Object ID structures * * ASSUMES: Input string is a valid "....." * *****************************************************************************/ static POBJECTID build_object_id (const char *p_str) { POBJECTID p_obj_id = NULL; POBJECTID p_obj_id_first = NULL; POBJECTID p_obj_id_lst = NULL; int value = 0; int fset = FALSE; /* if no sting.. forget it */ if (!p_str) return NULL; H245TRACE(0,20,"API:Object Id %s",p_str); /* while there is a string left.. */ while (*p_str != '\0') { /* while there is a string left, and it's not a '.' */ value = 0; fset = FALSE; while ((*p_str != '\0') && (*p_str != '.')) { fset = TRUE; value = value*10+(*p_str-'0'); p_str++; } /* must ahve been a "." or an end string */ if (fset) { if (*p_str != '\0') p_str++; /* allocate the first object */ if (!(p_obj_id = (POBJECTID) MemAlloc (sizeof(*p_obj_id)))) { free_object_id (p_obj_id_first); return NULL; } /* if alloc failes */ /* if first objected allocated */ if (!p_obj_id_first) p_obj_id_first = p_obj_id; else p_obj_id_lst->next = p_obj_id; p_obj_id->value = (unsigned short) value; p_obj_id->next = NULL; p_obj_id_lst = p_obj_id; } } /* while */ return p_obj_id_first; } /***************************************************************************** * * TYPE: Global * * PROCEDURE: free_mux_table_list - recursively free mux table list * * DESCRIPTION: * * RETURN: * * ASSUME: List is Locked * *****************************************************************************/ void free_mux_table_list (H245_MUX_TABLE_T *p_mux_tbl) { if (!p_mux_tbl) return; free_mux_table_list (p_mux_tbl->pNext); free_mux_el_list (p_mux_tbl->pMuxTblEntryElem); MemFree (p_mux_tbl); } /***************************************************************************** * * TYPE: Global * * PROCEDURE: free_mux_el_list - recursively free mux element list * * DESCRIPTION: * * RETURN: * * ASSUME: List is Locked * *****************************************************************************/ void free_mux_el_list (H245_MUX_ENTRY_ELEMENT_T *p_mux_el) { if (!p_mux_el) return; if (p_mux_el->Kind == H245_MUX_ENTRY_ELEMENT) free_mux_el_list (p_mux_el->u.pMuxTblEntryElem); free_mux_el_list (p_mux_el->pNext); MemFree (p_mux_el); } /***************************************************************************** * * TYPE: Global * * PROCEDURE: api_init () * * DESCRIPTION: * * RETURN: * * ASSUMES: * *****************************************************************************/ HRESULT api_init (struct InstanceStruct *pInstance) { ASSERT (pInstance != NULL); H245TRACE(pInstance->dwInst,10,"API:api_init <-"); /**************************/ /* Terminal Cap TABLE */ /**************************/ pInstance->API.PDU_LocalTermCap.choice = MltmdSystmCntrlMssg_rqst_chosen; pInstance->API.PDU_LocalTermCap.u.MltmdSystmCntrlMssg_rqst.choice = terminalCapabilitySet_chosen; pInstance->API.PDU_RemoteTermCap.choice = MltmdSystmCntrlMssg_rqst_chosen; pInstance->API.PDU_RemoteTermCap.u.MltmdSystmCntrlMssg_rqst.choice = terminalCapabilitySet_chosen; /**************************/ /* MULTIPLEX TABLE CAP's */ /**************************/ switch (pInstance->Configuration) { case H245_CONF_H324: { H223Capability *p_H223; /* set h223 capabilities */ pInstance->API.PDU_LocalTermCap. u.MltmdSystmCntrlMssg_rqst. u.terminalCapabilitySet.multiplexCapability.choice = h223Capability_chosen; p_H223 = &(pInstance->API.PDU_LocalTermCap. u.MltmdSystmCntrlMssg_rqst. u.terminalCapabilitySet.multiplexCapability. u.h223Capability); /* (TBC) how do we communicate this to the API */ /* booleans.. */ p_H223->transportWithI_frames; p_H223-> videoWithAL1 = FALSE; p_H223-> videoWithAL2 = FALSE; p_H223-> videoWithAL3 = TRUE; p_H223-> audioWithAL1 = FALSE; p_H223-> audioWithAL2 = TRUE; p_H223-> audioWithAL3 = FALSE; p_H223-> dataWithAL1 = FALSE; p_H223-> dataWithAL2 = FALSE; p_H223-> dataWithAL3 = FALSE; /* ushort's */ p_H223-> maximumAl2SDUSize = 2048; p_H223-> maximumAl3SDUSize = 2048; p_H223-> maximumDelayJitter = 0; /* enhanced/Basic */ p_H223->h223MultiplexTableCapability.choice = h223MltplxTblCpblty_bsc_chosen; } break; case H245_CONF_H323: break; case H245_CONF_H310: case H245_CONF_GVD: default: return H245_ERROR_NOSUP; break; } /* switch */ /* setup Object Id for Terminal Cap Set */ /* (TBC) where do we get/set the protocolIdentifier */ pInstance->API.PDU_LocalTermCap. u.MltmdSystmCntrlMssg_rqst. u.terminalCapabilitySet.protocolIdentifier = build_object_id (H245_PROTOID); pInstance->API.MasterSlave = APIMS_Undef; pInstance->API.SystemState = APIST_Inited; pInstance->API.LocalCapIdNum = H245_MAX_CAPID + 1; pInstance->API.LocalCapDescIdNum = 0; H245TRACE(pInstance->dwInst,10,"API:api_init -> OK"); return H245_ERROR_OK; } /***************************************************************************** * * TYPE: Global * * PROCEDURE: api_deinit () * * DESCRIPTION: * * RETURN: * * ASSUMES: * *****************************************************************************/ HRESULT api_deinit (struct InstanceStruct *pInstance) { Tracker_T *pTracker; int nCount; H245TRACE(pInstance->dwInst,10,"API:api_deinit <-"); /* free structures and act on outstanding links in structure */ #ifndef NDEBUG dump_tracker(pInstance); #endif free_object_id (pInstance->API.PDU_LocalTermCap. u.MltmdSystmCntrlMssg_rqst. u.terminalCapabilitySet.protocolIdentifier); /* free simultaneous capabilities */ for (nCount = 0; nCount < 256; ++nCount) { if (pInstance->API.PDU_LocalTermCap.TERMCAPSET.capabilityDescriptors.value[nCount].smltnsCpblts) dealloc_simultaneous_cap (&pInstance->API.PDU_LocalTermCap.TERMCAPSET.capabilityDescriptors.value[nCount]); if (pInstance->API.PDU_RemoteTermCap.TERMCAPSET.capabilityDescriptors.value[nCount].smltnsCpblts) dealloc_simultaneous_cap (&pInstance->API.PDU_RemoteTermCap.TERMCAPSET.capabilityDescriptors.value[nCount]); } /* free capabilities */ del_mux_cap(&pInstance->API.PDU_LocalTermCap.u.MltmdSystmCntrlMssg_rqst.u.terminalCapabilitySet); del_mux_cap(&pInstance->API.PDU_RemoteTermCap.u.MltmdSystmCntrlMssg_rqst.u.terminalCapabilitySet); dealloc_link_cap_list ( &pInstance->API.PDU_LocalTermCap.TERMCAPSET); dealloc_link_cap_list ( &pInstance->API.PDU_RemoteTermCap.TERMCAPSET); while ((pTracker = pInstance->API.pTracker) != NULL) { H245TRACE(pInstance->dwInst,1,"API:api_deinit -> %s Tracker Still Pending", map_tracker_type(pTracker->TrackerType)); unlink_dealloc_tracker (pInstance, pTracker); } H245TRACE(pInstance->dwInst,10,"API:api_deinit -> OK"); return H245_ERROR_OK; } #if defined(_DEBUG) /***************************************************************************** * * TYPE: Global * * PROCEDURE: map_api_error () * * DESCRIPTION: * * RETURN: * * ASSUMES: * *****************************************************************************/ LPSTR map_api_error (HRESULT lError) { static TCHAR szBuf[128]; switch (lError) { case H245_ERROR_OK: return "H245_ERROR_OK"; case H245_ERROR_INVALID_DATA_FORMAT: return "H245_ERROR_INVALID_DATA_FORMAT"; case H245_ERROR_NOMEM: return "H245_ERROR_NOMEM"; case H245_ERROR_NOSUP: return "H245_ERROR_NOSUP"; case H245_ERROR_PARAM: return "H245_ERROR_PARAM"; case H245_ERROR_ALREADY_INIT: return "H245_ERROR_ALREADY_INIT"; case H245_ERROR_NOT_CONNECTED: return "H245_ERROR_NOT_CONNECTED"; case H245_ERROR_NORESOURCE: return "H245_ERROR_NORESOURCE"; case H245_ERROR_NOTIMP: return "H245_ERROR_NOTIMP"; case H245_ERROR_SUBSYS: return "H245_ERROR_SUBSYS"; case H245_ERROR_FATAL: return "H245_ERROR_FATAL"; case H245_ERROR_MAXTBL: return "H245_ERROR_MAXTBL"; case H245_ERROR_CHANNEL_INUSE: return "H245_ERROR_CHANNEL_INUSE"; case H245_ERROR_INVALID_CAPID: return "H245_ERROR_INVALID_CAPID"; case H245_ERROR_INVALID_OP: return "H245_ERROR_INVALID_OP"; case H245_ERROR_UNKNOWN: return "H245_ERROR_UNKNOWN"; case H245_ERROR_NOBANDWIDTH: return "H245_ERROR_NOBANDWIDTH"; case H245_ERROR_LOSTCON: return "H245_ERROR_LOSTCON"; case H245_ERROR_INVALID_MUXTBLENTRY: return "H245_ERROR_INVALID_MUXTBLENTRY"; case H245_ERROR_INVALID_INST: return "H245_ERROR_INVALID_INST"; case H245_ERROR_INPROCESS: return "H245_ERROR_INPROCESS"; case H245_ERROR_INVALID_STATE: return "H245_ERROR_INVALID_STATE"; case H245_ERROR_TIMEOUT: return "H245_ERROR_TIMEOUT"; case H245_ERROR_INVALID_CHANNEL: return "H245_ERROR_INVALID_CHANNEL"; case H245_ERROR_INVALID_CAPDESCID: return "H245_ERROR_INVALID_CAPDESCID"; case H245_ERROR_CANCELED: return "H245_ERROR_CANCELED"; case H245_ERROR_MUXELEMENT_DEPTH: return "H245_ERROR_MUXELEMENT_DEPTH"; case H245_ERROR_MUXELEMENT_WIDTH: return "H245_ERROR_MUXELEMENT_WIDTH"; case H245_ERROR_ASN1: return "H245_ERROR_ASN1"; case H245_ERROR_NO_MUX_CAPS: return "H245_ERROR_NO_MUX_CAPS"; case H245_ERROR_NO_CAPDESC: return "H245_ERROR_NO_CAPDESC"; default: wsprintf (szBuf,"**** UNKNOWN ERROR *** %d (0x%x)",lError,lError); return szBuf; } } /***************************************************************************** * * TYPE: Global * * PROCEDURE: map_fsm_event - * * DESpCRIPTION: * * RETURN: * * ASSUMES: * *****************************************************************************/ LPSTR map_fsm_event (DWORD event) { static TCHAR szBuf[128]; switch (event) { case H245_IND_MSTSLV: return "H245_IND_MSTSLV"; case H245_IND_CAP: return "H245_IND_CAP"; case H245_IND_OPEN: return "H245_IND_OPEN"; case H245_IND_OPEN_CONF: return "H245_IND_OPEN_CONF"; case H245_IND_CLOSE: return "H245_IND_CLOSE"; case H245_IND_REQ_CLOSE: return "H245_IND_REQ_CLOSE"; case H245_IND_MUX_TBL: return "H245_IND_MUX_TBL"; case H245_IND_MTSE_RELEASE: return "H245_IND_MTSE_RELEASE"; case H245_IND_RMESE: return "H245_IND_RMESE"; case H245_IND_RMESE_RELEASE: return "H245_IND_RMESE_RELEASE"; case H245_IND_MRSE: return "H245_IND_MRSE"; case H245_IND_MRSE_RELEASE: return "H245_IND_MRSE_RELEASE"; case H245_IND_MLSE: return "H245_IND_MLSE"; case H245_IND_MLSE_RELEASE: return "H245_IND_MLSE_RELEASE"; case H245_IND_NONSTANDARD_REQUEST: return "H245_IND_NONSTANDARD_REQUEST"; case H245_IND_NONSTANDARD_RESPONSE: return "H245_IND_NONSTANDARD_RESPONSE"; case H245_IND_NONSTANDARD_COMMAND: return "H245_IND_NONSTANDARD_COMMAND"; case H245_IND_NONSTANDARD: return "H245_IND_NONSTANDARD"; case H245_IND_MISC_COMMAND: return "H245_IND_MISC_COMMAND"; case H245_IND_MISC: return "H245_IND_MISC"; case H245_IND_COMM_MODE_REQUEST: return "H245_IND_COMM_MODE_REQUEST"; case H245_IND_COMM_MODE_RESPONSE: return "H245_IND_COMM_MODE_RESPONSE"; case H245_IND_COMM_MODE_COMMAND: return "H245_IND_COMM_MODE_COMMAND"; case H245_IND_CONFERENCE_REQUEST: return "H245_IND_CONFERENCE_REQUEST"; case H245_IND_CONFERENCE_RESPONSE: return "H245_IND_CONFERENCE_RESPONSE"; case H245_IND_CONFERENCE_COMMAND: return "H245_IND_CONFERENCE_COMMAND"; case H245_IND_CONFERENCE: return "H245_IND_CONFERENCE"; case H245_IND_SEND_TERMCAP: return "H245_IND_SEND_TERMCAP"; case H245_IND_ENCRYPTION: return "H245_IND_ENCRYPTION"; case H245_IND_FLOW_CONTROL: return "H245_IND_FLOW_CONTROL"; case H245_IND_ENDSESSION: return "H245_IND_ENDSESSION"; case H245_IND_FUNCTION_NOT_UNDERSTOOD:return "H245_IND_FUNCTION_NOT_UNDERSTOOD:"; case H245_IND_JITTER: return "H245_IND_JITTER"; case H245_IND_H223_SKEW: return "H245_IND_H223_SKEW"; case H245_IND_NEW_ATM_VC: return "H245_IND_NEW_ATM_VC"; case H245_IND_USERINPUT: return "H245_IND_USERINPUT"; case H245_IND_H2250_MAX_SKEW: return "H245_IND_H2250_MAX_SKEW"; case H245_IND_MC_LOCATION: return "H245_IND_MC_LOCATION"; case H245_IND_VENDOR_ID: return "H245_IND_VENDOR_ID"; case H245_IND_FUNCTION_NOT_SUPPORTED: return "H245_IND_FUNCTION_NOT_SUPPORTED"; case H245_IND_H223_RECONFIG: return "H245_IND_H223_RECONFIG"; case H245_IND_H223_RECONFIG_ACK: return "H245_IND_H223_RECONFIG_ACK"; case H245_IND_H223_RECONFIG_REJECT: return "H245_IND_H223_RECONFIG_REJECT"; case H245_CONF_INIT_MSTSLV: return "H245_CONF_INIT_MSTSLV"; case H245_CONF_SEND_TERMCAP: return "H245_CONF_SEND_TERMCAP"; case H245_CONF_OPEN: return "H245_CONF_OPEN"; case H245_CONF_NEEDRSP_OPEN: return "H245_CONF_NEEDRSP_OPEN"; case H245_CONF_CLOSE: return "H245_CONF_CLOSE"; case H245_CONF_REQ_CLOSE: return "H245_CONF_REQ_CLOSE"; case H245_CONF_MUXTBL_SND: return "H245_CONF_MUXTBL_SND"; case H245_CONF_RMESE: return "H245_CONF_RMESE"; case H245_CONF_RMESE_REJECT: return "H245_CONF_RMESE_REJECT"; case H245_CONF_RMESE_EXPIRED: return "H245_CONF_RMESE_EXPIRED"; case H245_CONF_MRSE: return "H245_CONF_MRSE"; case H245_CONF_MRSE_REJECT: return "H245_CONF_MRSE_REJECT"; case H245_CONF_MRSE_EXPIRED: return "H245_CONF_MRSE_EXPIRED"; case H245_CONF_MLSE: return "H245_CONF_MLSE"; case H245_CONF_MLSE_REJECT: return "H245_CONF_MLSE_REJECT"; case H245_CONF_MLSE_EXPIRED: return "H245_CONF_MLSE_EXPIRED"; case H245_CONF_RTDSE: return "H245_CONF_RTDSE"; case H245_CONF_RTDSE_EXPIRED: return "H245_CONF_RTDSE_EXPIRED"; default: wsprintf (szBuf,"**** UNKNOWN EVENT *** %d (0x%x)",event,event); return szBuf; } } LPSTR map_tracker_type (API_TRACKER_T tracker_type) { static TCHAR szBuf[128]; switch (tracker_type) { case API_TERMCAP_T: return "API_TERMCAP_T"; case API_OPEN_CHANNEL_T: return "API_OPEN_CHANNEL_T"; case API_CLOSE_CHANNEL_T: return "API_CLOSE_CHANNEL_T"; case API_MSTSLV_T: return "API_MSTSLV_T"; case API_SEND_MUX_T: return "API_SEND_MUX_T"; case API_RECV_MUX_T: return "API_RECV_MUX_T"; default: wsprintf (szBuf,"**** UNKNOWN TRACKER TYPE *** %d (0x%x)",tracker_type,tracker_type); return szBuf; } } #endif // (_DEBUG)