/*------------------------------------------------------------------------------------------------*/ /* UNICENS XML Parser */ /* Copyright 2017, Microchip Technology Inc. and its subsidiaries. */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions are met: */ /* */ /* 1. Redistributions of source code must retain the above copyright notice, this */ /* list of conditions and the following disclaimer. */ /* */ /* 2. Redistributions in binary form must reproduce the above copyright notice, */ /* this list of conditions and the following disclaimer in the documentation */ /* and/or other materials provided with the distribution. */ /* */ /* 3. Neither the name of the copyright holder nor the names of its */ /* contributors may be used to endorse or promote products derived from */ /* this software without specific prior written permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" */ /* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE */ /* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE */ /* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL */ /* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR */ /* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */ /* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, */ /* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /*------------------------------------------------------------------------------------------------*/ #include #include #include #include "UcsXml.h" #include "UcsXml_Private.h" static const char* USB_PHY_STANDARD = "Standard"; static const char* USB_PHY_HSIC = "HSIC"; static const char* CLOCK_8FS = "8Fs"; static const char* CLOCK_16FS = "16Fs"; static const char* CLOCK_32FS = "32Fs"; static const char* CLOCK_64FS = "64Fs"; static const char* CLOCK_128FS = "128Fs"; static const char* CLOCK_256FS = "256Fs"; static const char* CLOCK_512FS = "512Fs"; static const char* CLOCK_1024FS = "1024Fs"; static const char* CLOCK_2048FS = "2048Fs"; static const char* CLOCK_3072FS = "3072Fs"; static const char* CLOCK_4096FS = "4096Fs"; static const char* CLOCK_6144FS = "6144Fs"; static const char* CLOCK_8192FS = "8192Fs"; static const char* CLOCK_WILDCARD = "Wildcard"; static const char* STRM_ALIGN_L16 = "Left16Bit"; static const char* STRM_ALIGN_L24 = "Left24Bit"; static const char* STRM_ALIGN_R16 = "Right16Bit"; static const char* STRM_ALIGN_R24 = "Right24Bit"; static const char* STRM_ALIGN_SEQUENTIAL = "Seq"; static const char* I2S_PIN_SRXA0 = "SRXA0"; static const char* I2S_PIN_SRXA1 = "SRXA1"; static const char* I2S_PIN_SRXB0 = "SRXB0"; static const char* I2S_PIN_SRXB1 = "SRXB1"; static const char* MUTE_OFF = "NoMuting"; static const char* MUTE_SIGNAL = "MuteSignal"; #define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) #define ASSERT_FALSE(func, par) { UcsXml_CB_OnError("Parameter error in attribute=%s value=%s, file=%s, line=%d", 4, func, par, __FILENAME__, __LINE__); return false; } #define CHECK_POINTER(PTR) if (NULL == PTR) { ASSERT_FALSE(PTR, "NULL pointer"); } static int32_t Str2Int(const char *val) { return strtol( val, NULL, 0 ); } void *MCalloc(struct UcsXmlObjectList *list, uint32_t nElem, uint32_t elemSize) { void *obj; struct UcsXmlObjectList *tail = list; if (NULL == list || 0 == nElem || 0 == elemSize) return NULL; obj = calloc(nElem, elemSize); if (NULL == obj) { assert(false); return NULL; } if (NULL == list->obj) { list->obj = obj; return obj; } while(tail->next) tail = tail->next; tail->next = calloc(1, sizeof(struct UcsXmlObjectList)); if (NULL == tail->next) { assert(false); free(obj); return NULL; } tail->next->obj = obj; return obj; } void FreeObjList(struct UcsXmlObjectList *cur) { struct UcsXmlObjectList *root = cur; while(cur) { struct UcsXmlObjectList *next = cur->next; assert(NULL != cur->obj); if (cur->obj) free(cur->obj); if (cur != root) free(cur); cur = next; } } bool GetMostSocket(Ucs_Xrm_MostSocket_t **mostSoc, struct MostSocketParameters *param) { Ucs_Xrm_MostSocket_t *soc = NULL; CHECK_POINTER(mostSoc); CHECK_POINTER(param); CHECK_POINTER(param->list); soc = MCalloc(param->list, 1, sizeof(Ucs_Xrm_MostSocket_t)); CHECK_POINTER(soc); *mostSoc = soc; soc->resource_type = UCS_XRM_RC_TYPE_MOST_SOCKET; soc->most_port_handle = 0x0D00; soc->bandwidth = param->bandwidth; soc->direction = param->isSource ? UCS_SOCKET_DIR_INPUT : UCS_SOCKET_DIR_OUTPUT; switch(param->dataType) { case SYNC_DATA: soc->data_type = UCS_MOST_SCKT_SYNC_DATA; break; case AV_PACKETIZED: soc->data_type = UCS_MOST_SCKT_AV_PACKETIZED; break; case QOS_IP: soc->data_type = UCS_MOST_SCKT_QOS_IP; break; case DISC_FRAME_PHASE: soc->data_type = UCS_MOST_SCKT_DISC_FRAME_PHASE; break; default: ASSERT_FALSE("GetMostSocket->dataType", ""); } return true; } bool GetUsbPort(Ucs_Xrm_UsbPort_t **usbPort, struct UsbPortParameters *param) { Ucs_Xrm_UsbPort_t *port = NULL; CHECK_POINTER(usbPort); CHECK_POINTER(param); CHECK_POINTER(param->list); CHECK_POINTER(param->deviceInterfaces); CHECK_POINTER(param->streamInCount); CHECK_POINTER(param->streamOutCount); CHECK_POINTER(param->physicalLayer); port = MCalloc(param->list, 1, sizeof(Ucs_Xrm_UsbPort_t)); CHECK_POINTER(port); *usbPort = port; port->resource_type = UCS_XRM_RC_TYPE_USB_PORT; port->index = 0; port->devices_interfaces = (uint16_t)Str2Int(param->deviceInterfaces); port->streaming_if_ep_in_count = (uint8_t)Str2Int(param->streamInCount); port->streaming_if_ep_out_count = (uint8_t)Str2Int(param->streamOutCount); if (0 == strcmp(USB_PHY_STANDARD, param->physicalLayer)) port->physical_layer = UCS_USB_PHY_LAYER_STANDARD; else if (0 == strcmp(USB_PHY_HSIC, param->physicalLayer)) port->physical_layer = UCS_USB_PHY_LAYER_HSCI; else ASSERT_FALSE("GetUsbPort->physical_layer", param->physicalLayer); return true; } bool GetUsbPortDefaultCreated(Ucs_Xrm_ResObject_t **usbPort, struct UcsXmlObjectList *list) { Ucs_Xrm_DefaultCreatedPort_t *p; CHECK_POINTER(usbPort); CHECK_POINTER(list); p = MCalloc(list, 1, sizeof(Ucs_Xrm_DefaultCreatedPort_t)); CHECK_POINTER(p); p->resource_type = UCS_XRM_RC_TYPE_DC_PORT; p->port_type = UCS_XRM_PORT_TYPE_USB; p->index = 0; *usbPort = (Ucs_Xrm_ResObject_t *)p; return true; } bool GetUsbSocket(Ucs_Xrm_UsbSocket_t **usbSoc, struct UsbSocketParameters *param) { Ucs_Xrm_UsbSocket_t *soc = NULL; CHECK_POINTER(usbSoc); CHECK_POINTER(param); CHECK_POINTER(param->list); CHECK_POINTER(param->endpointAddress); CHECK_POINTER(param->framesPerTrans); CHECK_POINTER(param->usbPort); soc = MCalloc(param->list, 1, sizeof(Ucs_Xrm_UsbSocket_t)); CHECK_POINTER(soc); *usbSoc = soc; soc->resource_type = UCS_XRM_RC_TYPE_USB_SOCKET; soc->direction = param->isSource ? UCS_SOCKET_DIR_INPUT : UCS_SOCKET_DIR_OUTPUT; switch(param->dataType) { case SYNC_DATA: soc->data_type = UCS_USB_SCKT_SYNC_DATA; break; case AV_PACKETIZED: soc->data_type = UCS_USB_SCKT_AV_PACKETIZED; break; case IPC_PACKET: soc->data_type = UCS_USB_SCKT_IPC_PACKET; break; default: ASSERT_FALSE("GetUsbSocket->dataType", ""); } soc->end_point_addr = (uint8_t)Str2Int(param->endpointAddress); soc->frames_per_transfer = (uint16_t)Str2Int(param->framesPerTrans); soc->usb_port_obj_ptr = param->usbPort; return true; } bool GetMlbPort(Ucs_Xrm_MlbPort_t **mlbPort, struct MlbPortParameters *param) { Ucs_Xrm_MlbPort_t *port = NULL; CHECK_POINTER(mlbPort); CHECK_POINTER(param); CHECK_POINTER(param->list); CHECK_POINTER(param->clockConfig); port = MCalloc(param->list, 1, sizeof(Ucs_Xrm_MlbPort_t)); CHECK_POINTER(port); *mlbPort = port; port->resource_type = UCS_XRM_RC_TYPE_MLB_PORT; port->index = 0; if (0 == strcmp(param->clockConfig, CLOCK_256FS)) port->clock_config = UCS_MLB_CLK_CFG_256_FS; else if (0 == strcmp(param->clockConfig, CLOCK_512FS)) port->clock_config = UCS_MLB_CLK_CFG_512_FS; else if (0 == strcmp(param->clockConfig, CLOCK_1024FS)) port->clock_config = UCS_MLB_CLK_CFG_1024_FS; else if (0 == strcmp(param->clockConfig, CLOCK_2048FS)) port->clock_config = UCS_MLB_CLK_CFG_2048_FS; else if (0 == strcmp(param->clockConfig, CLOCK_3072FS)) port->clock_config = UCS_MLB_CLK_CFG_3072_FS; else if (0 == strcmp(param->clockConfig, CLOCK_4096FS)) port->clock_config = UCS_MLB_CLK_CFG_4096_FS; else if (0 == strcmp(param->clockConfig, CLOCK_6144FS)) port->clock_config = UCS_MLB_CLK_CFG_6144_FS; else if (0 == strcmp(param->clockConfig, CLOCK_8192FS)) port->clock_config = UCS_MLB_CLK_CFG_8192_FS; else ASSERT_FALSE("GetMlbPort->clockConfig", param->clockConfig); return true; } bool GetMlbPortDefaultCreated(Ucs_Xrm_ResObject_t **mlbPort, struct UcsXmlObjectList *list) { Ucs_Xrm_DefaultCreatedPort_t *p; CHECK_POINTER(mlbPort); CHECK_POINTER(list) p = MCalloc(list, 1, sizeof(Ucs_Xrm_DefaultCreatedPort_t)); CHECK_POINTER(p); p->resource_type = UCS_XRM_RC_TYPE_DC_PORT; p->port_type = UCS_XRM_PORT_TYPE_MLB; p->index = 0; *mlbPort = (Ucs_Xrm_ResObject_t *)p; return true; } bool GetMlbSocket(Ucs_Xrm_MlbSocket_t **mlbSoc, struct MlbSocketParameters *param) { Ucs_Xrm_MlbSocket_t *soc = NULL; CHECK_POINTER(mlbSoc); CHECK_POINTER(param); CHECK_POINTER(param->list); CHECK_POINTER(param->channelAddress); CHECK_POINTER(param->mlbPort); soc = MCalloc(param->list, 1, sizeof(Ucs_Xrm_MlbSocket_t)); CHECK_POINTER(soc); *mlbSoc = soc; soc->resource_type = UCS_XRM_RC_TYPE_MLB_SOCKET; soc->direction = param->isSource ? UCS_SOCKET_DIR_INPUT : UCS_SOCKET_DIR_OUTPUT; soc->bandwidth = param->bandwidth; switch(param->dataType) { case SYNC_DATA: soc->data_type = UCS_MLB_SCKT_SYNC_DATA; break; case AV_PACKETIZED: soc->data_type = UCS_MLB_SCKT_AV_PACKETIZED; break; case QOS_IP: soc->data_type = UCS_MLB_SCKT_QOS_IP; break; case DISC_FRAME_PHASE: soc->data_type = UCS_MLB_SCKT_DISC_FRAME_PHASE; break; case IPC_PACKET: soc->data_type = UCS_MLB_SCKT_IPC_PACKET; break; default: ASSERT_FALSE("GetMlbSocket->dataType", ""); } soc->channel_address = (uint16_t)Str2Int(param->channelAddress); soc->mlb_port_obj_ptr = param->mlbPort; return true; } bool GetStrmPort(Ucs_Xrm_StrmPort_t **strmPort, struct StrmPortParameters *param) { Ucs_Xrm_StrmPort_t *port = NULL; CHECK_POINTER(strmPort); CHECK_POINTER(param); CHECK_POINTER(param->list); CHECK_POINTER(param->clockConfig); port = MCalloc(param->list, 1, sizeof(Ucs_Xrm_StrmPort_t)); CHECK_POINTER(port); *strmPort = port; port->resource_type = UCS_XRM_RC_TYPE_STRM_PORT; port->index = param->index; if (0 == port->index) { if (0 == strcmp(param->clockConfig, CLOCK_8FS)) port->clock_config = UCS_STREAM_PORT_CLK_CFG_8FS; else if (0 == strcmp(param->clockConfig, CLOCK_16FS)) port->clock_config = UCS_STREAM_PORT_CLK_CFG_16FS; else if (0 == strcmp(param->clockConfig, CLOCK_32FS)) port->clock_config = UCS_STREAM_PORT_CLK_CFG_32FS; else if (0 == strcmp(param->clockConfig, CLOCK_64FS)) port->clock_config = UCS_STREAM_PORT_CLK_CFG_64FS; else if (0 == strcmp(param->clockConfig, CLOCK_128FS)) port->clock_config = UCS_STREAM_PORT_CLK_CFG_128FS; else if (0 == strcmp(param->clockConfig, CLOCK_256FS)) port->clock_config = UCS_STREAM_PORT_CLK_CFG_256FS; else if (0 == strcmp(param->clockConfig, CLOCK_512FS)) port->clock_config = UCS_STREAM_PORT_CLK_CFG_512FS; else if (0 == strcmp(param->clockConfig, CLOCK_WILDCARD)) port->clock_config = UCS_STREAM_PORT_CLK_CFG_WILD; else ASSERT_FALSE("GetStrmPort->clockConfig", param->clockConfig); } else { port->clock_config = UCS_STREAM_PORT_CLK_CFG_WILD; } if (0 == strcmp(param->dataAlignment, STRM_ALIGN_L16)) port->data_alignment = UCS_STREAM_PORT_ALGN_LEFT16BIT; else if (0 == strcmp(param->dataAlignment, STRM_ALIGN_L24)) port->data_alignment = UCS_STREAM_PORT_ALGN_LEFT24BIT; else if (0 == strcmp(param->dataAlignment, STRM_ALIGN_R16)) port->data_alignment = UCS_STREAM_PORT_ALGN_RIGHT16BIT; else if (0 == strcmp(param->dataAlignment, STRM_ALIGN_R24)) port->data_alignment = UCS_STREAM_PORT_ALGN_RIGHT24BIT; else if (0 == strcmp(param->dataAlignment, STRM_ALIGN_SEQUENTIAL)) port->data_alignment = UCS_STREAM_PORT_ALGN_SEQ; else ASSERT_FALSE("GetStrmPort->dataAlignment", param->dataAlignment); return true; } bool GetStrmSocket(Ucs_Xrm_StrmSocket_t **strmSoc, struct StrmSocketParameters *param) { Ucs_Xrm_StrmSocket_t *soc = NULL; CHECK_POINTER(strmSoc); CHECK_POINTER(param); CHECK_POINTER(param->list); CHECK_POINTER(param->streamPin); CHECK_POINTER(param->streamPortA); CHECK_POINTER(param->streamPortB); soc = MCalloc(param->list, 1, sizeof(Ucs_Xrm_StrmSocket_t)); CHECK_POINTER(soc); *strmSoc = soc; soc->resource_type = UCS_XRM_RC_TYPE_STRM_SOCKET; soc->direction = param->isSource ? UCS_SOCKET_DIR_INPUT : UCS_SOCKET_DIR_OUTPUT; switch(param->dataType) { case SYNC_DATA: soc->data_type = UCS_STREAM_PORT_SCKT_SYNC_DATA; break; default: ASSERT_FALSE("GetStrmSocket->dataType", ""); } soc->bandwidth = param->bandwidth; if (0 == strcmp(param->streamPin, I2S_PIN_SRXA0)) { soc->stream_pin_id = UCS_STREAM_PORT_PIN_ID_SRXA0; soc->stream_port_obj_ptr = param->streamPortA; return true; } else if (0 == strcmp(param->streamPin, I2S_PIN_SRXA1)) { soc->stream_pin_id = UCS_STREAM_PORT_PIN_ID_SRXA1; soc->stream_port_obj_ptr = param->streamPortA; return true; } else if (0 == strcmp(param->streamPin, I2S_PIN_SRXB0)) { soc->stream_pin_id = UCS_STREAM_PORT_PIN_ID_SRXB0; soc->stream_port_obj_ptr = param->streamPortB; return true; } else if (0 == strcmp(param->streamPin, I2S_PIN_SRXB1)) { soc->stream_pin_id = UCS_STREAM_PORT_PIN_ID_SRXB1; soc->stream_port_obj_ptr = param->streamPortB; return true; } else ASSERT_FALSE("GetStrmSocket->streamPin", param->streamPin); return true; } bool GetSplitter(Ucs_Xrm_Splitter_t **splitter, struct SplitterParameters *param) { Ucs_Xrm_Splitter_t *split = NULL; CHECK_POINTER(splitter); CHECK_POINTER(param); CHECK_POINTER(param->list); split = MCalloc(param->list, 1, sizeof(Ucs_Xrm_Splitter_t)); CHECK_POINTER(split); *splitter = split; split->most_port_handle = 0x0D00; split->resource_type = UCS_XRM_RC_TYPE_SPLITTER; split->bytes_per_frame = param->bytesPerFrame; split->socket_in_obj_ptr = param->inSoc; return true; } bool GetCombiner(Ucs_Xrm_Combiner_t **combiner, struct CombinerParameters *param) { Ucs_Xrm_Combiner_t *comb = NULL; CHECK_POINTER(combiner); CHECK_POINTER(param); CHECK_POINTER(param->list); comb = MCalloc(param->list, 1, sizeof(Ucs_Xrm_Combiner_t)); CHECK_POINTER(comb); *combiner = comb; comb->most_port_handle = 0x0D00; comb->resource_type = UCS_XRM_RC_TYPE_COMBINER; comb->bytes_per_frame = param->bytesPerFrame; comb->port_socket_obj_ptr = param->outSoc; return true; } bool GetSyncCon(Ucs_Xrm_SyncCon_t **syncCon, struct SyncConParameters *param) { Ucs_Xrm_SyncCon_t *con = NULL; CHECK_POINTER(syncCon); CHECK_POINTER(param); CHECK_POINTER(param->list); CHECK_POINTER(param->muteMode); CHECK_POINTER(param->inSoc); CHECK_POINTER(param->outSoc); con = MCalloc(param->list, 1, sizeof(Ucs_Xrm_SyncCon_t)); CHECK_POINTER(con); *syncCon = con; con->resource_type = UCS_XRM_RC_TYPE_SYNC_CON; if (0 == strcmp(param->muteMode, MUTE_OFF)) con->mute_mode = UCS_SYNC_MUTE_MODE_NO_MUTING; else if (0 == strcmp(param->muteMode, MUTE_SIGNAL)) con->mute_mode = UCS_SYNC_MUTE_MODE_MUTE_SIGNAL; else ASSERT_FALSE("GetSyncCon->mute_mode", param->muteMode); if (param->optional_offset) con->offset = (uint16_t)Str2Int(param->optional_offset); else con->offset = 0; con->socket_in_obj_ptr = param->inSoc; con->socket_out_obj_ptr = param->outSoc; return true; } bool GetAvpCon(Ucs_Xrm_AvpCon_t **avpCon, struct AvpConParameters *param) { Ucs_Xrm_AvpCon_t *con = NULL; CHECK_POINTER(avpCon); CHECK_POINTER(param); CHECK_POINTER(param->list); CHECK_POINTER(param->inSoc); CHECK_POINTER(param->outSoc); con = MCalloc(param->list, 1, sizeof(Ucs_Xrm_AvpCon_t)); CHECK_POINTER(con); *avpCon = con; con->resource_type = UCS_XRM_RC_TYPE_AVP_CON; con->socket_in_obj_ptr = param->inSoc; con->socket_out_obj_ptr = param->outSoc; if (param->optional_isocPacketSize) { int32_t pSize = Str2Int(param->optional_isocPacketSize); switch(pSize) { case 188: con->isoc_packet_size = UCS_ISOC_PCKT_SIZE_188; break; case 196: con->isoc_packet_size = UCS_ISOC_PCKT_SIZE_196; break; case 206: con->isoc_packet_size = UCS_ISOC_PCKT_SIZE_206; break; default: ASSERT_FALSE("GetAvpCon->isoc_packet_size", ""); } } else { con->isoc_packet_size = UCS_ISOC_PCKT_SIZE_188; } return true; }