-/*
- * Unicens XML Parser
- *
- * Copyright (C) 2017 Microchip Technology Germany II GmbH & Co. KG
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * You may also obtain this software under a propriety license from Microchip.
- * Please contact Microchip for further information.
- *
- */
-#include <assert.h>
-#include <string.h>
-#include "mxml.h"
-#include "UcsXml.h"
-
-/************************************************************************/
-/* USER ADJUSTABLE CONSTANTS */
-/************************************************************************/
-
-#define MAX_JOB_LIST_LEN 6
-
-/************************************************************************/
-/* PRIVATE DECLARATIONS */
-/************************************************************************/
-
-#define COMPILETIME_CHECK(cond) (void)sizeof(int[!!(cond) - 1])
-
-struct UcsXmlObjectList
-{
- void *obj;
- struct UcsXmlObjectList *next;
-};
-
-struct UcsXmlRouteInfo
-{
- bool isSource;
- char routeName[32];
- Ucs_Rm_EndPoint_t *ep;
- struct UcsXmlRouteInfo *next;
-};
-
-struct UcsXmlScriptInfo
-{
- char scriptName[32];
- Ucs_Rm_Node_t *node;
- struct UcsXmlScriptInfo *next;
-};
-
-typedef enum
-{
- SYNC_DATA = 0, /*!< \brief Specifies the synchronous streaming data type */
- CONTROL_DATA = 2, /*!< \brief Specifies the control data type */
- AV_PACKETIZED = 3, /*!< \brief Specifies the A/V Packetized Isochronous
- streaming data type */
- QOS_IP = 4, /*!< \brief Specifies the Quality of Service IP
- streaming data type*/
- DISC_FRAME_PHASE = 5, /*!< \brief Specifies the DiscreteFrame Isochronous
- streaming phase data type */
- IPC_PACKET = 7, /*!< \brief Specifies the IPC packet data type */
- INVALID = 0xFF /*!< \brief Defined invalid value */
-} MData_t;
-
-typedef enum
-{
- MPORT_MOST,
- MPORT_USB,
- MPORT_MLB,
- MPORT_I2S,
- MPORT_INVALID = 0xFF
-} MPort_t;
-
-typedef enum
-{
- Parse_Success = 10,
- Parse_MemoryError,
- Parse_XmlError
-} ParseResult_t;
-
-typedef struct {
- struct UcsXmlObjectList objList;
- struct UcsXmlRouteInfo *pRtLst;
- struct UcsXmlScriptInfo *pScrLst;
- Ucs_Rm_Node_t *nod;
- Ucs_Xrm_ResObject_t *inSocket;
- Ucs_Xrm_ResObject_t *outSocket;
- Ucs_Xrm_ResObject_t **jobList;
- MData_t dataType;
- uint16_t blockWidth;
- const char* chName;
- uint16_t pause;
-} PrivateData_t;
-
-/************************************************************************/
-/* Constants */
-/************************************************************************/
-
-//Key section
-static const char* UNICENS = "unicens";
-static const char* ASYNC_BANDWIDTH = "async_bandwidth";
-static const char* CHANNEL = "channel";
-static const char* CHANNEL_NAME = "channel_name";
-static const char* ADDRESS = "channel_addr";
-static const char* BANDWIDTH = "bandwidth";
-static const char* OFFSET = "offset";
-static const char* DATA_TYPE = "data_type";
-static const char* DEVICE = "device";
-static const char* DEVICE_MLB_SPEED = "mlb_port_speed";
-static const char* NODE_ADDR = "node_address";
-static const char* DIR = "dir";
-static const char* I2S_PIN = "i2s_pin";
-static const char* PACKETS_XACT = "packets_per_xact";
-static const char* PORT = "port";
-static const char* SOCKET = "socket";
-
-static const char* I2S_FS_SPEED = "i2s_fs_speed";
-static const char* I2S_ALIGN = "i2s_align";
-
-//value section
-static const char* PORT_MOST = "MOST";
-static const char* PORT_USB = "USB";
-static const char* PORT_MLB = "MLB";
-static const char* PORT_I2S = "I2S";
-
-static const char* DATATYPE_SYNC = "SYNC";
-static const char* DATATYPE_AVP = "AVP";
-static const char* DATATYPE_CTRL = "CTRL";
-static const char* DATATYPE_QOS = "QOS";
-static const char* DATATYPE_DFP = "DFP";
-static const char* DATATYPE_IPC = "IPC";
-
-static const char* DIR_IN = "IN";
-static const char* DIR_OUT = "OUT";
-
-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* I2S_ALIGN_L16 = "Left16";
-static const char* I2S_ALIGN_L24 = "Left24";
-static const char* I2S_ALIGN_R16 = "Right16";
-static const char* I2S_ALIGN_R24 = "Right24";
-static const char* I2S_ALIGN_SEQUENTIAL = "Seq";
-
-static const char* SCRIPT = "script";
-static const char* ACTION = "action";
-static const char* NAME = "name";
-static const char* TYPE = "type";
-static const char* FBLOCK_ID = "fblock_id";
-static const char* FUNCTION_ID = "function_id";
-static const char* OP_TYPE_REQUEST = "op_request";
-static const char* OP_TYPE_RESPONSE = "op_response";
-static const char* PAYLOAD_REQ_HEX = "load_req_hex";
-static const char* PAYLOAD_RES_HEX = "load_res_hex";
-static const char* PAUSE_MS = "pause_ms";
-
-static const char* SEND_MSG = "SEND_MSG";
-static const char* PAUSE = "PAUSE";
-
-/************************************************************************/
-/* Private Function Prototypes */
-/************************************************************************/
-
-static void *MCalloc(struct UcsXmlObjectList *list, uint32_t nElem, uint32_t elemSize);
-static void FreeObjList(struct UcsXmlObjectList *cur);
-static void FreeVal(UcsXmlVal_t *v);
-static bool GetElement(mxml_node_t *element, const char *name, bool goDeep, mxml_node_t **out, bool mandatory);
-static bool GetCount(mxml_node_t *element, const char *name, uint32_t *out, bool mandatory);
-static bool GetString(mxml_node_t *element, const char *key, const char **out, bool mandatory);
-static bool GetUInt16(mxml_node_t *element, const char *key, uint16_t *out, bool mandatory);
-static bool GetUInt8(mxml_node_t *element, const char *key, uint8_t *out, bool mandatory);
-static bool GetMlbSpeed(mxml_node_t *element, const char *key, Ucs_Mlb_ClockConfig_t *clock, bool mandatory);
-static bool GetI2SSpeed(mxml_node_t *element, const char *key, Ucs_Stream_PortClockConfig_t *clock, bool mandatory);
-static bool GetI2SPin(mxml_node_t *element, Ucs_Stream_PortPinId_t *pin, uint8_t *portIndex, bool mandatory);
-static bool GetI2SAlignment(mxml_node_t *element, Ucs_Stream_PortDataAlign_t *align, bool mandatory);
-static bool GetDirection(mxml_node_t *element, Ucs_SocketDirection_t *out);
-static bool GetDataType(mxml_node_t *element, MData_t *out);
-static bool GetPort(mxml_node_t *element, MPort_t *out);
-static bool GetPayload(mxml_node_t *element, const char *name, uint8_t **pPayload, uint8_t *len,
- struct UcsXmlObjectList *obj, bool mandatory);
-static bool AddJob(Ucs_Xrm_ResObject_t **joblist, Ucs_Xrm_ResObject_t *job);
-static void AddRoute(struct UcsXmlRouteInfo **pRtLst, struct UcsXmlRouteInfo *route);
-static void AddScript(struct UcsXmlScriptInfo **pScrLst, struct UcsXmlScriptInfo *script);
-static ParseResult_t ParseAll(mxml_node_t *tree, UcsXmlVal_t *v, PrivateData_t *vp);
-static ParseResult_t ParseDevice(mxml_node_t * dev, PrivateData_t *vp);
-static ParseResult_t ParseChannel(mxml_node_t * ch, PrivateData_t *vp);
-static ParseResult_t ParseSocket(mxml_node_t *soc, PrivateData_t *vp);
-static ParseResult_t ParseMostSoc(Ucs_Xrm_MostSocket_t *mostSoc, mxml_node_t *soc, PrivateData_t *vp);
-static ParseResult_t ParseUsbSoc(Ucs_Xrm_UsbSocket_t *usbSoc, mxml_node_t *soc, PrivateData_t *vp);
-static ParseResult_t ParseMlbSoc(Ucs_Xrm_MlbSocket_t *mlbSoc, mxml_node_t *soc, PrivateData_t *vp);
-static ParseResult_t ParseStreamSoc(Ucs_Xrm_StrmSocket_t *strmSoc, mxml_node_t *soc, PrivateData_t *vp);
-static ParseResult_t ParseScript(mxml_node_t *scr, PrivateData_t *vp);
-static ParseResult_t ParseScriptAction(mxml_node_t *act, Ucs_Rm_Node_t *n, uint32_t index, PrivateData_t *vp);
-static ParseResult_t ParseRoutes(UcsXmlVal_t *v, PrivateData_t *vp);
-
-/************************************************************************/
-/* Public Functions */
-/************************************************************************/
-
-UcsXmlVal_t *UcsXml_Parse(const char *xmlString)
-{
- UcsXmlVal_t *v = NULL;
- ParseResult_t result = Parse_Success;
- mxml_node_t *tree = mxmlLoadString(NULL, xmlString, MXML_NO_CALLBACK);
- if (!tree)
- {
- result = Parse_XmlError;
- }
- if (Parse_Success == result)
- {
- if (!GetElement(tree, UNICENS, true, &tree, true))
- result = Parse_XmlError;
- }
- if (Parse_Success == result)
- {
- //Do not use MCalloc for the root element
- v = calloc(1, sizeof(UcsXmlVal_t));
- if (NULL == v) result = Parse_MemoryError;
- }
- if (Parse_Success == result)
- {
- //Do not use MCalloc for the private data
- v->pInternal = calloc(1, sizeof(PrivateData_t));
- if (NULL == v->pInternal) result = Parse_MemoryError;
- }
- if (Parse_Success == result)
- {
- result = ParseAll(tree, v, v->pInternal);
- }
- if (!tree)
- {
- mxmlDelete(tree);
- }
- if (Parse_Success == result)
- {
- return v;
- }
- if (Parse_MemoryError == result)
- {
- UcsXml_CB_OnError("XML error, aborting..", 0);
- }
- else
- {
- UcsXml_CB_OnError("Alloc error, aborting..", 0);
- }
- assert(false);
- FreeVal(v);
- return NULL;
-}
-
-void UcsXml_FreeVal(UcsXmlVal_t *val)
-{
- FreeVal(val);
-}
-
-/************************************************************************/
-/* Private Function Implementations */
-/************************************************************************/
-
-static 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;
-}
-
-static 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;
- }
-}
-
-static void FreeVal(UcsXmlVal_t *v)
-{
- PrivateData_t *vp;
- if (NULL == v || NULL == v->pInternal)
- return;
- vp = v->pInternal;
- FreeObjList(&vp->objList);
- free(v->pInternal);
- free(v);
-}
-
-static bool GetElement(mxml_node_t *element, const char *name, bool goDeep, mxml_node_t **out, bool mandatory)
-{
- mxml_node_t *n = element;
- if (NULL == n || NULL == name || NULL == out) return false;
- if (goDeep)
- {
- *out = mxmlFindElement(n, n, name, NULL, NULL, MXML_DESCEND);
- return (NULL != *out);
- }
- while ((n = n->next))
- {
- if (MXML_ELEMENT != n->type)
- continue;
- if (0 == strcmp(name, n->value.opaque))
- {
- *out = n;
- return true;
- }
- }
- if (mandatory)
- UcsXml_CB_OnError("Can not find tag <%s>", 1, name);
- return false;
-}
-
-static bool GetCount(mxml_node_t *element, const char *name, uint32_t *out, bool mandatory)
-{
- uint32_t cnt = 0;
- mxml_node_t *n;
- if (NULL == element || NULL == name) return false;
- if(!GetElement(element, name, true, &n, false))
- return false;
- while(NULL != n)
- {
- ++cnt;
- if(!GetElement(n, name, false, &n, false))
- break;
- }
- if (mandatory && 0 == cnt)
- {
- UcsXml_CB_OnError("element count of <%s> is zero", 1, name);
- return false;
- }
- *out = cnt;
- return true;
-}
-
-static bool GetString(mxml_node_t *element, const char *key, const char **out, bool mandatory)
-{
- uint32_t i;
- if (NULL == element || NULL == key) return false;
- for (i = 0; i < element->value.element.num_attrs; i++)
- {
- mxml_attr_t *attr = &element->value.element.attrs[i];
- if (0 == strcmp(key, attr->name))
- {
- *out = attr->value;
- return true;
- }
- }
- if (mandatory)
- UcsXml_CB_OnError("Can not find attribute='%s' from element <%s>",
- 2, key, element->value.element.name);
- return false;
-}
-
-static bool GetUInt16(mxml_node_t *element, const char *key, uint16_t *out, bool mandatory)
-{
- const char* txt;
- if (!GetString(element, key, &txt, mandatory)) return false;
- *out = strtol( txt, NULL, 0 );
- return true;
-}
-
-static bool GetUInt8(mxml_node_t *element, const char *key, uint8_t *out, bool mandatory)
-{
- const char* txt;
- if (!GetString(element, key, &txt, mandatory)) return false;
- *out = strtol( txt, NULL, 0 );
- return true;
-}
-
-static bool GetMlbSpeed(mxml_node_t *element, const char *key, Ucs_Mlb_ClockConfig_t *clock, bool mandatory)
-{
- uint16_t speed;
- if (!GetUInt16(element, DEVICE_MLB_SPEED, &speed, false))
- return false;
- switch(speed)
- {
- case 256: *clock = UCS_MLB_CLK_CFG_256_FS; break;
- case 512: *clock = UCS_MLB_CLK_CFG_512_FS; break;
- case 1024: *clock = UCS_MLB_CLK_CFG_1024_FS; break;
- case 2048: *clock = UCS_MLB_CLK_CFG_2048_FS; break;
- case 3072: *clock = UCS_MLB_CLK_CFG_3072_FS; break;
- case 4096: *clock = UCS_MLB_CLK_CFG_4096_FS; break;
- case 6144: *clock = UCS_MLB_CLK_CFG_6144_FS; break;
- case 8192: *clock = UCS_MLB_CLK_CFG_8192_FS; break;
- case 0: *clock = UCS_MLB_CLK_CFG_WILDCARD; break;
- default:
- UcsXml_CB_OnError("Invalid MLB clock val:'%d'", 1, clock);
- return false;
- }
- return true;
-}
-
-static bool GetI2SSpeed(mxml_node_t *element, const char *key, Ucs_Stream_PortClockConfig_t *clock, bool mandatory)
-{
- uint16_t speed;
- if (!GetUInt16(element, I2S_FS_SPEED, &speed, false))
- return false;
- switch(speed)
- {
- case 8: *clock = UCS_STREAM_PORT_CLK_CFG_8FS; break;
- case 16: *clock = UCS_STREAM_PORT_CLK_CFG_16FS; break;
- case 32: *clock = UCS_STREAM_PORT_CLK_CFG_32FS; break;
- case 64: *clock = UCS_STREAM_PORT_CLK_CFG_64FS; break;
- case 128: *clock = UCS_STREAM_PORT_CLK_CFG_128FS; break;
- case 256: *clock = UCS_STREAM_PORT_CLK_CFG_256FS; break;
- case 512: *clock = UCS_STREAM_PORT_CLK_CFG_512FS; break;
- case 0: *clock = UCS_MLB_CLK_CFG_WILDCARD; break;
- default:
- UcsXml_CB_OnError("Invalid I2S clock val:'%d'", 1, clock);
- return false;
- }
- return true;
-}
-
-static bool GetI2SPin(mxml_node_t *element, Ucs_Stream_PortPinId_t *pin, uint8_t *portIndex, bool mandatory)
-{
- const char *txt;
- if (!GetString(element, I2S_PIN, &txt, true))
- return false;
- if (0 == strcmp(I2S_PIN_SRXA0, txt))
- {
- *pin = UCS_STREAM_PORT_PIN_ID_SRXA0;
- *portIndex = 0;
- return true;
- }
- else if (0 == strcmp(I2S_PIN_SRXA1, txt))
- {
- *pin = UCS_STREAM_PORT_PIN_ID_SRXA1;
- *portIndex = 0;
- return true;
- }
- else if (0 == strcmp(I2S_PIN_SRXB0, txt))
- {
- *pin = UCS_STREAM_PORT_PIN_ID_SRXB0;
- *portIndex = 1;
- return true;
- }
- else if (0 == strcmp(I2S_PIN_SRXB1, txt))
- {
- *pin = UCS_STREAM_PORT_PIN_ID_SRXB1;
- *portIndex = 1;
- return true;
- }
- UcsXml_CB_OnError("Invalid I2S pin val:'%s'", 1, txt);
- return false;
-}
-
-static bool GetI2SAlignment(mxml_node_t *element, Ucs_Stream_PortDataAlign_t *align, bool mandatory)
-{
- const char *txt;
- if (!GetString(element, I2S_ALIGN, &txt, true))
- return false;
- if (0 == strcmp(I2S_ALIGN_L16, txt))
- *align = UCS_STREAM_PORT_ALGN_LEFT16BIT;
- else if (0 == strcmp(I2S_ALIGN_L24, txt))
- *align = UCS_STREAM_PORT_ALGN_LEFT24BIT;
- else if (0 == strcmp(I2S_ALIGN_R16, txt))
- *align = UCS_STREAM_PORT_ALGN_RIGHT16BIT;
- else if (0 == strcmp(I2S_ALIGN_R24, txt))
- *align = UCS_STREAM_PORT_ALGN_RIGHT24BIT;
- else if (0 == strcmp(I2S_ALIGN_SEQUENTIAL, txt))
- *align = UCS_STREAM_PORT_ALGN_SEQ;
- else
- {
- UcsXml_CB_OnError("Invalid I2S alignment:'%s'", 1, txt);
- return false;
- }
- return true;
-}
-
-static bool GetDirection(mxml_node_t *element, Ucs_SocketDirection_t *out)
-{
- const char *txt;
- if (!GetString(element, DIR, &txt, true)) return false;
- if (0 == strcmp(DIR_IN, txt))
- *out = UCS_SOCKET_DIR_INPUT;
- else if (0 == strcmp(DIR_OUT, txt))
- *out = UCS_SOCKET_DIR_OUTPUT;
- else
- return false;
- return true;
-}
-
-static bool GetDataType(mxml_node_t *element, MData_t *out)
-{
- const char *txt;
- if (!GetString(element, DATA_TYPE, &txt, true)) return false;
- if (0 == strcmp(DATATYPE_SYNC, txt)) {
- *out = SYNC_DATA;
- } else if (0 == strcmp(DATATYPE_CTRL, txt)) {
- *out = CONTROL_DATA;
- } else if (0 == strcmp(DATATYPE_AVP, txt)) {
- *out = AV_PACKETIZED;
- } else if (0 == strcmp(DATATYPE_QOS, txt)) {
- *out = QOS_IP;
- } else if (0 == strcmp(DATATYPE_DFP, txt)) {
- *out = DISC_FRAME_PHASE;
- } else if (0 == strcmp(DATATYPE_IPC, txt)) {
- *out = IPC_PACKET;
- } else {
- UcsXml_CB_OnError("Unknown data type : '%s'", 1, txt);
- return false;
- }
- return true;
-}
-
-static bool GetPort(mxml_node_t *element, MPort_t *out)
-{
- const char *txt;
- if (!GetString(element, PORT, &txt, true)) return false;
- if (0 == strcmp(txt, PORT_MOST)) {
- *out = MPORT_MOST;
- } else if (0 == strcmp(txt, PORT_USB)) {
- *out = MPORT_USB;
- } else if (0 == strcmp(txt, PORT_MLB)) {
- *out = MPORT_MLB;
- } else if (0 == strcmp(txt, PORT_I2S)) {
- *out = MPORT_I2S;
- } else {
- UcsXml_CB_OnError("Unknown port : '%s'", 1, txt);
- return false;
- }
- return true;
-}
-
-static bool GetPayload(mxml_node_t *element, const char *name, uint8_t **pPayload, uint8_t *outLen, struct UcsXmlObjectList *obj, bool mandatory)
-{
- uint32_t tempLen, len = 0;
- uint8_t *p;
- const char *txt;
- char *txtCopy;
- char *tkPtr;
- char *token;
- if (!GetString(element, name, &txt, mandatory))
- return false;
- tempLen = strlen(txt) + 1;
- txtCopy = malloc(tempLen);
- if (NULL == txtCopy)
- return false;
- strncpy(txtCopy, txt, tempLen);
- tempLen = tempLen / 3; /* 2 chars hex value plus space (AA ) */
- p = MCalloc(obj, tempLen, 1);
- if (NULL == p)
- {
- free(txtCopy);
- return false;
- }
- *pPayload = p;
- token = strtok_r( txtCopy, " ,.-", &tkPtr );
- while( NULL != token )
- {
- if( len >= tempLen )
- {
- UcsXml_CB_OnError("Script payload values must be stuffed to two characters", 0);
- free(txtCopy);
- assert(false);
- return 0;
- }
- p[len++] = strtol( token, NULL, 16 );
- token = strtok_r( NULL, " ,.-", &tkPtr );
- }
- *outLen = len;
- return true;
-}
-
-static bool AddJob(Ucs_Xrm_ResObject_t **joblist, Ucs_Xrm_ResObject_t *job)
-{
- uint32_t i;
- if (NULL == joblist || NULL == job)
- {
- assert(false);
- return false;
- }
- for (i = 0; i < MAX_JOB_LIST_LEN; i++)
- {
- if (NULL == joblist[i])
- {
- joblist[i] = job;
- return true;
- }
- }
- assert(false);
- return false;
-}
-
-static void AddRoute(struct UcsXmlRouteInfo **pRtLst, struct UcsXmlRouteInfo *route)
-{
- struct UcsXmlRouteInfo *tail;
- if (NULL == pRtLst || NULL == route) return;
- if (NULL == pRtLst[0])
- {
- pRtLst[0] = route;
- return;
- }
- tail = pRtLst[0];
- while(tail->next) tail = tail->next;
- tail->next = route;
-}
-
-static void AddScript(struct UcsXmlScriptInfo **pScrLst, struct UcsXmlScriptInfo *script)
-{
- struct UcsXmlScriptInfo *tail;
- if (NULL == pScrLst || NULL == script) return;
- if (NULL == pScrLst[0])
- {
- pScrLst[0] = script;
- return;
- }
- tail = pScrLst[0];
- while(tail->next) tail = tail->next;
- tail->next = script;
-}
-
-static ParseResult_t ParseAll(mxml_node_t *tree, UcsXmlVal_t *v, PrivateData_t *vp)
-{
- uint32_t devCount;
- mxml_node_t *sub;
- ParseResult_t result;
- if (!GetCount(tree, DEVICE, &devCount, true))
- return Parse_XmlError;
-
- v->pNod = MCalloc(&vp->objList, devCount, sizeof(Ucs_Rm_Node_t));
- if (NULL == v->pNod) return Parse_MemoryError;
-
- if (!GetUInt16(tree, ASYNC_BANDWIDTH, &v->packetBw, true))
- return Parse_XmlError;
-
- ///Iterate all devices
- if (!GetElement(tree, DEVICE, true, &sub, true))
- return Parse_XmlError;
- while(sub)
- {
- mxml_node_t *ch;
- vp->nod = &v->pNod[v->nodSize];
- if (Parse_Success != (result = ParseDevice(sub, vp)))
- return result;
- ///Iterate all channels. Device without any channel is also valid.
- if (GetElement(sub->child, CHANNEL, false, &ch, false))
- {
- while(ch)
- {
- mxml_node_t *soc;
- uint8_t sockCnt = 0;
- if (Parse_Success != (result = ParseChannel(ch, vp)))
- return result;
- ///Iterate all sockets
- if(!GetElement(ch->child, SOCKET, false, &soc, true))
- return Parse_XmlError;
- while(soc)
- {
- ParseResult_t result;
- if (Parse_Success != (result = ParseSocket(soc, vp)))
- return result;
- ++sockCnt;
- if (!GetElement(soc, SOCKET, false, &soc, false))
- break;
- }
- if (2 != sockCnt)
- {
- UcsXml_CB_OnError("%d sockets per channel found, must be 2", 1, sockCnt);
- return Parse_XmlError;
- }
- if (!GetElement(ch, CHANNEL, false, &ch, false))
- break;
- }
- }
- ++v->nodSize;
- if (!GetElement(sub, DEVICE, false, &sub, false))
- break;
- }
-
- ///Fill route structures
- result = ParseRoutes(v, vp);
- if (Parse_MemoryError == result) return Parse_MemoryError;
- else if (Parse_XmlError == result) return Parse_XmlError;
-
- ///Iterate all scripts. No scripts at all is allowed
- if(GetElement(tree, SCRIPT, true, &sub, false))
- {
- while(sub)
- {
- ParseResult_t result = ParseScript(sub, vp);
- if (Parse_MemoryError == result) return Parse_MemoryError;
- else if (Parse_XmlError == result) return Parse_XmlError;
- if(!GetElement(sub, SCRIPT, false, &sub, false))
- break;
- }
- }
- return result;
-}
-
-static ParseResult_t ParseDevice(mxml_node_t * dev, PrivateData_t *vp)
-{
- const char *txt;
- assert(NULL != dev && NULL != vp);
- vp->nod->signature_ptr = MCalloc(&vp->objList, 1, sizeof(Ucs_Signature_t));
- if(NULL == vp->nod->signature_ptr) return Parse_MemoryError;
- if (!GetUInt16(dev, NODE_ADDR, &vp->nod->signature_ptr->node_address, true))
- return Parse_XmlError;
- if (GetString(dev, SCRIPT, &txt, false))
- {
- struct UcsXmlScriptInfo *scr = MCalloc(&vp->objList, 1, sizeof(struct UcsXmlScriptInfo));
- if (NULL == scr) return Parse_MemoryError;
- scr->node = vp->nod;
- strncpy(scr->scriptName, txt, sizeof(scr->scriptName));
- AddScript(&vp->pScrLst, scr);
- }
- return Parse_Success;;
-}
-
-static ParseResult_t ParseChannel(mxml_node_t *ch, PrivateData_t *vp)
-{
- vp->inSocket = NULL;
- vp->outSocket = NULL;
- vp->jobList = NULL;
- vp->dataType = 0xFF;
- vp->blockWidth = 0;
- vp->chName = NULL;
- assert(NULL != ch && NULL != vp);
- if (!GetString(ch, CHANNEL_NAME, &vp->chName, true))
- return Parse_XmlError;
- if (!GetDataType(ch, &vp->dataType))
- return Parse_XmlError;
- if (!GetUInt16(ch, BANDWIDTH, &vp->blockWidth, true))
- return Parse_XmlError;
- vp->jobList = MCalloc(&vp->objList, MAX_JOB_LIST_LEN, sizeof(Ucs_Xrm_ResObject_t *));
- if (NULL == vp->jobList) return Parse_MemoryError;
- return Parse_Success;
-}
-
-static ParseResult_t ParseSocket(mxml_node_t *soc, PrivateData_t *vp)
-{
- MPort_t port;
- bool isIn = false;
- bool isSource = false;
- uint16_t offset = 0;
- assert(NULL != soc && NULL != vp);
- Ucs_SocketDirection_t direction;
- if (!GetDirection(soc, &direction))
- return Parse_XmlError;
- isIn = (UCS_SOCKET_DIR_INPUT == direction);
- if (!GetPort(soc, &port))
- return Parse_XmlError;
- switch(port)
- {
- case MPORT_MOST:
- {
- Ucs_Xrm_MostSocket_t *sock = MCalloc(&vp->objList, 1, sizeof(Ucs_Xrm_MostSocket_t));
- if (NULL == sock) return Parse_MemoryError;
- if (!AddJob(vp->jobList, sock)) return Parse_XmlError;
- sock->data_type = vp->dataType;
- sock->bandwidth = vp->blockWidth;
- if (Parse_Success != ParseMostSoc(sock, soc, vp))
- return Parse_XmlError;
- isSource = (UCS_SOCKET_DIR_OUTPUT == direction);
- if (isIn) vp->inSocket = sock; else vp->outSocket = sock;
- break;
- }
- case MPORT_USB:
- {
- Ucs_Xrm_UsbSocket_t *sock = MCalloc(&vp->objList, 1, sizeof(Ucs_Xrm_UsbSocket_t));
- if (NULL == sock) return Parse_MemoryError;
- if (!AddJob(vp->jobList, sock)) return Parse_XmlError;
- sock->data_type = vp->dataType;
- if (Parse_Success != ParseUsbSoc(sock, soc, vp))
- return Parse_XmlError;
- if (isIn) vp->inSocket = sock; else vp->outSocket = sock;
- break;
- }
- case MPORT_MLB:
- {
- Ucs_Xrm_MlbSocket_t *sock = MCalloc(&vp->objList, 1, sizeof(Ucs_Xrm_MlbSocket_t));
- if (NULL == sock) return Parse_MemoryError;
- if (!AddJob(vp->jobList, sock)) return Parse_XmlError;
- sock->data_type = vp->dataType;
- sock->bandwidth = vp->blockWidth;
- if (Parse_Success != ParseMlbSoc(sock, soc, vp))
- return Parse_XmlError;
- if (isIn) vp->inSocket = sock; else vp->outSocket = sock;
- break;
- }
- case MPORT_I2S:
- {
- Ucs_Xrm_StrmSocket_t *sock = MCalloc(&vp->objList, 1, sizeof(Ucs_Xrm_StrmSocket_t));
- if (NULL == sock) return Parse_MemoryError;
- sock->data_type = vp->dataType;
- sock->bandwidth = vp->blockWidth;
- if (Parse_Success != ParseStreamSoc(sock, soc, vp))
- return Parse_XmlError;
- if (isIn) vp->inSocket = sock; else vp->outSocket = sock;
- break;
- }
- default:
- assert(false);
- return Parse_XmlError;
- }
- if (GetUInt16(soc, OFFSET, &offset, false))
- {
- //TODO: If offset is non zero allocate Splitter / Combiner
- }
- //Connect in and out socket once they are created
- if (vp->inSocket && vp->outSocket)
- {
- switch(vp->dataType)
- {
- case AV_PACKETIZED:
- {
- Ucs_Xrm_AvpCon_t *con = MCalloc(&vp->objList, 1, sizeof(Ucs_Xrm_AvpCon_t));
- if (NULL == con) return Parse_MemoryError;
- if (!AddJob(vp->jobList, con))
- return Parse_XmlError;
- con->resource_type = UCS_XRM_RC_TYPE_AVP_CON;
- con->socket_in_obj_ptr = vp->inSocket;
- con->socket_out_obj_ptr = vp->outSocket;
- con->isoc_packet_size = UCS_ISOC_PCKT_SIZE_188; //TODO:Read from XML
- break;
- }
- case SYNC_DATA:
- {
- Ucs_Xrm_SyncCon_t *con = MCalloc(&vp->objList, 1, sizeof(Ucs_Xrm_SyncCon_t));
- if (NULL == con) return Parse_MemoryError;
- if (!AddJob(vp->jobList, con))
- return Parse_XmlError;
- con->resource_type = UCS_XRM_RC_TYPE_SYNC_CON;
- con->socket_in_obj_ptr = vp->inSocket;
- con->socket_out_obj_ptr = vp->outSocket;
- con->mute_mode = UCS_SYNC_MUTE_MODE_NO_MUTING; //TODO:Read from XML
- con->offset = offset;
- break;
- }
- default:
- UcsXml_CB_OnError("Could not connect sockets, data type not implemented: %d", 1, vp->dataType);
- return Parse_XmlError;
- break;
- }
- Ucs_Rm_EndPoint_t *ep = MCalloc(&vp->objList, 1, sizeof(Ucs_Rm_EndPoint_t));
- if (NULL == ep) return Parse_MemoryError;
- ep->endpoint_type = isSource ? UCS_RM_EP_SOURCE : UCS_RM_EP_SINK;
- ep->jobs_list_ptr = vp->jobList;
- ep->node_obj_ptr = vp->nod;
-
- struct UcsXmlRouteInfo *route = MCalloc(&vp->objList, 1, sizeof(struct UcsXmlRouteInfo));
- if (NULL == route) return Parse_MemoryError;
- route->isSource = isSource;
- route->ep = ep;
- strncpy(route->routeName, vp->chName, sizeof(route->routeName));
- AddRoute(&vp->pRtLst, route);
- }
- return Parse_Success;
-}
-
-static ParseResult_t ParseMostSoc(Ucs_Xrm_MostSocket_t *mostSoc, mxml_node_t *soc, PrivateData_t *vp)
-{
- assert(NULL != mostSoc && NULL != soc && NULL != vp);
- COMPILETIME_CHECK(SYNC_DATA == (MData_t)UCS_MOST_SCKT_SYNC_DATA);
- COMPILETIME_CHECK(AV_PACKETIZED == (MData_t)UCS_MOST_SCKT_AV_PACKETIZED);
- COMPILETIME_CHECK(QOS_IP == (MData_t)UCS_MOST_SCKT_QOS_IP);
- COMPILETIME_CHECK(DISC_FRAME_PHASE == (MData_t)UCS_MOST_SCKT_DISC_FRAME_PHASE);
- switch((MData_t)mostSoc->data_type)
- {
- case SYNC_DATA:
- case AV_PACKETIZED:
- case QOS_IP:
- case DISC_FRAME_PHASE:
- break; //Nothing to do, valid values.
- default:
- UcsXml_CB_OnError("Invalid DataType=%d for MOST socket", 1, mostSoc->data_type);
- return Parse_XmlError;
- }
- mostSoc->resource_type = UCS_XRM_RC_TYPE_MOST_SOCKET;
- mostSoc->most_port_handle = 0x0D00;
- if (!GetDirection(soc, &mostSoc->direction))
- return Parse_XmlError;
- return Parse_Success;
-}
-
-static ParseResult_t ParseUsbSoc(Ucs_Xrm_UsbSocket_t *usbSoc, mxml_node_t *soc, PrivateData_t *vp)
-{
- Ucs_Xrm_DefaultCreatedPort_t *p;
- assert(NULL != usbSoc && NULL != soc && NULL != vp);
- COMPILETIME_CHECK(SYNC_DATA == (MData_t)UCS_USB_SCKT_SYNC_DATA);
- COMPILETIME_CHECK(CONTROL_DATA == (MData_t)UCS_USB_SCKT_CONTROL_DATA);
- COMPILETIME_CHECK(AV_PACKETIZED == (MData_t)UCS_USB_SCKT_AV_PACKETIZED);
- switch((MData_t)usbSoc->data_type)
- {
- case SYNC_DATA:
- case CONTROL_DATA:
- case AV_PACKETIZED:
- break; //Nothing to do, valid values.
- default:
- UcsXml_CB_OnError("Invalid DataType=%d for USB socket", 1, usbSoc->data_type);
- return Parse_XmlError;
- }
- usbSoc->resource_type = UCS_XRM_RC_TYPE_USB_SOCKET;
- if (!GetDirection(soc, &usbSoc->direction))
- return Parse_XmlError;
- if (!GetUInt8(soc, ADDRESS, &usbSoc->end_point_addr, true))
- return Parse_XmlError;
-
- if (!GetUInt16(soc, PACKETS_XACT, &usbSoc->frames_per_transfer, true))
- return Parse_XmlError;
-
- //XML provides currently no way to open USB port, so use ConfigString default
- p = MCalloc(&vp->objList, 1, sizeof(Ucs_Xrm_DefaultCreatedPort_t));
- if (NULL == p) return Parse_MemoryError;
- if (!AddJob(vp->jobList, p)) return Parse_MemoryError;
- p->resource_type = UCS_XRM_RC_TYPE_DC_PORT;
- p->port_type = UCS_XRM_PORT_TYPE_USB;
- p->index = 0;
- usbSoc->usb_port_obj_ptr = p;
- return Parse_Success;
-}
-
-static ParseResult_t ParseMlbSoc(Ucs_Xrm_MlbSocket_t *mlbSoc, mxml_node_t *soc, PrivateData_t *vp)
-{
- Ucs_Mlb_ClockConfig_t clock;
- assert(NULL != mlbSoc && NULL != soc && NULL != vp);
- COMPILETIME_CHECK(SYNC_DATA == (MData_t)UCS_MLB_SCKT_SYNC_DATA);
- COMPILETIME_CHECK(CONTROL_DATA == (MData_t)UCS_MLB_SCKT_CONTROL_DATA);
- COMPILETIME_CHECK(AV_PACKETIZED == (MData_t)UCS_USB_SCKT_AV_PACKETIZED);
- COMPILETIME_CHECK(QOS_IP == (MData_t)UCS_MLB_SCKT_QOS_IP);
- COMPILETIME_CHECK(DISC_FRAME_PHASE == (MData_t)UCS_MLB_SCKT_DISC_FRAME_PHASE);
- COMPILETIME_CHECK(IPC_PACKET == (MData_t)UCS_MLB_SCKT_IPC_PACKET);
- switch((MData_t)mlbSoc->data_type)
- {
- case SYNC_DATA:
- case CONTROL_DATA:
- case AV_PACKETIZED:
- case QOS_IP:
- case DISC_FRAME_PHASE:
- case IPC_PACKET:
- break; //Nothing to do, valid values.
- default:
- UcsXml_CB_OnError("Invalid DataType=%d for MLB socket", 1, mlbSoc->data_type);
- return Parse_XmlError;
- }
- mlbSoc->resource_type = UCS_XRM_RC_TYPE_MLB_SOCKET;
- if (!GetDirection(soc, &mlbSoc->direction))
- return Parse_XmlError;
- if (!GetUInt16(soc, ADDRESS, &mlbSoc->channel_address, true))
- return Parse_XmlError;
-
- //Create MLB port when DEVICE_MLB_SPEED is defined, otherwise use ConfigString default
- if (GetMlbSpeed(soc, DEVICE_MLB_SPEED, &clock, false))
- {
- Ucs_Xrm_MlbPort_t *p = MCalloc(&vp->objList, 1, sizeof(Ucs_Xrm_MlbPort_t));
- if (NULL == p) return Parse_MemoryError;
- if (!AddJob(vp->jobList, p)) return Parse_MemoryError;
- p->resource_type = UCS_XRM_RC_TYPE_MLB_PORT;
- p->index = 0;
- p->clock_config = clock;
- mlbSoc->mlb_port_obj_ptr = p;
- } else {
- Ucs_Xrm_DefaultCreatedPort_t *p = MCalloc(&vp->objList, 1, sizeof(Ucs_Xrm_DefaultCreatedPort_t));
- if (NULL == p) return Parse_MemoryError;
- if (!AddJob(vp->jobList, p)) return Parse_MemoryError;
- p->resource_type = UCS_XRM_RC_TYPE_DC_PORT;
- p->port_type = UCS_XRM_PORT_TYPE_MLB;
- p->index = 0;
- mlbSoc->mlb_port_obj_ptr = p;
- }
- return Parse_Success;
-}
-
-static ParseResult_t ParseStreamSoc(Ucs_Xrm_StrmSocket_t *strmSoc, mxml_node_t *soc, PrivateData_t *vp)
-{
- const char *txt;
- Ucs_Xrm_StrmPort_t *strPort;
- assert(NULL != strmSoc && NULL != soc && NULL != vp);
- COMPILETIME_CHECK(SYNC_DATA == (MData_t)UCS_STREAM_PORT_SCKT_SYNC_DATA);
- if (SYNC_DATA != (MData_t)strmSoc->data_type)
- {
- UcsXml_CB_OnError("Invalid DataType=%d for I2S socket", 1, strmSoc->data_type);
- return Parse_XmlError;
- }
- strPort = MCalloc(&vp->objList, 1, sizeof(Ucs_Xrm_StrmPort_t));
- if (NULL == strPort) return Parse_MemoryError;
- if (!AddJob(vp->jobList, strPort)) return Parse_MemoryError;
- if (!AddJob(vp->jobList, strmSoc)) return Parse_MemoryError;
- strmSoc->resource_type = UCS_XRM_RC_TYPE_STRM_SOCKET;
- strmSoc->stream_port_obj_ptr = strPort;
-
- strPort->resource_type = UCS_XRM_RC_TYPE_STRM_PORT;
- if (!GetDirection(soc, &strmSoc->direction))
- return Parse_XmlError;
- if (!GetI2SPin(soc, &strmSoc->stream_pin_id, &strPort->index, true))
- return Parse_XmlError;
- if (!GetI2SSpeed(soc, I2S_FS_SPEED, &strPort->clock_config, true))
- return Parse_XmlError;
- if (!GetString(soc, I2S_ALIGN, &txt, true))
- return Parse_XmlError;
- if (!GetI2SAlignment(soc, &strPort->data_alignment, true))
- return Parse_XmlError;
- return Parse_Success;
-}
-
-static ParseResult_t ParseScript(mxml_node_t *scr, PrivateData_t *vp)
-{
- mxml_node_t *act;
- uint32_t actCnt;
- uint32_t i = 0;
- const char *txt;
- assert(NULL != scr && NULL != vp);
- vp->pause = 0;
- if (!GetString(scr, NAME, &txt, true))
- return Parse_XmlError;
- Ucs_Rm_Node_t *n = NULL;
- struct UcsXmlScriptInfo *scrlist = vp->pScrLst;
- while(NULL != scrlist)
- {
- if (0 == strcmp(txt, scrlist->scriptName))
- {
- n = scrlist->node;
- break;
- }
- scrlist = scrlist->next;
- }
- if (NULL == n)
- {
- UcsXml_CB_OnError("Script defined:'%s', which was never referenced", 1, txt);
- return Parse_XmlError;
- }
- if (!GetCount(scr, ACTION, &actCnt, true)) return Parse_XmlError;
- if (NULL == (n->script_list_ptr = MCalloc(&vp->objList, actCnt, sizeof(Ucs_Ns_Script_t))))
- return Parse_MemoryError;
- n->script_list_size = actCnt;
- ///Iterate all actions
- if (!GetElement(scr, ACTION, true, &act, true)) return false;
- while(act)
- {
- ParseResult_t result = ParseScriptAction(act, n, i, vp);
- if (Parse_Success != result) return result;
- if (!GetElement(act, ACTION, false, &act, false))
- break;
- ++i;
- }
- return Parse_Success;
-}
-
-static ParseResult_t ParseScriptAction(mxml_node_t *act, Ucs_Rm_Node_t *n, uint32_t index, PrivateData_t *vp)
-{
- const char *txt;
- uint8_t opResult;
- assert(NULL != act && NULL != vp);
- Ucs_Ns_Script_t *scr = &n->script_list_ptr[index];
- if (!GetString(act, TYPE, &txt, true))
- return Parse_XmlError;
- if (0 == strcmp(txt, SEND_MSG))
- {
- Ucs_Ns_ConfigMsg_t *req;
- scr->send_cmd = MCalloc(&vp->objList, 1, sizeof(Ucs_Ns_ConfigMsg_t));
- req = scr->send_cmd;
- if (NULL == req) return Parse_MemoryError;
- scr->pause = vp->pause;
- if (vp->pause) vp->pause = 0;
- req->InstId = 1;
- if (!GetUInt8(act, FBLOCK_ID, &req->FBlockId, true))
- return Parse_XmlError;
-
- if (!GetUInt16(act, FUNCTION_ID, &req->FunktId, true))
- return Parse_XmlError;
-
- if (!GetUInt8(act, OP_TYPE_REQUEST, &req->OpCode, true))
- return Parse_XmlError;
-
- if (GetUInt8(act, OP_TYPE_RESPONSE, &opResult, false))
- {
- //Waiting for response is optional
- Ucs_Ns_ConfigMsg_t *res;
- scr->exp_result = MCalloc(&vp->objList, 1, sizeof(Ucs_Ns_ConfigMsg_t));
- res = scr->exp_result;
- res->FBlockId = req->FBlockId;
- res->InstId = req->InstId;
- res->FunktId = req->FunktId;
- res->OpCode = opResult;
- //Not interested in result:
- GetPayload(act, PAYLOAD_RES_HEX, &res->DataPtr, &res->DataLen, &vp->objList, false);
- }
- if (!GetPayload(act, PAYLOAD_REQ_HEX, &req->DataPtr, &req->DataLen, &vp->objList, true))
- return Parse_XmlError;
- if (0 == req->DataLen || NULL == req->DataPtr)
- return Parse_XmlError;
- }
- else if (0 == strcmp(txt, PAUSE))
- {
- if (!GetUInt16(act, PAUSE_MS, &vp->pause, true))
- return Parse_XmlError;
- }
- return Parse_Success;
-}
-
-static ParseResult_t ParseRoutes(UcsXmlVal_t *v, PrivateData_t *vp)
-{
- uint16_t routeAmount = 0;
- struct UcsXmlRouteInfo *sourceRoute;
- assert(NULL != v && NULL != vp);
- //First: Count the amount of routes and allocate the correct amount
- sourceRoute = vp->pRtLst;
- while (NULL != sourceRoute)
- {
- if (!sourceRoute->isSource) //There can be more sinks than sources, so count them
- {
- ++routeAmount;
- }
- sourceRoute = sourceRoute->next;
- }
- if (0 == routeAmount)
- return Parse_Success; //Its okay to have no routes at all (e.g. MEP traffic only)
- v->pRoutes = MCalloc(&vp->objList, routeAmount, sizeof(Ucs_Rm_Route_t));
- if (NULL == v->pRoutes) return Parse_MemoryError;
-
- //Second: Fill allocated structure now
- sourceRoute = vp->pRtLst;
- while (NULL != sourceRoute)
- {
- if (sourceRoute->isSource)
- {
- struct UcsXmlRouteInfo *sinkRoute = vp->pRtLst;
- while (NULL != sinkRoute)
- {
- if (sourceRoute != sinkRoute
- && !sinkRoute->isSource
- && (0 == strncmp(sourceRoute->routeName, sinkRoute->routeName, sizeof(sourceRoute->routeName))))
- {
- Ucs_Rm_Route_t *route = &v->pRoutes[v->routesSize++];
- route->source_endpoint_ptr = sourceRoute->ep;
- route->sink_endpoint_ptr = sinkRoute->ep;
- route->active = 1;
- }
- sinkRoute = sinkRoute->next;
- }
- }
- sourceRoute = sourceRoute->next;
- }
- return Parse_Success;
-}
+/*------------------------------------------------------------------------------------------------*/\r
+/* Unicens XML Parser */\r
+/* Copyright 2017, Microchip Technology Inc. and its subsidiaries. */\r
+/* */\r
+/* Redistribution and use in source and binary forms, with or without */\r
+/* modification, are permitted provided that the following conditions are met: */\r
+/* */\r
+/* 1. Redistributions of source code must retain the above copyright notice, this */\r
+/* list of conditions and the following disclaimer. */\r
+/* */\r
+/* 2. Redistributions in binary form must reproduce the above copyright notice, */\r
+/* this list of conditions and the following disclaimer in the documentation */\r
+/* and/or other materials provided with the distribution. */\r
+/* */\r
+/* 3. Neither the name of the copyright holder nor the names of its */\r
+/* contributors may be used to endorse or promote products derived from */\r
+/* this software without specific prior written permission. */\r
+/* */\r
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" */\r
+/* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE */\r
+/* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */\r
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE */\r
+/* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL */\r
+/* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR */\r
+/* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */\r
+/* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, */\r
+/* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */\r
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */\r
+/*------------------------------------------------------------------------------------------------*/\r
+#include <assert.h>\r
+#include <string.h>\r
+#include "mxml.h"\r
+#include "UcsXml_Private.h"\r
+#include "UcsXml.h"\r
+\r
+/************************************************************************/\r
+/* PRIVATE DECLARATIONS */\r
+/************************************************************************/\r
+\r
+#define COMPILETIME_CHECK(cond) (void)sizeof(int[2 * !!(cond) - 1])\r
+#define RETURN_ASSERT(result) { assert(false); return result; }\r
+#define MISC_HB(value) ((uint8_t)((uint16_t)(value) >> 8))\r
+#define MISC_LB(value) ((uint8_t)((uint16_t)(value) & (uint16_t)0xFF))\r
+\r
+struct UcsXmlRoute\r
+{\r
+ bool isSource;\r
+ bool isActive;\r
+ uint16_t routeId;\r
+ char routeName[32];\r
+ Ucs_Rm_EndPoint_t *ep;\r
+ struct UcsXmlRoute *next;\r
+};\r
+\r
+struct UcsXmlScript\r
+{\r
+ char scriptName[32];\r
+ Ucs_Rm_Node_t *node;\r
+ struct UcsXmlScript *next;\r
+};\r
+\r
+struct UcsXmlJobList\r
+{\r
+ Ucs_Xrm_ResObject_t *job;\r
+ struct UcsXmlJobList *next; \r
+};\r
+\r
+typedef enum\r
+{\r
+ MSocket_MOST = 20,\r
+ MSocket_USB,\r
+ MSocket_MLB,\r
+ MSocket_STRM,\r
+ MSocket_SPLITTER,\r
+ MSocket_COMBINER\r
+} MSocketType_t;\r
+\r
+typedef enum\r
+{\r
+ Parse_Success = 10,\r
+ Parse_MemoryError,\r
+ Parse_XmlError\r
+} ParseResult_t;\r
+\r
+typedef struct\r
+{\r
+ Ucs_Rm_Node_t *nod;\r
+ bool usbPortAddedToJobList; /* USB Port must be added only ONCE to connection job lists */\r
+ Ucs_Xrm_UsbPort_t *usbPort;\r
+ bool mlbPortAddedToJobList; /* MLB Port must be added only ONCE to connection job lists */\r
+ Ucs_Xrm_MlbPort_t *mlbPort;\r
+ bool strmPortsAddedToJobList; /* STRM Ports must be added only ONCE to connection job lists */\r
+ Ucs_Xrm_StrmPort_t *strmPortA;\r
+ Ucs_Xrm_StrmPort_t *strmPortB;\r
+} NodeData_t;\r
+\r
+typedef struct\r
+{\r
+ MDataType_t dataType;\r
+ uint8_t sockCnt;\r
+ bool syncOffsetNeeded;\r
+ bool isDeactivated;\r
+ uint16_t routeId;\r
+ uint16_t syncOffset;\r
+ const char *routeName;\r
+ Ucs_Xrm_ResObject_t *inSocket;\r
+ Ucs_Xrm_ResObject_t *outSocket;\r
+ struct UcsXmlJobList *jobList;\r
+ Ucs_Xrm_Combiner_t *combiner;\r
+ mxml_node_t *pendingCombinerMostSockets;\r
+ Ucs_Sync_MuteMode_t muteMode;\r
+ Ucs_Avp_IsocPacketSize_t isocPacketSize;\r
+} ConnectionData_t;\r
+\r
+typedef struct\r
+{\r
+ uint16_t pause;\r
+} ScriptData_t;\r
+\r
+typedef struct {\r
+ uint16_t autoRouteId;\r
+ struct UcsXmlObjectList objList;\r
+ struct UcsXmlRoute *pRtLst;\r
+ struct UcsXmlScript *pScrLst;\r
+ NodeData_t nodeData;\r
+ ConnectionData_t conData;\r
+ ScriptData_t scriptData;\r
+} PrivateData_t;\r
+\r
+/************************************************************************/\r
+/* Constants */\r
+/************************************************************************/\r
+\r
+/*Key section*/\r
+static const char* UNICENS = "Unicens";\r
+static const char* PACKET_BW = "AsyncBandwidth";\r
+static const char* NAME = "Name";\r
+static const char* ROUTE = "Route";\r
+static const char* ROUTE_ID = "RouteId";\r
+static const char* ROUTE_IS_ACTIVE = "IsActive";\r
+static const char* ENDPOINT_ADDRESS = "EndpointAddress";\r
+static const char* CHANNEL_ADDRESS = "ChannelAddress";\r
+static const char* BANDWIDTH = "Bandwidth";\r
+static const char* BYTES_PER_FRAME = "BytesPerFrame";\r
+static const char* OFFSET = "Offset";\r
+static const char* NODE = "Node";\r
+static const char* CLOCK_CONFIG = "ClockConfig";\r
+static const char* ADDRESS = "Address";\r
+static const char* FRAMES_PER_TRANSACTION = "FramesPerTransaction";\r
+static const char* MUTE_MODE = "MuteMode";\r
+static const char* MUTE_MODE_NO_MUTING = "NoMuting";\r
+static const char* MUTE_MODE_MUTE_SIGNAL = "MuteSignal";\r
+static const char* AVP_PACKET_SIZE = "IsocPacketSize";\r
+#define SYNC_CONNECTION "SyncConnection"\r
+#define AVP_CONNECTION "AVPConnection"\r
+#define DFP_CONNECTION "DFPhaseConnection"\r
+#define QOS_CONNECTION "QoSConnection"\r
+#define IPC_CONNECTION "IPCConnection"\r
+\r
+static const char* ALL_CONNECTIONS[] = { SYNC_CONNECTION, AVP_CONNECTION, \r
+ DFP_CONNECTION, QOS_CONNECTION, IPC_CONNECTION, NULL };\r
+\r
+#define MOST_SOCKET "MOSTSocket"\r
+#define USB_SOCKET "USBSocket"\r
+#define MLB_SOCKET "MediaLBSocket"\r
+#define STREAM_SOCKET "StreamSocket"\r
+#define SPLITTER "Splitter"\r
+#define COMBINER "Combiner"\r
+static const char* ALL_SOCKETS[] = { MOST_SOCKET, USB_SOCKET, MLB_SOCKET, \r
+ STREAM_SOCKET, SPLITTER, COMBINER, NULL };\r
+\r
+#define MLB_PORT "MediaLBPort"\r
+#define USB_PORT "USBPort"\r
+#define STRM_PORT "StreamPort"\r
+static const char* ALL_PORTS[] = { MLB_PORT, USB_PORT, STRM_PORT };\r
+\r
+static const char* PHYSICAL_LAYER = "PhysicalLayer";\r
+static const char* DEVICE_INTERFACES = "DeviceInterfaces";\r
+static const char* STRM_IN_COUNT = "StreamingIfEpInCount";\r
+static const char* STRM_OUT_COUNT = "StreamingIfEpOutCount";\r
+\r
+static const char* STRM_PIN = "StreamPinID";\r
+static const char* STRM_ALIGN = "DataAlignment";\r
+\r
+static const char* SCRIPT = "Script";\r
+static const char* FBLOCK_ID = "FBlockId";\r
+static const char* FUNCTION_ID = "FunctionId";\r
+static const char* OP_TYPE_REQUEST = "OpTypeRequest";\r
+static const char* OP_TYPE_RESPONSE = "OpTypeResponse";\r
+static const char* PAYLOAD_REQ_HEX = "PayloadRequest";\r
+static const char* PAYLOAD_RES_HEX = "PayloadResponse";\r
+static const char* PAUSE_MS = "WaitTime";\r
+static const char* DEBOUNCE_TIME = "DebounceTime";\r
+static const char* PIN_CONFIG = "PinConfiguration";\r
+static const char* PIN_MASK = "Mask";\r
+static const char* PIN_DATA = "Data";\r
+static const char* I2C_SPEED = "Speed";\r
+static const char* I2C_SPEED_SLOW = "SlowMode";\r
+static const char* I2C_SPEED_FAST = "FastMode";\r
+static const char* I2C_WRITE_MODE = "Mode";\r
+static const char* I2C_WRITE_MODE_DEFAULT = "DefaultMode";\r
+static const char* I2C_WRITE_MODE_REPEAT = "RepeatedStartMode";\r
+static const char* I2C_WRITE_MODE_BURST = "BurstMode";\r
+static const char* I2C_WRITE_BLOCK_COUNT = "BlockCount";\r
+static const char* I2C_SLAVE_ADDRESS = "Address";\r
+static const char* I2C_PAYLOAD_LENGTH = "Length";\r
+static const char* I2C_PAYLOAD = "Payload";\r
+static const char* I2C_TIMEOUT = "Timeout";\r
+\r
+#define SCRIPT_MSG_SEND "MsgSend"\r
+#define SCRIPT_PAUSE "Pause"\r
+#define SCRIPT_GPIO_PORT_CREATE "GPIOPortCreate"\r
+#define SCRIPT_GPIO_PORT_PIN_MODE "GPIOPortPinMode"\r
+#define SCRIPT_GPIO_PIN_STATE "GPIOPinState"\r
+#define SCRIPT_I2C_PORT_CREATE "I2CPortCreate"\r
+#define SCRIPT_I2C_PORT_WRITE "I2CPortWrite"\r
+#define SCRIPT_I2C_PORT_READ "I2CPortRead"\r
+static const char* ALL_SCRIPTS[] = { SCRIPT_MSG_SEND, SCRIPT_PAUSE, \r
+ SCRIPT_GPIO_PORT_CREATE, SCRIPT_GPIO_PORT_PIN_MODE, SCRIPT_GPIO_PIN_STATE,\r
+ SCRIPT_I2C_PORT_CREATE, SCRIPT_I2C_PORT_WRITE, SCRIPT_I2C_PORT_READ, NULL };\r
+\r
+static const char* VALUE_TRUE = "true";\r
+static const char* VALUE_FALSE = "false";\r
+static const char* VALUE_1 = "1";\r
+static const char* VALUE_0 = "0";\r
+\r
+/************************************************************************/\r
+/* Private Function Prototypes */\r
+/************************************************************************/\r
+\r
+static void FreeVal(UcsXmlVal_t *ucs);\r
+static bool GetElement(mxml_node_t *element, const char *name, bool goDeep, mxml_node_t **out, bool mandatory);\r
+static bool GetElementArray(mxml_node_t *element, const char *array[], const char **foundName, mxml_node_t **out);\r
+static bool GetCount(mxml_node_t *element, const char *name, uint32_t *out, bool mandatory);\r
+static bool GetCountArray(mxml_node_t *element, const char *array[], uint32_t *out, bool mandatory);\r
+static bool GetString(mxml_node_t *element, const char *key, const char **out, bool mandatory);\r
+static bool GetUInt16(mxml_node_t *element, const char *key, uint16_t *out, bool mandatory);\r
+static bool GetUInt8(mxml_node_t *element, const char *key, uint8_t *out, bool mandatory);\r
+static bool GetSocketType(const char *txt, MSocketType_t *out);\r
+static bool GetPayload(mxml_node_t *element, const char *name, uint8_t **pPayload, uint8_t *len, uint8_t offset,\r
+ struct UcsXmlObjectList *obj, bool mandatory);\r
+static bool AddJob(struct UcsXmlJobList **joblist, Ucs_Xrm_ResObject_t *job, struct UcsXmlObjectList *objList);\r
+static Ucs_Xrm_ResObject_t **GetJobList(struct UcsXmlJobList *joblist, struct UcsXmlObjectList *objList);\r
+static struct UcsXmlJobList *DeepCopyJobList(struct UcsXmlJobList *jobsIn, struct UcsXmlObjectList *objList);\r
+static void AddRoute(struct UcsXmlRoute **pRtLst, struct UcsXmlRoute *route);\r
+static void AddScript(struct UcsXmlScript **pScrLst, struct UcsXmlScript *script);\r
+static ParseResult_t ParseAll(mxml_node_t *tree, UcsXmlVal_t *ucs, PrivateData_t *priv);\r
+static ParseResult_t ParseNode(mxml_node_t * node, PrivateData_t *priv);\r
+static ParseResult_t ParseConnection(mxml_node_t * node, const char *conType, PrivateData_t *priv);\r
+static ParseResult_t ParseSocket(mxml_node_t *soc, bool isSource, MSocketType_t socketType, struct UcsXmlJobList **jobList, PrivateData_t *priv);\r
+static ParseResult_t ParseScript(mxml_node_t *scr, PrivateData_t *priv);\r
+static bool FillScriptInitialValues(Ucs_Ns_Script_t *scr, PrivateData_t *priv);\r
+static ParseResult_t ParseScriptMsgSend(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);\r
+static ParseResult_t ParseScriptGpioPortCreate(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);\r
+static ParseResult_t ParseScriptGpioPinMode(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);\r
+static ParseResult_t ParseScriptGpioPinState(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);\r
+static ParseResult_t ParseScriptPortCreate(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);\r
+static ParseResult_t ParseScriptPortWrite(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);\r
+static ParseResult_t ParseScriptPortRead(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);\r
+static ParseResult_t ParseScriptPause(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);\r
+static ParseResult_t ParseRoutes(UcsXmlVal_t *ucs, PrivateData_t *priv);\r
+\r
+/************************************************************************/\r
+/* Public Functions */\r
+/************************************************************************/\r
+\r
+UcsXmlVal_t *UcsXml_Parse(const char *xmlString)\r
+{\r
+ UcsXmlVal_t *val;\r
+ ParseResult_t result = Parse_MemoryError;\r
+ mxml_node_t *tree;\r
+ if (!(tree = mxmlLoadString(NULL, xmlString, MXML_NO_CALLBACK))) goto ERROR;\r
+ if (!GetElement(tree, UNICENS, true, &tree, true)) goto ERROR;\r
+ /*Do not use MCalloc for the root element*/\r
+ val = calloc(1, sizeof(UcsXmlVal_t));\r
+ if (!val) goto ERROR;\r
+ val->pInternal = calloc(1, sizeof(PrivateData_t));\r
+ if (!val->pInternal) goto ERROR;\r
+ result = ParseAll(tree, val, val->pInternal);\r
+ if (Parse_Success == result)\r
+ return val;\r
+ERROR:\r
+ if (Parse_MemoryError == result)\r
+ UcsXml_CB_OnError("XML error, aborting..", 0);\r
+ else\r
+ UcsXml_CB_OnError("Allocation error, aborting..", 0);\r
+ assert(false); \r
+ if (!tree)\r
+ mxmlDelete(tree);\r
+ FreeVal(val);\r
+ return NULL;\r
+}\r
+\r
+void UcsXml_FreeVal(UcsXmlVal_t *val)\r
+{\r
+ FreeVal(val);\r
+}\r
+\r
+/************************************************************************/\r
+/* Private Function Implementations */\r
+/************************************************************************/\r
+\r
+void FreeVal(UcsXmlVal_t *ucs)\r
+{\r
+ PrivateData_t *priv;\r
+ if (NULL == ucs || NULL == ucs->pInternal)\r
+ return;\r
+ priv = ucs->pInternal;\r
+ FreeObjList(&priv->objList);\r
+ free(ucs->pInternal);\r
+ free(ucs);\r
+}\r
+\r
+static bool GetElement(mxml_node_t *element, const char *name, bool goDeep, mxml_node_t **out, bool mandatory)\r
+{\r
+ mxml_node_t *n = element;\r
+ if (NULL == n || NULL == name || NULL == out) return false;\r
+ if (goDeep)\r
+ {\r
+ *out = mxmlFindElement(n, n, name, NULL, NULL, MXML_DESCEND);\r
+ return (NULL != *out);\r
+ }\r
+ while ((n = n->next))\r
+ {\r
+ if (MXML_ELEMENT != n->type)\r
+ continue;\r
+ if (0 == strcmp(name, n->value.opaque))\r
+ {\r
+ *out = n;\r
+ return true;\r
+ }\r
+ }\r
+ if (mandatory)\r
+ UcsXml_CB_OnError("Can not find tag <%s>", 1, name);\r
+ return false;\r
+}\r
+\r
+static bool GetElementArray(mxml_node_t *element, const char *array[], const char **foundName, mxml_node_t **out)\r
+{\r
+ mxml_node_t *n = element;\r
+ if (NULL == n || NULL == array || NULL == foundName || NULL == out) return false;\r
+ while ((n = n->next))\r
+ {\r
+ uint32_t i;\r
+ if (MXML_ELEMENT != n->type)\r
+ continue;\r
+ for (i = 0; NULL != array[i]; i++)\r
+ {\r
+ if (0 == strcmp(array[i], n->value.opaque))\r
+ {\r
+ *foundName = array[i];\r
+ *out = n;\r
+ return true;\r
+ }\r
+ }\r
+ }\r
+ return false;\r
+}\r
+\r
+static bool GetCount(mxml_node_t *element, const char *name, uint32_t *out, bool mandatory)\r
+{\r
+ uint32_t cnt = 0;\r
+ mxml_node_t *n;\r
+ if (NULL == element || NULL == name) return false;\r
+ if(!GetElement(element, name, true, &n, false))\r
+ return false;\r
+ while(NULL != n)\r
+ {\r
+ ++cnt;\r
+ if(!GetElement(n, name, false, &n, false))\r
+ break;\r
+ }\r
+ if (mandatory && 0 == cnt)\r
+ {\r
+ UcsXml_CB_OnError("element count of <%s> is zero", 1, name);\r
+ return false;\r
+ }\r
+ *out = cnt;\r
+ return true;\r
+}\r
+\r
+static bool GetCountArray(mxml_node_t *element, const char *array[], uint32_t *out, bool mandatory)\r
+{\r
+ const char *tmp;\r
+ uint32_t cnt = 0;\r
+ mxml_node_t *n;\r
+ if (NULL == element || NULL == array) return false;\r
+ n = element;\r
+ while(NULL != n)\r
+ {\r
+ if(!GetElementArray(n, array, &tmp, &n))\r
+ break;\r
+ ++cnt;\r
+ }\r
+ if (mandatory && 0 == cnt)\r
+ {\r
+ UcsXml_CB_OnError("element count is zero, searched with string array", 0);\r
+ return false;\r
+ }\r
+ *out = cnt;\r
+ return true;\r
+}\r
+\r
+static bool GetString(mxml_node_t *element, const char *key, const char **out, bool mandatory)\r
+{\r
+ int32_t i;\r
+ if (NULL == element || NULL == key) return false;\r
+ for (i = 0; i < element->value.element.num_attrs; i++)\r
+ {\r
+ mxml_attr_t *attr = &element->value.element.attrs[i];\r
+ if (0 == strcmp(key, attr->name))\r
+ {\r
+ *out = attr->value;\r
+ return true;\r
+ }\r
+ }\r
+ if (mandatory)\r
+ UcsXml_CB_OnError("Can not find attribute='%s' from element <%s>", \r
+ 2, key, element->value.element.name);\r
+ return false;\r
+}\r
+\r
+static bool GetUInt16(mxml_node_t *element, const char *key, uint16_t *out, bool mandatory)\r
+{\r
+ const char* txt;\r
+ if (!GetString(element, key, &txt, mandatory)) return false;\r
+ *out = strtol( txt, NULL, 0 );\r
+ return true;\r
+}\r
+\r
+static bool GetUInt8(mxml_node_t *element, const char *key, uint8_t *out, bool mandatory)\r
+{\r
+ const char* txt;\r
+ if (!GetString(element, key, &txt, mandatory)) return false;\r
+ *out = strtol( txt, NULL, 0 );\r
+ return true;\r
+}\r
+\r
+static bool GetDataType(const char *txt, MDataType_t *out)\r
+{\r
+ if (NULL == txt || NULL == out) return false;\r
+ if (0 == strcmp(SYNC_CONNECTION, txt)) {\r
+ *out = SYNC_DATA;\r
+ } else if (0 == strcmp(AVP_CONNECTION, txt)) {\r
+ *out = AV_PACKETIZED;\r
+ } else if (0 == strcmp(QOS_CONNECTION, txt)) {\r
+ *out = QOS_IP;\r
+ } else if (0 == strcmp(DFP_CONNECTION, txt)) {\r
+ *out = DISC_FRAME_PHASE;\r
+ } else if (0 == strcmp(IPC_CONNECTION, txt)) {\r
+ *out = IPC_PACKET;\r
+ } else {\r
+ UcsXml_CB_OnError("Unknown data type : '%s'", 1, txt);\r
+ return false;\r
+ }\r
+ return true;\r
+}\r
+\r
+static bool GetSocketType(const char *txt, MSocketType_t *out)\r
+{\r
+ if (0 == strcmp(txt, MOST_SOCKET)) {\r
+ *out = MSocket_MOST;\r
+ } else if (0 == strcmp(txt, USB_SOCKET)) {\r
+ *out = MSocket_USB;\r
+ } else if (0 == strcmp(txt, MLB_SOCKET)) {\r
+ *out = MSocket_MLB;\r
+ } else if (0 == strcmp(txt, STREAM_SOCKET)) {\r
+ *out = MSocket_STRM;\r
+ } else if (0 == strcmp(txt, SPLITTER)) {\r
+ *out = MSocket_SPLITTER;\r
+ } else if (0 == strcmp(txt, COMBINER)) {\r
+ *out = MSocket_COMBINER;\r
+ } else {\r
+ UcsXml_CB_OnError("Unknown port : '%s'", 1, txt);\r
+ return false;\r
+ }\r
+ return true;\r
+}\r
+\r
+static bool GetPayload(mxml_node_t *element, const char *name, uint8_t **pPayload, uint8_t *outLen, uint8_t offset, struct UcsXmlObjectList *obj, bool mandatory)\r
+{\r
+ uint32_t tempLen, len = 0;\r
+ uint8_t *p;\r
+ const char *txt;\r
+ char *txtCopy;\r
+ char *tkPtr;\r
+ char *token;\r
+ if (!GetString(element, name, &txt, mandatory))\r
+ return false;\r
+ tempLen = strlen(txt) + 1;\r
+ txtCopy = malloc(tempLen);\r
+ if (NULL == txtCopy) \r
+ return false;\r
+ strncpy(txtCopy, txt, tempLen);\r
+ tempLen = tempLen / 3; /* 2 chars hex value plus space (AA ) */\r
+ p = MCalloc(obj, offset + tempLen, 1);\r
+ if (NULL == p)\r
+ {\r
+ free(txtCopy);\r
+ return false;\r
+ }\r
+ *pPayload = p;\r
+ token = strtok_r( txtCopy, " ,.-", &tkPtr );\r
+ while( NULL != token )\r
+ {\r
+ if( len >= tempLen )\r
+ {\r
+ UcsXml_CB_OnError("Script payload values must be stuffed to two characters", 0);\r
+ free(txtCopy);\r
+ assert(false);\r
+ return 0;\r
+ }\r
+ p[offset + len++] = strtol( token, NULL, 16 );\r
+ token = strtok_r( NULL, " ,.-", &tkPtr );\r
+ }\r
+ *outLen = len;\r
+ return true;\r
+}\r
+\r
+static bool AddJob(struct UcsXmlJobList **joblist, Ucs_Xrm_ResObject_t *job, struct UcsXmlObjectList *objList)\r
+{\r
+ struct UcsXmlJobList *tail;\r
+ if (NULL == joblist || NULL == job)\r
+ return false;\r
+ assert(UCS_XRM_RC_TYPE_QOS_CON >= *((Ucs_Xrm_ResourceType_t *)job));\r
+ if (NULL == joblist[0])\r
+ {\r
+ joblist[0] = MCalloc(objList, 1, sizeof(struct UcsXmlJobList));\r
+ if (NULL == joblist[0]) return false;;\r
+ joblist[0]->job = job;\r
+ return true;\r
+ }\r
+ tail = joblist[0];\r
+ while(tail->next) tail = tail->next;\r
+ tail->next = MCalloc(objList, 1, sizeof(struct UcsXmlJobList));\r
+ if (NULL == tail->next) return false;\r
+ tail->next->job = job;\r
+ return true;\r
+}\r
+\r
+static Ucs_Xrm_ResObject_t **GetJobList(struct UcsXmlJobList *joblist, struct UcsXmlObjectList *objList)\r
+{\r
+ Ucs_Xrm_ResObject_t **outJob;\r
+ uint32_t count = 0;\r
+ struct UcsXmlJobList *tail;\r
+ if (NULL == joblist)\r
+ return false;\r
+ /*First: Get amount of stored jobs by enumerate all*/\r
+ tail = joblist;\r
+ while(tail)\r
+ {\r
+ ++count;\r
+ tail = tail->next;\r
+ }\r
+ if (0 == count)\r
+ return false;\r
+ /*Second: Allocate count+1 elements (NULL terminated) and copy pointers*/\r
+ outJob = MCalloc(objList, (count + 1), sizeof(Ucs_Xrm_ResObject_t *));\r
+ if (NULL == outJob)\r
+ return false;\r
+ tail = joblist;\r
+ count = 0;\r
+ while(tail)\r
+ {\r
+ outJob[count++] = tail->job;\r
+ tail = tail->next;\r
+ }\r
+ return outJob;\r
+}\r
+\r
+static struct UcsXmlJobList *DeepCopyJobList(struct UcsXmlJobList *jobsIn, struct UcsXmlObjectList *objList)\r
+{\r
+ struct UcsXmlJobList *jobsOut, *tail;\r
+ if (NULL == jobsIn || NULL == objList)\r
+ return NULL;\r
+ jobsOut = tail = MCalloc(objList, 1, sizeof(struct UcsXmlJobList));\r
+ if (NULL == jobsOut) { assert(false); return NULL; }\r
+ while(jobsIn)\r
+ {\r
+ tail->job = jobsIn->job;\r
+ if (jobsIn->next)\r
+ {\r
+ tail->next = MCalloc(objList, 1, sizeof(struct UcsXmlJobList));\r
+ if (NULL == tail->next) { assert(false); return NULL; }\r
+ tail = tail->next;\r
+ }\r
+ jobsIn = jobsIn->next;\r
+ }\r
+ return jobsOut;\r
+}\r
+\r
+static void AddRoute(struct UcsXmlRoute **pRtLst, struct UcsXmlRoute *route)\r
+{\r
+ struct UcsXmlRoute *tail;\r
+ if (NULL == pRtLst || NULL == route)\r
+ {\r
+ assert(false);\r
+ return;\r
+ }\r
+ if (NULL == pRtLst[0])\r
+ {\r
+ pRtLst[0] = route;\r
+ return;\r
+ }\r
+ tail = pRtLst[0];\r
+ while(tail->next) tail = tail->next;\r
+ tail->next = route;\r
+}\r
+\r
+static void AddScript(struct UcsXmlScript **pScrLst, struct UcsXmlScript *script)\r
+{\r
+ struct UcsXmlScript *tail;\r
+ if (NULL == pScrLst || NULL == script)\r
+ {\r
+ assert(false);\r
+ return;\r
+ }\r
+ if (NULL == pScrLst[0])\r
+ {\r
+ pScrLst[0] = script;\r
+ return;\r
+ }\r
+ tail = pScrLst[0];\r
+ while(tail->next) tail = tail->next;\r
+ tail->next = script;\r
+}\r
+\r
+static ParseResult_t ParseAll(mxml_node_t *tree, UcsXmlVal_t *ucs, PrivateData_t *priv)\r
+{\r
+ uint32_t nodeCount;\r
+ mxml_node_t *sub;\r
+ ParseResult_t result;\r
+ priv->autoRouteId = 0x8000;\r
+ if (!GetCount(tree, NODE, &nodeCount, true))\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ \r
+ ucs->pNod = MCalloc(&priv->objList, nodeCount, sizeof(Ucs_Rm_Node_t));\r
+ if (NULL == ucs->pNod) RETURN_ASSERT(Parse_MemoryError);\r
+\r
+ if (!GetUInt16(tree, PACKET_BW, &ucs->packetBw, true))\r
+ RETURN_ASSERT(Parse_XmlError);\r
+\r
+ /*Iterate all nodes*/\r
+ if (!GetElement(tree, NODE, true, &sub, true))\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ while(sub)\r
+ {\r
+ const char *conType;\r
+ mxml_node_t *con;\r
+ memset(&priv->nodeData, 0, sizeof(NodeData_t));\r
+ priv->nodeData.nod = &ucs->pNod[ucs->nodSize];\r
+ if (Parse_Success != (result = ParseNode(sub, priv)))\r
+ return result;\r
+ /*/Iterate all connections. Node without any connection is also valid.*/\r
+ if (!GetElementArray(sub->child, ALL_CONNECTIONS, &conType, &con))\r
+ continue;\r
+ while(con)\r
+ {\r
+ const char *socTypeStr;\r
+ MSocketType_t socType;\r
+ mxml_node_t *soc;\r
+ memset(&priv->conData, 0, sizeof(ConnectionData_t));\r
+ if (Parse_Success != (result = ParseConnection(con, conType, priv)))\r
+ return result;\r
+ /*Iterate all sockets*/\r
+ if(!GetElementArray(con->child, ALL_SOCKETS, &socTypeStr, &soc)) RETURN_ASSERT(Parse_XmlError);\r
+ while(soc)\r
+ {\r
+ if (!GetSocketType(socTypeStr, &socType)) RETURN_ASSERT(Parse_XmlError);\r
+ if (Parse_Success != (result = ParseSocket(soc, (0 == priv->conData.sockCnt), socType, &priv->conData.jobList, priv)))\r
+ return result;\r
+ ++priv->conData.sockCnt;\r
+ if(!GetElementArray(soc, ALL_SOCKETS, &socTypeStr, &soc))\r
+ break;\r
+ }\r
+ if(!GetElementArray(con, ALL_CONNECTIONS, &conType, &con))\r
+ break;\r
+ }\r
+ ++ucs->nodSize;\r
+ if (!GetElement(sub, NODE, false, &sub, false))\r
+ break;\r
+ }\r
+\r
+ /*Fill route structures*/\r
+ result = ParseRoutes(ucs, priv);\r
+ if (Parse_MemoryError == result) RETURN_ASSERT(Parse_MemoryError)\r
+ else if (Parse_XmlError == result) RETURN_ASSERT(Parse_XmlError);\r
+ \r
+ /*Iterate all scripts. No scripts at all is allowed*/\r
+ if(GetElement(tree, SCRIPT, true, &sub, false))\r
+ {\r
+ while(sub)\r
+ {\r
+ result = ParseScript(sub, priv);\r
+ if (Parse_MemoryError == result) RETURN_ASSERT(Parse_MemoryError)\r
+ else if (Parse_XmlError == result) RETURN_ASSERT(Parse_XmlError);\r
+ if(!GetElement(sub, SCRIPT, false, &sub, false))\r
+ break;\r
+ }\r
+ }\r
+ return result;\r
+}\r
+\r
+static ParseResult_t ParseNode(mxml_node_t *node, PrivateData_t *priv)\r
+{\r
+ const char *txt;\r
+ mxml_node_t *port;\r
+ Ucs_Signature_t *signature;\r
+ assert(NULL != node && NULL != priv);\r
+ priv->nodeData.nod->signature_ptr = MCalloc(&priv->objList, 1, sizeof(Ucs_Signature_t));\r
+ signature = priv->nodeData.nod->signature_ptr;\r
+ if(NULL == signature) RETURN_ASSERT(Parse_MemoryError);\r
+ if (!GetUInt16(node, ADDRESS, &signature->node_address, true))\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ if (GetString(node, SCRIPT, &txt, false))\r
+ {\r
+ struct UcsXmlScript *scr = MCalloc(&priv->objList, 1, sizeof(struct UcsXmlScript));\r
+ if (NULL == scr) RETURN_ASSERT(Parse_MemoryError);\r
+ scr->node = priv->nodeData.nod;\r
+ strncpy(scr->scriptName, txt, sizeof(scr->scriptName));\r
+ AddScript(&priv->pScrLst, scr);\r
+ }\r
+ /*Iterate all ports*/\r
+ if(GetElementArray(node->child, ALL_PORTS, &txt, &port))\r
+ {\r
+ while(port)\r
+ {\r
+ if (0 == (strcmp(txt, MLB_PORT)))\r
+ {\r
+ struct MlbPortParameters p;\r
+ p.list = &priv->objList;\r
+ if (!GetString(port, CLOCK_CONFIG, &p.clockConfig, true)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetMlbPort(&priv->nodeData.mlbPort, &p)) RETURN_ASSERT(Parse_XmlError);\r
+ }\r
+ else if (0 == (strcmp(txt, USB_PORT)))\r
+ {\r
+ struct UsbPortParameters p;\r
+ p.list = &priv->objList;\r
+ if (!GetString(port, PHYSICAL_LAYER, &p.physicalLayer, true)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetString(port, DEVICE_INTERFACES, &p.deviceInterfaces, true)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetString(port, STRM_IN_COUNT, &p.streamInCount, true)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetString(port, STRM_OUT_COUNT, &p.streamOutCount, true)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetUsbPort(&priv->nodeData.usbPort, &p)) RETURN_ASSERT(Parse_XmlError);\r
+ }\r
+ else if (0 == (strcmp(txt, STRM_PORT)))\r
+ {\r
+ struct StrmPortParameters p;\r
+ p.list = &priv->objList;\r
+ p.index = 0;\r
+ if (!GetString(port, CLOCK_CONFIG, &p.clockConfig, true)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetString(port, STRM_ALIGN, &p.dataAlignment, true)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetStrmPort(&priv->nodeData.strmPortA, &p)) RETURN_ASSERT(Parse_XmlError);\r
+ p.index = 1;\r
+ if (!GetStrmPort(&priv->nodeData.strmPortB, &p)) RETURN_ASSERT(Parse_XmlError);\r
+ }\r
+ else\r
+ {\r
+ UcsXml_CB_OnError("Unknown Port:'%s'", 1, txt);\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ }\r
+ if(!GetElementArray(port, ALL_SOCKETS, &txt, &port))\r
+ break;\r
+ }\r
+ }\r
+ return Parse_Success;;\r
+}\r
+\r
+static ParseResult_t ParseConnection(mxml_node_t * node, const char *conType, PrivateData_t *priv)\r
+{ \r
+ assert(NULL != node && NULL != priv);\r
+ if (NULL == conType) RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetDataType(conType, &priv->conData.dataType)) RETURN_ASSERT(Parse_XmlError);\r
+ switch (priv->conData.dataType)\r
+ {\r
+ case SYNC_DATA:\r
+ {\r
+ const char *txt;\r
+ if (GetString(node, MUTE_MODE, &txt, false))\r
+ {\r
+ if (0 == strcmp(txt, MUTE_MODE_NO_MUTING))\r
+ priv->conData.muteMode = UCS_SYNC_MUTE_MODE_NO_MUTING;\r
+ else if (0 == strcmp(txt, MUTE_MODE_MUTE_SIGNAL))\r
+ priv->conData.muteMode = UCS_SYNC_MUTE_MODE_MUTE_SIGNAL;\r
+ else\r
+ {\r
+ UcsXml_CB_OnError("ParseConnection: MuteMode='%s' not implemented", 1, txt);\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*Be tolerant, this is an optional feature*/\r
+ priv->conData.muteMode = UCS_SYNC_MUTE_MODE_NO_MUTING;\r
+ }\r
+ break;\r
+ }\r
+ case AV_PACKETIZED:\r
+ {\r
+ uint16_t size;\r
+ if (GetUInt16(node, AVP_PACKET_SIZE, &size, false))\r
+ {\r
+ switch(size)\r
+ {\r
+ case 188:\r
+ priv->conData.isocPacketSize = UCS_ISOC_PCKT_SIZE_188;\r
+ break;\r
+ case 196:\r
+ priv->conData.isocPacketSize = UCS_ISOC_PCKT_SIZE_196;\r
+ break;\r
+ case 206:\r
+ priv->conData.isocPacketSize = UCS_ISOC_PCKT_SIZE_206;\r
+ break;\r
+ default:\r
+ UcsXml_CB_OnError("ParseConnection: %s='%d' not implemented", 2, AVP_PACKET_SIZE, size);\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*Be tolerant, this is an optional feature*/\r
+ priv->conData.isocPacketSize = UCS_ISOC_PCKT_SIZE_188;\r
+ }\r
+ break;\r
+ }\r
+ default:\r
+ UcsXml_CB_OnError("ParseConnection: Datatype='%s' not implemented", 1, conType);\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ break;\r
+ }\r
+ return Parse_Success;\r
+}\r
+\r
+static ParseResult_t ParseSocket(mxml_node_t *soc, bool isSource, MSocketType_t socketType, struct UcsXmlJobList **jobList, PrivateData_t *priv)\r
+{\r
+ Ucs_Xrm_ResObject_t **targetSock;\r
+ assert(NULL != soc && NULL != priv);\r
+ targetSock = isSource ? &priv->conData.inSocket : &priv->conData.outSocket;\r
+ switch(socketType)\r
+ {\r
+ case MSocket_MOST:\r
+ {\r
+ const char* txt;\r
+ struct MostSocketParameters p;\r
+ /* If there is an combiner stored, add it now into job list (right before MOST socket) */\r
+ if (priv->conData.combiner)\r
+ if (!AddJob(jobList, priv->conData.combiner, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
+ \r
+ p.list = &priv->objList;\r
+ p.isSource = isSource;\r
+ p.dataType = priv->conData.dataType;\r
+ if (!GetUInt16(soc, BANDWIDTH, &p.bandwidth, true)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetString(soc, ROUTE, &priv->conData.routeName, true)) RETURN_ASSERT(Parse_XmlError);\r
+ if (GetString(soc, ROUTE_IS_ACTIVE, &txt, false))\r
+ {\r
+ if (0 == strcmp(txt, VALUE_TRUE) || 0 == strcmp(txt, VALUE_1))\r
+ priv->conData.isDeactivated = false;\r
+ else if (0 == strcmp(txt, VALUE_FALSE) || 0 == strcmp(txt, VALUE_0))\r
+ priv->conData.isDeactivated = true;\r
+ else RETURN_ASSERT(Parse_XmlError);\r
+ } else {\r
+ priv->conData.isDeactivated = false;\r
+ }\r
+ if (!GetUInt16(soc, ROUTE_ID, &priv->conData.routeId, false))\r
+ priv->conData.routeId = ++priv->autoRouteId;\r
+ if (priv->conData.syncOffsetNeeded)\r
+ {\r
+ if (!GetUInt16(soc, OFFSET, &priv->conData.syncOffset, true)) RETURN_ASSERT(Parse_XmlError);\r
+ }\r
+ if (!GetMostSocket((Ucs_Xrm_MostSocket_t **)targetSock, &p)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!AddJob(jobList, *targetSock, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
+ break;\r
+ }\r
+ case MSocket_USB:\r
+ {\r
+ struct UsbSocketParameters p;\r
+ p.list = &priv->objList;\r
+ p.isSource = isSource;\r
+ p.dataType = priv->conData.dataType;\r
+ if (priv->nodeData.usbPort)\r
+ {\r
+ p.usbPort = priv->nodeData.usbPort;\r
+ } else {\r
+ if (!GetUsbPortDefaultCreated(&p.usbPort, &priv->objList)) \r
+ RETURN_ASSERT(Parse_XmlError);\r
+ priv->nodeData.usbPort = (Ucs_Xrm_UsbPort_t *)p.usbPort;\r
+ }\r
+ if (!priv->nodeData.usbPortAddedToJobList)\r
+ {\r
+ priv->nodeData.usbPortAddedToJobList = true;\r
+ if(!AddJob(jobList, p.usbPort, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
+ }\r
+ if (!GetString(soc, ENDPOINT_ADDRESS, &p.endpointAddress, true)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetString(soc, FRAMES_PER_TRANSACTION, &p.framesPerTrans, true)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetUsbSocket((Ucs_Xrm_UsbSocket_t **)targetSock, &p)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!AddJob(jobList, *targetSock, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
+ break;\r
+ }\r
+ case MSocket_MLB:\r
+ {\r
+ struct MlbSocketParameters p;\r
+ p.list = &priv->objList;\r
+ p.isSource = isSource;\r
+ p.dataType = priv->conData.dataType;\r
+ if (priv->nodeData.mlbPort)\r
+ {\r
+ p.mlbPort = priv->nodeData.mlbPort;\r
+ } else {\r
+ if (!GetMlbPortDefaultCreated(&p.mlbPort, &priv->objList)) \r
+ RETURN_ASSERT(Parse_XmlError);\r
+ priv->nodeData.mlbPort = (Ucs_Xrm_MlbPort_t *)p.mlbPort;\r
+ }\r
+ if (!priv->nodeData.mlbPortAddedToJobList)\r
+ {\r
+ priv->nodeData.mlbPortAddedToJobList = true;\r
+ if (!AddJob(jobList, p.mlbPort, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
+ }\r
+ if (!GetUInt16(soc, BANDWIDTH, &p.bandwidth, true)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetString(soc, CHANNEL_ADDRESS, &p.channelAddress, true)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetMlbSocket((Ucs_Xrm_MlbSocket_t **)targetSock, &p)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!AddJob(jobList, *targetSock, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
+ break;\r
+ }\r
+ case MSocket_STRM:\r
+ {\r
+ struct StrmSocketParameters p;\r
+ p.list = &priv->objList;\r
+ p.isSource = isSource;\r
+ p.dataType = priv->conData.dataType;\r
+ p.streamPortA = priv->nodeData.strmPortA;\r
+ p.streamPortB = priv->nodeData.strmPortB;\r
+ if (!priv->nodeData.strmPortsAddedToJobList)\r
+ {\r
+ priv->nodeData.strmPortsAddedToJobList = true;\r
+ if (!AddJob(jobList, p.streamPortA, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!AddJob(jobList, p.streamPortB, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
+ }\r
+ if (!GetUInt16(soc, BANDWIDTH, &p.bandwidth, true)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetString(soc, STRM_PIN, &p.streamPin, true)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetStrmSocket((Ucs_Xrm_StrmSocket_t **)targetSock, &p)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!AddJob(jobList, *targetSock, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
+ break;\r
+ }\r
+ case MSocket_SPLITTER:\r
+ {\r
+ mxml_node_t *mostSoc;\r
+ struct SplitterParameters p;\r
+ if (isSource)\r
+ {\r
+ UcsXml_CB_OnError("Splitter can not be used as input socket", 0);\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ }\r
+ p.list = &priv->objList;\r
+ if (!GetUInt16(soc, BYTES_PER_FRAME, &p.bytesPerFrame, true)) RETURN_ASSERT(Parse_XmlError);\r
+ /* Current input socket will be stored inside splitter \r
+ * and splitter will become the new input socket */\r
+ if (!(p.inSoc = priv->conData.inSocket)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetSplitter((Ucs_Xrm_Splitter_t **)&priv->conData.inSocket, &p)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!AddJob(jobList, priv->conData.inSocket, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetElement(soc->child, MOST_SOCKET, false, &mostSoc, true))\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ priv->conData.syncOffsetNeeded = true;\r
+ \r
+ while(mostSoc)\r
+ {\r
+ struct UcsXmlJobList *jobListCopy = DeepCopyJobList(*jobList, &priv->objList);\r
+ if (!ParseSocket(mostSoc, false, MSocket_MOST, &jobListCopy, priv)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetElement(mostSoc, MOST_SOCKET, false, &mostSoc, false))\r
+ return Parse_Success; /* Do not break here, otherwise an additional invalid route will be created */\r
+ }\r
+ break;\r
+ }\r
+ case MSocket_COMBINER:\r
+ {\r
+ struct CombinerParameters p;\r
+ if (!isSource)\r
+ {\r
+ UcsXml_CB_OnError("Combiner can not be used as output socket", 0);\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ }\r
+ p.list = &priv->objList;\r
+ if (!GetUInt16(soc, BYTES_PER_FRAME, &p.bytesPerFrame, true)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetCombiner(&priv->conData.combiner, &p)) RETURN_ASSERT(Parse_XmlError);\r
+ priv->conData.syncOffsetNeeded = true;\r
+ if (!GetElement(soc->child, MOST_SOCKET, false, &priv->conData.pendingCombinerMostSockets, true))\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ break;\r
+ }\r
+ default:\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ }\r
+ /*Handle Pending Combiner Tasks*/\r
+ if (NULL != priv->conData.outSocket && NULL != priv->conData.combiner && \r
+ NULL != priv->conData.pendingCombinerMostSockets)\r
+ {\r
+ mxml_node_t *tmp = priv->conData.pendingCombinerMostSockets;\r
+ priv->conData.pendingCombinerMostSockets = NULL;\r
+ /* Current output socket will be stored inside combiner \r
+ * and combiner will become the new output socket */\r
+ priv->conData.combiner->port_socket_obj_ptr = priv->conData.outSocket;\r
+ priv->conData.outSocket = priv->conData.combiner;\r
+ while(tmp)\r
+ {\r
+ struct UcsXmlJobList *jobListCopy = DeepCopyJobList(*jobList, &priv->objList);\r
+ if (!ParseSocket(tmp, true, MSocket_MOST, &jobListCopy, priv)) RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetElement(tmp, MOST_SOCKET, false, &tmp, false))\r
+ return Parse_Success; /* Do not break here, otherwise an additional invalid route will be created */\r
+ }\r
+ }\r
+ /*Connect in and out socket once they are created*/\r
+ if (priv->conData.inSocket && priv->conData.outSocket)\r
+ {\r
+ bool mostIsOutput;\r
+ Ucs_Rm_EndPoint_t *ep;\r
+ struct UcsXmlRoute *route;\r
+ switch(priv->conData.dataType)\r
+ {\r
+ case SYNC_DATA:\r
+ {\r
+ Ucs_Xrm_SyncCon_t *con = MCalloc(&priv->objList, 1, sizeof(Ucs_Xrm_SyncCon_t));\r
+ if (NULL == con) RETURN_ASSERT(Parse_MemoryError);\r
+ if (!AddJob(jobList, con, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
+ con->resource_type = UCS_XRM_RC_TYPE_SYNC_CON;\r
+ con->socket_in_obj_ptr = priv->conData.inSocket;\r
+ con->socket_out_obj_ptr = priv->conData.outSocket;\r
+ con->mute_mode = priv->conData.muteMode;\r
+ con->offset = priv->conData.syncOffset;\r
+ break;\r
+ }\r
+ case AV_PACKETIZED:\r
+ {\r
+ Ucs_Xrm_AvpCon_t *con = MCalloc(&priv->objList, 1, sizeof(Ucs_Xrm_AvpCon_t));\r
+ if (NULL == con) RETURN_ASSERT(Parse_MemoryError);\r
+ if (!AddJob(jobList, con, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
+ con->resource_type = UCS_XRM_RC_TYPE_AVP_CON;\r
+ con->socket_in_obj_ptr = priv->conData.inSocket;\r
+ con->socket_out_obj_ptr = priv->conData.outSocket;\r
+ con->isoc_packet_size = priv->conData.isocPacketSize;\r
+ break;\r
+ }\r
+ default:\r
+ UcsXml_CB_OnError("Could not connect sockets, data type not implemented: %d", 1, priv->conData.dataType);\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ break;\r
+ }\r
+ ep = MCalloc(&priv->objList, 1, sizeof(Ucs_Rm_EndPoint_t));\r
+ if (NULL == ep) RETURN_ASSERT(Parse_MemoryError);\r
+\r
+ mostIsOutput = (UCS_XRM_RC_TYPE_MOST_SOCKET == *((Ucs_Xrm_ResourceType_t *)priv->conData.outSocket));\r
+ ep->endpoint_type = mostIsOutput ? UCS_RM_EP_SOURCE : UCS_RM_EP_SINK;\r
+ ep->jobs_list_ptr = GetJobList(*jobList, &priv->objList);\r
+ if(NULL == ep->jobs_list_ptr) RETURN_ASSERT(Parse_MemoryError);\r
+ ep->node_obj_ptr = priv->nodeData.nod;\r
+ route = MCalloc(&priv->objList, 1, sizeof(struct UcsXmlRoute));\r
+ if (NULL == route) RETURN_ASSERT(Parse_MemoryError);\r
+ route->isSource = mostIsOutput;\r
+ route->isActive = !priv->conData.isDeactivated;\r
+ route->routeId = priv->conData.routeId;\r
+ route->ep = ep;\r
+ assert(NULL != priv->conData.routeName);\r
+ strncpy(route->routeName, priv->conData.routeName, sizeof(route->routeName));\r
+ AddRoute(&priv->pRtLst, route);\r
+ }\r
+ return Parse_Success;\r
+}\r
+\r
+static ParseResult_t ParseScript(mxml_node_t *scr, PrivateData_t *priv)\r
+{\r
+ bool found = false;\r
+ mxml_node_t *act;\r
+ uint32_t actCnt;\r
+ uint32_t i = 0;\r
+ const char *txt;\r
+ struct UcsXmlScript *scrlist;\r
+ Ucs_Ns_Script_t *script;\r
+ assert(NULL != scr && NULL != priv);\r
+ priv->scriptData.pause = 0;\r
+ scrlist = priv->pScrLst;\r
+ if (!GetCountArray(scr->child, ALL_SCRIPTS, &actCnt, false)) RETURN_ASSERT(Parse_XmlError);\r
+ if (NULL == (script = MCalloc(&priv->objList, actCnt, sizeof(Ucs_Ns_Script_t))))\r
+ RETURN_ASSERT(Parse_MemoryError);\r
+ actCnt = 0;\r
+ /*Iterate all actions*/\r
+ if (!GetElementArray(scr->child, ALL_SCRIPTS, &txt, &act)) RETURN_ASSERT(Parse_XmlError);\r
+ while(act)\r
+ {\r
+ if (0 == strcmp(txt, SCRIPT_MSG_SEND)) {\r
+ ParseResult_t result = ParseScriptMsgSend(act, &script[i], priv);\r
+ if (Parse_Success != result) return result;\r
+ ++actCnt;\r
+ } else if (0 == strcmp(txt, SCRIPT_GPIO_PORT_CREATE)) {\r
+ ParseResult_t result = ParseScriptGpioPortCreate(act, &script[i], priv);\r
+ if (Parse_Success != result) return result;\r
+ ++actCnt;\r
+ } else if (0 == strcmp(txt, SCRIPT_GPIO_PORT_PIN_MODE)) {\r
+ ParseResult_t result = ParseScriptGpioPinMode(act, &script[i], priv);\r
+ if (Parse_Success != result) return result;\r
+ ++actCnt;\r
+ } else if (0 == strcmp(txt, SCRIPT_GPIO_PIN_STATE)) {\r
+ ParseResult_t result = ParseScriptGpioPinState(act, &script[i], priv);\r
+ if (Parse_Success != result) return result;\r
+ ++actCnt;\r
+ } else if (0 == strcmp(txt, SCRIPT_I2C_PORT_CREATE)) {\r
+ ParseResult_t result = ParseScriptPortCreate(act, &script[i], priv);\r
+ if (Parse_Success != result) return result;\r
+ ++actCnt;\r
+ } else if (0 == strcmp(txt, SCRIPT_I2C_PORT_WRITE)) {\r
+ ParseResult_t result = ParseScriptPortWrite(act, &script[i], priv);\r
+ if (Parse_Success != result) return result;\r
+ ++actCnt;\r
+ } else if (0 == strcmp(txt, SCRIPT_I2C_PORT_READ)) {\r
+ ParseResult_t result = ParseScriptPortRead(act, &script[i], priv);\r
+ if (Parse_Success != result) return result;\r
+ ++actCnt;\r
+ } else if (0 == strcmp(txt, SCRIPT_PAUSE)) {\r
+ ParseResult_t result = ParseScriptPause(act, &script[i], priv);\r
+ if (Parse_Success != result) return result;\r
+ } else {\r
+ UcsXml_CB_OnError("Unknown script action:'%s'", 1, txt);\r
+ /*RETURN_ASSERT(Parse_XmlError);*/\r
+ }\r
+ if (!GetElementArray(act, ALL_SCRIPTS, &txt, &act))\r
+ break;\r
+ ++i;\r
+ }\r
+ if (!GetString(scr, NAME, &txt, true))\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ while(NULL != scrlist)\r
+ {\r
+ if (0 == strcmp(txt, scrlist->scriptName))\r
+ {\r
+ Ucs_Rm_Node_t *node = scrlist->node;\r
+ node->script_list_ptr = script;\r
+ node->script_list_size = actCnt;\r
+ found = true;\r
+ }\r
+ scrlist = scrlist->next;\r
+ }\r
+ if(!found)\r
+ {\r
+ UcsXml_CB_OnError("Script defined:'%s', which was never referenced", 1, txt);\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ }\r
+ return Parse_Success;\r
+}\r
+\r
+static bool FillScriptInitialValues(Ucs_Ns_Script_t *scr, PrivateData_t *priv)\r
+{\r
+ assert(NULL != scr && NULL != priv);\r
+ scr->send_cmd = MCalloc(&priv->objList, 1, sizeof(Ucs_Ns_ConfigMsg_t));\r
+ scr->exp_result = MCalloc(&priv->objList, 1, sizeof(Ucs_Ns_ConfigMsg_t));\r
+ assert(scr->send_cmd && scr->exp_result);\r
+ if (NULL == scr->send_cmd || NULL == scr->exp_result) return false;\r
+ scr->pause = priv->scriptData.pause;\r
+ priv->scriptData.pause = 0;\r
+ return true;\r
+}\r
+\r
+static ParseResult_t ParseScriptMsgSend(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)\r
+{\r
+ Ucs_Ns_ConfigMsg_t *req, *res;\r
+ assert(NULL != act && NULL != scr && NULL != priv);\r
+ if (!FillScriptInitialValues(scr, priv)) return Parse_MemoryError;\r
+ req = scr->send_cmd;\r
+ res = scr->exp_result;\r
+ req->InstId = res->InstId = 1;\r
+ if (!GetUInt8(act, FBLOCK_ID, &req->FBlockId, true))\r
+ RETURN_ASSERT(Parse_XmlError);\r
+\r
+ if (!GetUInt16(act, FUNCTION_ID, &req->FunktId, true))\r
+ RETURN_ASSERT(Parse_XmlError);\r
+\r
+ if (!GetUInt8(act, OP_TYPE_REQUEST, &req->OpCode, true))\r
+ RETURN_ASSERT(Parse_XmlError);\r
+\r
+ if (!GetUInt8(act, OP_TYPE_RESPONSE, &res->OpCode, true))\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ \r
+ res->FBlockId = req->FBlockId;\r
+ res->FunktId = req->FunktId;\r
+ GetPayload(act, PAYLOAD_RES_HEX, &res->DataPtr, &res->DataLen, 0, &priv->objList, false);\r
+ \r
+ if (!GetPayload(act, PAYLOAD_REQ_HEX, &req->DataPtr, &req->DataLen, 0, &priv->objList, true))\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ if (0 == req->DataLen || NULL == req->DataPtr)\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ return Parse_Success;\r
+}\r
+\r
+static ParseResult_t ParseScriptGpioPortCreate(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)\r
+{\r
+ uint16_t debounce;\r
+ Ucs_Ns_ConfigMsg_t *req, *res;\r
+ assert(NULL != act && NULL != scr && NULL != priv);\r
+ if (!FillScriptInitialValues(scr, priv))\r
+ RETURN_ASSERT(Parse_MemoryError);\r
+ if (!GetUInt16(act, DEBOUNCE_TIME, &debounce, true))\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ req = scr->send_cmd;\r
+ res = scr->exp_result;\r
+ req->InstId = res->InstId = 1;\r
+ req->FunktId = res->FunktId = 0x701;\r
+ req->OpCode = 0x2;\r
+ res->OpCode = 0xC;\r
+ req->DataLen = 3;\r
+ res->DataLen = 2;\r
+ req->DataPtr = MCalloc(&priv->objList, req->DataLen, 1);\r
+ if (NULL == req->DataPtr) return Parse_MemoryError;\r
+ res->DataPtr = MCalloc(&priv->objList, res->DataLen, 1);\r
+ if (NULL == res->DataPtr) return Parse_MemoryError;\r
+ req->DataPtr[0] = 0; /*GPIO Port instance, always 0*/\r
+ req->DataPtr[1] = MISC_HB(debounce);\r
+ req->DataPtr[2] = MISC_LB(debounce);\r
+\r
+ res->DataPtr[0] = 0x1D;\r
+ res->DataPtr[1] = 0x00;\r
+ return Parse_Success;\r
+}\r
+\r
+static ParseResult_t ParseScriptGpioPinMode(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)\r
+{\r
+#define PORT_HANDLE_OFFSET (2)\r
+ uint8_t *payload;\r
+ uint8_t payloadLen = 0;\r
+ Ucs_Ns_ConfigMsg_t *req, *res;\r
+ assert(NULL != act && NULL != scr && NULL != priv);\r
+ if (!FillScriptInitialValues(scr, priv))\r
+ RETURN_ASSERT(Parse_MemoryError);\r
+ req = scr->send_cmd;\r
+ res = scr->exp_result;\r
+ req->InstId = res->InstId = 1;\r
+ req->FunktId = res->FunktId = 0x703;\r
+ req->OpCode = 0x2;\r
+ res->OpCode = 0xC;\r
+ if (!GetPayload(act, PIN_CONFIG, &payload, &payloadLen, \r
+ PORT_HANDLE_OFFSET, /* First two bytes are reserved for port handle */\r
+ &priv->objList, true)) RETURN_ASSERT(Parse_XmlError);\r
+ payload[0] = 0x1D;\r
+ payload[1] = 0x00;\r
+ req->DataPtr = payload;\r
+ res->DataPtr = payload;\r
+ req->DataLen = payloadLen + PORT_HANDLE_OFFSET;\r
+ res->DataLen = payloadLen + PORT_HANDLE_OFFSET;\r
+ return Parse_Success;\r
+}\r
+\r
+static ParseResult_t ParseScriptGpioPinState(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)\r
+{\r
+ uint16_t mask, data;\r
+ Ucs_Ns_ConfigMsg_t *req, *res;\r
+ assert(NULL != act && NULL != scr && NULL != priv);\r
+ if (!FillScriptInitialValues(scr, priv))\r
+ RETURN_ASSERT(Parse_MemoryError);\r
+ if (!GetUInt16(act, PIN_MASK, &mask, true))\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetUInt16(act, PIN_DATA, &data, true))\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ req = scr->send_cmd;\r
+ res = scr->exp_result;\r
+ req->InstId = res->InstId = 1;\r
+ req->FunktId = res->FunktId = 0x704;\r
+ req->OpCode = 0x2;\r
+ res->OpCode = 0xC;\r
+ req->DataLen = 6;\r
+ res->DataLen = 8;\r
+ req->DataPtr = MCalloc(&priv->objList, req->DataLen, 1);\r
+ if (NULL == req->DataPtr) return Parse_MemoryError;\r
+ res->DataPtr = MCalloc(&priv->objList, res->DataLen, 1);\r
+ if (NULL == res->DataPtr) return Parse_MemoryError;\r
+ req->DataPtr[0] = 0x1D;\r
+ req->DataPtr[1] = 0x00;\r
+ req->DataPtr[2] = MISC_HB(mask);\r
+ req->DataPtr[3] = MISC_LB(mask);\r
+ req->DataPtr[4] = MISC_HB(data);\r
+ req->DataPtr[5] = MISC_LB(data);\r
+ memcpy(res->DataPtr, req->DataPtr, req->DataLen);\r
+ res->DataPtr[6] = 0x00;\r
+ res->DataPtr[7] = 0x00;\r
+ return Parse_Success;\r
+}\r
+\r
+static ParseResult_t ParseScriptPortCreate(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)\r
+{\r
+ const char *txt;\r
+ uint8_t speed;\r
+ Ucs_Ns_ConfigMsg_t *req, *res;\r
+ assert(NULL != act && NULL != scr && NULL != priv);\r
+ if (!FillScriptInitialValues(scr, priv))\r
+ RETURN_ASSERT(Parse_MemoryError);\r
+ if (!GetString(act, I2C_SPEED, &txt, true))\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ if (0 == strcmp(txt, I2C_SPEED_SLOW))\r
+ speed = 0;\r
+ else if (0 == strcmp(txt, I2C_SPEED_FAST))\r
+ speed = 1;\r
+ else RETURN_ASSERT(Parse_XmlError);\r
+ req = scr->send_cmd;\r
+ res = scr->exp_result;\r
+ req->InstId = res->InstId = 1;\r
+ req->FunktId = res->FunktId = 0x6C1;\r
+ req->OpCode = 0x2;\r
+ res->OpCode = 0xC;\r
+ req->DataLen = 4;\r
+ res->DataLen = 2;\r
+ req->DataPtr = MCalloc(&priv->objList, req->DataLen, 1);\r
+ if (NULL == req->DataPtr) return Parse_MemoryError;\r
+ res->DataPtr = MCalloc(&priv->objList, res->DataLen, 1);\r
+ if (NULL == res->DataPtr) return Parse_MemoryError;\r
+ req->DataPtr[0] = 0x00; /* I2C Port Instance always 0 */\r
+ req->DataPtr[1] = 0x00; /* I2C slave address, always 0, because we are Master */\r
+ req->DataPtr[2] = 0x01; /* We are Master */\r
+ req->DataPtr[3] = speed;\r
+\r
+ res->DataPtr[0] = 0x0F;\r
+ res->DataPtr[1] = 0x00;\r
+ return Parse_Success;\r
+}\r
+\r
+static ParseResult_t ParseScriptPortWrite(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)\r
+{\r
+#define HEADER_OFFSET 8\r
+ const char *txt;\r
+ uint8_t mode, blockCount, address, length, payloadLength;\r
+ uint16_t timeout;\r
+ uint8_t *payload;\r
+ Ucs_Ns_ConfigMsg_t *req, *res;\r
+ assert(NULL != act && NULL != scr && NULL != priv);\r
+ if (GetString(act, I2C_WRITE_MODE, &txt, false))\r
+ {\r
+ if (0 == strcmp(txt, I2C_WRITE_MODE_DEFAULT))\r
+ mode = 0;\r
+ else if (0 == strcmp(txt, I2C_WRITE_MODE_REPEAT))\r
+ mode = 1;\r
+ else if (0 == strcmp(txt, I2C_WRITE_MODE_BURST))\r
+ mode = 2;\r
+ } else {\r
+ mode = 0;\r
+ }\r
+ if (!GetUInt8(act, I2C_WRITE_BLOCK_COUNT, &blockCount, false))\r
+ blockCount = 0;\r
+ if (!GetUInt8(act, I2C_SLAVE_ADDRESS, &address, true))\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetUInt8(act, I2C_PAYLOAD_LENGTH, &length, false))\r
+ length = 0;\r
+ if (!GetUInt16(act, I2C_TIMEOUT, &timeout, false))\r
+ timeout = 100;\r
+ if (!GetPayload(act, I2C_PAYLOAD, &payload, &payloadLength, HEADER_OFFSET, &priv->objList, true))\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ if (0 == length)\r
+ length = payloadLength;\r
+ if (!FillScriptInitialValues(scr, priv))\r
+ RETURN_ASSERT(Parse_MemoryError);\r
+ req = scr->send_cmd;\r
+ res = scr->exp_result;\r
+ req->InstId = res->InstId = 1;\r
+ req->FunktId = res->FunktId = 0x6C4;\r
+ req->OpCode = 0x2;\r
+ res->OpCode = 0xC;\r
+ req->DataLen = payloadLength + HEADER_OFFSET;\r
+ res->DataLen = 4;\r
+ req->DataPtr = payload;\r
+ res->DataPtr = MCalloc(&priv->objList, res->DataLen, 1);\r
+ if (NULL == res->DataPtr) return Parse_MemoryError;\r
+\r
+ req->DataPtr[0] = 0x0F;\r
+ req->DataPtr[1] = 0x00;\r
+ req->DataPtr[2] = mode;\r
+ req->DataPtr[3] = blockCount;\r
+ req->DataPtr[4] = address;\r
+ req->DataPtr[5] = length;\r
+ req->DataPtr[6] = MISC_HB(timeout);\r
+ req->DataPtr[7] = MISC_LB(timeout);\r
+\r
+ res->DataPtr[0] = 0x0F;\r
+ res->DataPtr[1] = 0x00;\r
+ res->DataPtr[2] = address;\r
+ if (2 == mode)\r
+ res->DataPtr[3] = blockCount * length;\r
+ else\r
+ res->DataPtr[3] = length;\r
+ return Parse_Success;\r
+}\r
+\r
+static ParseResult_t ParseScriptPortRead(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)\r
+{\r
+ uint8_t address, length;\r
+ uint16_t timeout;\r
+ Ucs_Ns_ConfigMsg_t *req, *res;\r
+ assert(NULL != act && NULL != scr && NULL != priv);\r
+ if (!GetUInt8(act, I2C_SLAVE_ADDRESS, &address, true))\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetUInt8(act, I2C_PAYLOAD_LENGTH, &length, true))\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ if (!GetUInt16(act, I2C_TIMEOUT, &timeout, false))\r
+ timeout = 100;\r
+ if (!FillScriptInitialValues(scr, priv))\r
+ RETURN_ASSERT(Parse_MemoryError);\r
+ req = scr->send_cmd;\r
+ res = scr->exp_result;\r
+ req->InstId = res->InstId = 1;\r
+ req->FunktId = res->FunktId = 0x6C3;\r
+ req->OpCode = 0x2;\r
+ res->OpCode = 0xC;\r
+ req->DataLen = 6;\r
+ res->DataLen = 4;\r
+ req->DataPtr = MCalloc(&priv->objList, req->DataLen, 1);\r
+ if (NULL == req->DataPtr) return Parse_MemoryError;\r
+ res->DataPtr = MCalloc(&priv->objList, res->DataLen, 1);\r
+ if (NULL == res->DataPtr) return Parse_MemoryError;\r
+\r
+ req->DataPtr[0] = 0x0F;\r
+ req->DataPtr[1] = 0x00;\r
+ req->DataPtr[2] = address;\r
+ req->DataPtr[3] = length;\r
+ req->DataPtr[4] = MISC_HB(timeout);\r
+ req->DataPtr[5] = MISC_LB(timeout);\r
+\r
+ res->DataPtr[0] = 0x0F;\r
+ res->DataPtr[1] = 0x00;\r
+ res->DataPtr[2] = address;\r
+ res->DataPtr[3] = length;\r
+ return Parse_Success;\r
+}\r
+\r
+static ParseResult_t ParseScriptPause(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)\r
+{\r
+ assert(NULL != act && NULL != priv);\r
+ if (!GetUInt16(act, PAUSE_MS, &priv->scriptData.pause, true))\r
+ RETURN_ASSERT(Parse_XmlError);\r
+ return Parse_Success;\r
+}\r
+\r
+static ParseResult_t ParseRoutes(UcsXmlVal_t *ucs, PrivateData_t *priv)\r
+{\r
+ uint16_t routeAmount = 0;\r
+ struct UcsXmlRoute *sourceRoute;\r
+ assert(NULL != ucs && NULL != priv);\r
+ /*First: Count the amount of routes and allocate the correct amount*/\r
+ sourceRoute = priv->pRtLst;\r
+ while (NULL != sourceRoute)\r
+ {\r
+ if (!sourceRoute->isSource) /*There can be more sinks than sources, so count them*/\r
+ {\r
+ ++routeAmount;\r
+ }\r
+ sourceRoute = sourceRoute->next;\r
+ }\r
+ if (0 == routeAmount)\r
+ return Parse_Success; /*Its okay to have no routes at all (e.g. MEP traffic only)*/\r
+ ucs->pRoutes = MCalloc(&priv->objList, routeAmount, sizeof(Ucs_Rm_Route_t));\r
+ if (NULL == ucs->pRoutes) RETURN_ASSERT(Parse_MemoryError);\r
+ \r
+ /*Second: Fill allocated structure now*/\r
+ sourceRoute = priv->pRtLst;\r
+ while (NULL != sourceRoute)\r
+ {\r
+ if (sourceRoute->isSource)\r
+ {\r
+ struct UcsXmlRoute *sinkRoute = priv->pRtLst;\r
+ while (NULL != sinkRoute)\r
+ {\r
+ if (sourceRoute != sinkRoute\r
+ && !sinkRoute->isSource\r
+ && (0 == strncmp(sourceRoute->routeName, sinkRoute->routeName, sizeof(sourceRoute->routeName))))\r
+ {\r
+ Ucs_Rm_Route_t *route = &ucs->pRoutes[ucs->routesSize++];\r
+ route->source_endpoint_ptr = sourceRoute->ep;\r
+ route->sink_endpoint_ptr = sinkRoute->ep;\r
+ route->active = sinkRoute->isActive;\r
+ route->route_id = sinkRoute->routeId;\r
+ }\r
+ sinkRoute = sinkRoute->next;\r
+ }\r
+ }\r
+ sourceRoute = sourceRoute->next;\r
+ }\r
+ assert(routeAmount == ucs->routesSize);\r
+ \r
+#ifdef DEBUG\r
+ /* Third perform checks when running in debug mode*/\r
+ {\r
+ Ucs_Xrm_ResourceType_t *job;\r
+ uint16_t i, j;\r
+ for (i = 0; i < routeAmount; i++)\r
+ {\r
+ Ucs_Rm_Route_t *route = &ucs->pRoutes[i];\r
+ assert(NULL != route->source_endpoint_ptr);\r
+ assert(NULL != route->sink_endpoint_ptr);\r
+ assert(NULL != route->source_endpoint_ptr->jobs_list_ptr);\r
+ assert(UCS_RM_EP_SOURCE == route->source_endpoint_ptr->endpoint_type);\r
+ assert(UCS_RM_EP_SINK == route->sink_endpoint_ptr->endpoint_type);\r
+ assert(NULL != route->source_endpoint_ptr->node_obj_ptr);\r
+ assert(NULL != route->sink_endpoint_ptr->node_obj_ptr);\r
+ assert(NULL != route->source_endpoint_ptr->node_obj_ptr->signature_ptr);\r
+ assert(NULL != route->sink_endpoint_ptr->node_obj_ptr->signature_ptr);\r
+ j = 0;\r
+ while((job = ((Ucs_Xrm_ResourceType_t *)route->source_endpoint_ptr->jobs_list_ptr[j])))\r
+ {\r
+ assert(UCS_XRM_RC_TYPE_QOS_CON >= *job);\r
+ ++j;\r
+ }\r
+ j = 0;\r
+ while((job = ((Ucs_Xrm_ResourceType_t *)route->sink_endpoint_ptr->jobs_list_ptr[j])))\r
+ {\r
+ assert(UCS_XRM_RC_TYPE_QOS_CON >= *job);\r
+ ++j;\r
+ }\r
+ }\r
+ }\r
+#endif\r
+ return Parse_Success;\r
+}\r