-/*------------------------------------------------------------------------------------------------*/\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
- Ucs_Xrm_UsbPort_t *usbPort;\r
- Ucs_Xrm_MlbPort_t *mlbPort;\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, NULL };\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 = NULL;\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
- if (val)\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_PORTS, &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(!AddJob(jobList, p.usbPort, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\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 (!AddJob(jobList, p.mlbPort, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\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 (!AddJob(jobList, p.streamPortA, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
- if (!AddJob(jobList, p.streamPortB, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\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
- res->FBlockId = req->FBlockId;\r
- res->FunktId = req->FunktId;\r
-\r
- if (GetUInt8(act, OP_TYPE_RESPONSE, &res->OpCode, false))\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
+/*------------------------------------------------------------------------------------------------*/
+/* 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 <assert.h>
+#include <string.h>
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include "UcsXml_Private.h"
+#include "UcsXml.h"
+
+/************************************************************************/
+/* PRIVATE DECLARATIONS */
+/************************************************************************/
+
+#define COMPILETIME_CHECK(cond) (void)sizeof(int[2 * !!(cond) - 1])
+#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__)
+#define RETURN_ASSERT(result) { UcsXml_CB_OnError("Assertion in file=%s, line=%d", 2, __FILENAME__, __LINE__); return result; }
+#define MISC_HB(value) ((uint8_t)((uint16_t)(value) >> 8))
+#define MISC_LB(value) ((uint8_t)((uint16_t)(value) & (uint16_t)0xFF))
+#define ROUTE_AUTO_ID_START (0x8000)
+
+struct UcsXmlRoute
+{
+ bool isSource;
+ bool isActive;
+ uint16_t routeId;
+ char routeName[32];
+ Ucs_Rm_EndPoint_t *ep;
+ struct UcsXmlRoute *next;
+};
+
+struct UcsXmlScript
+{
+ bool inUse;
+ char scriptName[32];
+ Ucs_Rm_Node_t *node;
+ struct UcsXmlScript *next;
+};
+
+struct UcsXmlJobList
+{
+ Ucs_Xrm_ResObject_t *job;
+ struct UcsXmlJobList *next;
+};
+
+typedef enum
+{
+ MSocket_MOST = 20,
+ MSocket_USB,
+ MSocket_MLB,
+ MSocket_STRM,
+ MSocket_SPLITTER,
+ MSocket_COMBINER
+} MSocketType_t;
+
+typedef enum
+{
+ Parse_Success = 10,
+ Parse_MemoryError,
+ Parse_XmlError
+} ParseResult_t;
+
+typedef struct
+{
+ Ucs_Rm_Node_t *nod;
+ Ucs_Xrm_UsbPort_t *usbPort;
+ Ucs_Xrm_MlbPort_t *mlbPort;
+ Ucs_Xrm_StrmPort_t *strmPortA;
+ Ucs_Xrm_StrmPort_t *strmPortB;
+} NodeData_t;
+
+typedef struct
+{
+ MDataType_t dataType;
+ uint8_t sockCnt;
+ bool syncOffsetNeeded;
+ bool isDeactivated;
+ uint16_t routeId;
+ uint16_t syncOffset;
+ const char *routeName;
+ Ucs_Xrm_ResObject_t *inSocket;
+ Ucs_Xrm_ResObject_t *outSocket;
+ struct UcsXmlJobList *jobList;
+ Ucs_Xrm_Combiner_t *combiner;
+ xmlNode *pendingCombinerMostSockets;
+ Ucs_Sync_MuteMode_t muteMode;
+ Ucs_Avp_IsocPacketSize_t isocPacketSize;
+} ConnectionData_t;
+
+typedef struct
+{
+ uint16_t pause;
+} ScriptData_t;
+
+typedef struct {
+ xmlDoc *root;
+ uint16_t autoRouteId;
+ struct UcsXmlObjectList objList;
+ struct UcsXmlRoute *pRtLst;
+ struct UcsXmlScript *pScrLst;
+ NodeData_t nodeData;
+ ConnectionData_t conData;
+ ScriptData_t scriptData;
+} PrivateData_t;
+
+/************************************************************************/
+/* Constants */
+/************************************************************************/
+
+/*Key section*/
+static const char* UNICENS = "Unicens";
+static const char* PACKET_BW = "AsyncBandwidth";
+static const char* NAME = "Name";
+static const char* ROUTE = "Route";
+static const char* ROUTE_ID = "RouteId";
+static const char* ROUTE_IS_ACTIVE = "IsActive";
+static const char* ENDPOINT_ADDRESS = "EndpointAddress";
+static const char* CHANNEL_ADDRESS = "ChannelAddress";
+static const char* BANDWIDTH = "Bandwidth";
+static const char* BYTES_PER_FRAME = "BytesPerFrame";
+static const char* OFFSET = "Offset";
+static const char* NODE = "Node";
+static const char* CLOCK_CONFIG = "ClockConfig";
+static const char* ADDRESS = "Address";
+static const char* FRAMES_PER_TRANSACTION = "FramesPerTransaction";
+static const char* MUTE_MODE = "MuteMode";
+static const char* MUTE_MODE_NO_MUTING = "NoMuting";
+static const char* MUTE_MODE_MUTE_SIGNAL = "MuteSignal";
+static const char* AVP_PACKET_SIZE = "IsocPacketSize";
+#define SYNC_CONNECTION "SyncConnection"
+#define AVP_CONNECTION "AVPConnection"
+#define DFP_CONNECTION "DFPhaseConnection"
+#define QOS_CONNECTION "QoSConnection"
+#define IPC_CONNECTION "IPCConnection"
+
+static const char* ALL_CONNECTIONS[] = { SYNC_CONNECTION, AVP_CONNECTION,
+ DFP_CONNECTION, QOS_CONNECTION, IPC_CONNECTION, NULL };
+
+#define MOST_SOCKET "MOSTSocket"
+#define USB_SOCKET "USBSocket"
+#define MLB_SOCKET "MediaLBSocket"
+#define STREAM_SOCKET "StreamSocket"
+#define SPLITTER "Splitter"
+#define COMBINER "Combiner"
+static const char* ALL_SOCKETS[] = { MOST_SOCKET, USB_SOCKET, MLB_SOCKET,
+ STREAM_SOCKET, SPLITTER, COMBINER, NULL };
+
+#define MLB_PORT "MediaLBPort"
+#define USB_PORT "USBPort"
+#define STRM_PORT "StreamPort"
+static const char* ALL_PORTS[] = { MLB_PORT, USB_PORT, STRM_PORT, NULL };
+
+static const char* PHYSICAL_LAYER = "PhysicalLayer";
+static const char* DEVICE_INTERFACES = "DeviceInterfaces";
+static const char* STRM_IN_COUNT = "StreamingIfEpInCount";
+static const char* STRM_OUT_COUNT = "StreamingIfEpOutCount";
+
+static const char* STRM_PIN = "StreamPinID";
+static const char* STRM_ALIGN = "DataAlignment";
+
+static const char* SCRIPT = "Script";
+static const char* FBLOCK_ID = "FBlockId";
+static const char* FUNCTION_ID = "FunctionId";
+static const char* OP_TYPE_REQUEST = "OpTypeRequest";
+static const char* OP_TYPE_RESPONSE = "OpTypeResponse";
+static const char* PAYLOAD_REQ_HEX = "PayloadRequest";
+static const char* PAYLOAD_RES_HEX = "PayloadResponse";
+static const char* PAUSE_MS = "WaitTime";
+static const char* DEBOUNCE_TIME = "DebounceTime";
+static const char* PIN_CONFIG = "PinConfiguration";
+static const char* PIN_MASK = "Mask";
+static const char* PIN_DATA = "Data";
+static const char* I2C_SPEED = "Speed";
+static const char* I2C_SPEED_SLOW = "SlowMode";
+static const char* I2C_SPEED_FAST = "FastMode";
+static const char* I2C_WRITE_MODE = "Mode";
+static const char* I2C_WRITE_MODE_DEFAULT = "DefaultMode";
+static const char* I2C_WRITE_MODE_REPEAT = "RepeatedStartMode";
+static const char* I2C_WRITE_MODE_BURST = "BurstMode";
+static const char* I2C_WRITE_BLOCK_COUNT = "BlockCount";
+static const char* I2C_SLAVE_ADDRESS = "Address";
+static const char* I2C_PAYLOAD_LENGTH = "Length";
+static const char* I2C_PAYLOAD = "Payload";
+static const char* I2C_TIMEOUT = "Timeout";
+
+#define SCRIPT_MSG_SEND "MsgSend"
+#define SCRIPT_PAUSE "Pause"
+#define SCRIPT_GPIO_PORT_CREATE "GPIOPortCreate"
+#define SCRIPT_GPIO_PORT_PIN_MODE "GPIOPortPinMode"
+#define SCRIPT_GPIO_PIN_STATE "GPIOPinState"
+#define SCRIPT_I2C_PORT_CREATE "I2CPortCreate"
+#define SCRIPT_I2C_PORT_WRITE "I2CPortWrite"
+#define SCRIPT_I2C_PORT_READ "I2CPortRead"
+static const char* ALL_SCRIPTS[] = { SCRIPT_MSG_SEND, SCRIPT_PAUSE,
+ SCRIPT_GPIO_PORT_CREATE, SCRIPT_GPIO_PORT_PIN_MODE, SCRIPT_GPIO_PIN_STATE,
+ SCRIPT_I2C_PORT_CREATE, SCRIPT_I2C_PORT_WRITE, SCRIPT_I2C_PORT_READ, NULL };
+
+static const char* VALUE_TRUE = "true";
+static const char* VALUE_FALSE = "false";
+static const char* VALUE_1 = "1";
+static const char* VALUE_0 = "0";
+
+/************************************************************************/
+/* Private Function Prototypes */
+/************************************************************************/
+
+static void FreeVal(UcsXmlVal_t *ucs);
+static bool GetElement(xmlNode *element, const char *name, bool goDeep, xmlNode **out, bool mandatory);
+static bool GetElementArray(xmlNode *element, const char *array[], const char **foundName, xmlNode **out);
+static bool GetCount(xmlNode *element, const char *name, uint32_t *out, bool mandatory);
+static bool GetCountArray(xmlNode *element, const char *array[], uint32_t *out, bool mandatory);
+static bool GetString(xmlNode *element, const char *key, const char **out, bool mandatory);
+static bool CheckInteger(const char *val, bool forceHex);
+static bool GetUInt16(xmlNode *element, const char *key, uint16_t *out, bool mandatory);
+static bool GetUInt8(xmlNode *element, const char *key, uint8_t *out, bool mandatory);
+static bool GetSocketType(const char *txt, MSocketType_t *out);
+static bool GetPayload(xmlNode *element, const char *name, uint8_t **pPayload, uint8_t *len, uint8_t offset,
+ struct UcsXmlObjectList *obj, bool mandatory);
+static bool AddJob(struct UcsXmlJobList **joblist, Ucs_Xrm_ResObject_t *job, struct UcsXmlObjectList *objList);
+static Ucs_Xrm_ResObject_t **GetJobList(struct UcsXmlJobList *joblist, struct UcsXmlObjectList *objList);
+static struct UcsXmlJobList *DeepCopyJobList(struct UcsXmlJobList *jobsIn, struct UcsXmlObjectList *objList);
+static void AddRoute(struct UcsXmlRoute **pRtLst, struct UcsXmlRoute *route);
+static void AddScript(struct UcsXmlScript **pScrLst, struct UcsXmlScript *script);
+static ParseResult_t ParseAll(xmlNode * node, UcsXmlVal_t *ucs, PrivateData_t *priv);
+static ParseResult_t ParseNode(xmlNode * node, PrivateData_t *priv);
+static ParseResult_t ParseConnection(xmlNode * node, const char *conType, PrivateData_t *priv);
+static ParseResult_t ParseSocket(xmlNode *soc, bool isSource, MSocketType_t socketType, struct UcsXmlJobList **jobList, PrivateData_t *priv);
+static ParseResult_t ParseScript(xmlNode *scr, PrivateData_t *priv);
+static bool FillScriptInitialValues(Ucs_Ns_Script_t *scr, PrivateData_t *priv);
+static ParseResult_t ParseScriptMsgSend(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);
+static ParseResult_t ParseScriptGpioPortCreate(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);
+static ParseResult_t ParseScriptGpioPinMode(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);
+static ParseResult_t ParseScriptGpioPinState(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);
+static ParseResult_t ParseScriptPortCreate(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);
+static ParseResult_t ParseScriptPortWrite(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);
+static ParseResult_t ParseScriptPortRead(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);
+static ParseResult_t ParseScriptPause(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);
+static ParseResult_t ParseRoutes(UcsXmlVal_t *ucs, PrivateData_t *priv);
+static bool IsAutoRouteId(uint16_t id, PrivateData_t *priv);
+
+/************************************************************************/
+/* Public Functions */
+/************************************************************************/
+
+UcsXmlVal_t *UcsXml_Parse(const char *xmlString)
+{
+ xmlDoc *root;
+ UcsXmlVal_t *val = NULL;
+ ParseResult_t result = Parse_MemoryError;
+ xmlNode *tree;
+ if (NULL == (root = xmlReadMemory( xmlString, strlen( xmlString ), "config.xml", NULL, 0 ))) goto ERROR;
+ tree = xmlDocGetRootElement(root);
+ if (0 != strcmp(UNICENS, (const char *)tree->name)) goto ERROR;
+ /*Do not use MCalloc for the root element*/
+ val = calloc(1, sizeof(UcsXmlVal_t));
+ if (!val) goto ERROR;
+ val->pInternal = calloc(1, sizeof(PrivateData_t));
+ if (!val->pInternal) goto ERROR;
+ ((PrivateData_t *)val->pInternal)->root = root;
+ result = ParseAll(tree, val, val->pInternal);
+ if (Parse_Success == result)
+ return val;
+ERROR:
+ if (Parse_MemoryError == result)
+ UcsXml_CB_OnError("XML memory error, aborting..", 0);
+ else
+ UcsXml_CB_OnError("XML parsing error, aborting..", 0);
+ assert(false);
+ if (!root)
+ xmlFreeDoc(root);
+ if (val)
+ FreeVal(val);
+ return NULL;
+}
+
+void UcsXml_FreeVal(UcsXmlVal_t *val)
+{
+ FreeVal(val);
+}
+
+/************************************************************************/
+/* Private Function Implementations */
+/************************************************************************/
+
+void FreeVal(UcsXmlVal_t *ucs)
+{
+ PrivateData_t *priv;
+ if (NULL == ucs || NULL == ucs->pInternal)
+ return;
+ priv = ucs->pInternal;
+ FreeObjList(&priv->objList);
+
+ if (!priv->root)
+ xmlFreeDoc(priv->root);
+
+ free(ucs->pInternal);
+ free(ucs);
+}
+
+static bool GetElement(xmlNode *element, const char *name, bool goDeep, xmlNode **out, bool mandatory)
+{
+ xmlNode *n = element;
+ if (NULL == n || NULL == name || NULL == out) return false;
+ if (goDeep && GetElement(n->children, name, goDeep, out, false))
+ {
+ return true;
+ }
+ while ((n = n->next))
+ {
+ if (XML_ELEMENT_NODE != n->type)
+ continue;
+ if (0 == strcmp(name, (const char *)n->name))
+ {
+ *out = n;
+ return true;
+ }
+ else if (goDeep && GetElement(n->children, name, goDeep, out, false))
+ {
+ return true;
+ }
+ }
+ if (mandatory)
+ UcsXml_CB_OnError("Can not find tag <%s>", 1, name);
+ return false;
+}
+
+static bool GetElementArray(xmlNode *element, const char *array[], const char **foundName, xmlNode **out)
+{
+ xmlNode *n = element;
+ if (NULL == n || NULL == array || NULL == foundName || NULL == out) return false;
+ while ((n = n->next))
+ {
+ uint32_t i;
+ for (i = 0; NULL != array[i]; i++)
+ {
+ if (0 == strcmp(array[i], (const char *)n->name))
+ {
+ *foundName = array[i];
+ *out = n;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+static bool GetCount(xmlNode *element, const char *name, uint32_t *out, bool mandatory)
+{
+ uint32_t cnt = 0;
+ xmlNode *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 GetCountArray(xmlNode *element, const char *array[], uint32_t *out, bool mandatory)
+{
+ const char *tmp;
+ uint32_t cnt = 0;
+ xmlNode *n;
+ if (NULL == element || NULL == array) return false;
+ n = element;
+ while(NULL != n)
+ {
+ if(!GetElementArray(n, array, &tmp, &n))
+ break;
+ ++cnt;
+ }
+ if (mandatory && 0 == cnt)
+ {
+ UcsXml_CB_OnError("element count is zero, searched with string array", 0);
+ return false;
+ }
+ *out = cnt;
+ return true;
+}
+
+static bool GetString(xmlNode *element, const char *key, const char **out, bool mandatory)
+{
+ struct _xmlAttr *curAttr;
+ if (NULL == element || NULL == key) return false;
+ curAttr = element->properties;
+ do
+ {
+ if (XML_ATTRIBUTE_NODE != curAttr->type)
+ continue;
+ if (0 == strcmp(key, (const char *)curAttr->name))
+ {
+ struct _xmlNode *valAttr = curAttr->children;
+ do
+ {
+ if (XML_TEXT_NODE != valAttr->type)
+ continue;
+ *out = (const char *)valAttr->content;
+ return true;
+ }
+ while (NULL != (valAttr = valAttr->next));
+ }
+ }
+ while (NULL != (curAttr = curAttr->next));
+ if (mandatory)
+ UcsXml_CB_OnError("Can not find attribute='%s' from element <%s>",
+ 2, key, element->name);
+ return false;
+}
+
+static bool CheckInteger(const char *value, bool forceHex)
+{
+ bool hex = forceHex;
+ int32_t len;
+ if (!value) return false;
+ len = strlen(value);
+ if (len >= 3 && '0' == value[0] && 'x' == value[1])
+ {
+ hex = true;
+ value += 2;
+ }
+ while(value[0])
+ {
+ bool valid = false;
+ uint8_t v = value[0];
+ if (v >= '0' && v <= '9') valid = true;
+ if (hex)
+ {
+ if (v >= 'a' && v <= 'f') valid = true;
+ if (v >= 'A' && v <= 'F') valid = true;
+ }
+ if (!valid) return false;
+ ++value;
+ }
+ return true;
+}
+
+static bool GetUInt16(xmlNode *element, const char *key, uint16_t *out, bool mandatory)
+{
+ long int value;
+ const char* txt;
+ if (!GetString(element, key, &txt, mandatory)) return false;
+ if (!CheckInteger(txt, false))
+ {
+ UcsXml_CB_OnError("key='%s' contained invalid integer='%s'", 2, key, txt);
+ return false;
+ }
+ value = strtol( txt, NULL, 0 );
+ if (value > 0xFFFF)
+ {
+ UcsXml_CB_OnError("key='%s' is out of range='%d'", 2, key, value);
+ return false;
+ }
+ *out = value;
+ return true;
+}
+
+static bool GetUInt8(xmlNode *element, const char *key, uint8_t *out, bool mandatory)
+{
+ long int value;
+ const char* txt;
+ if (!GetString(element, key, &txt, mandatory)) return false;
+ if (!CheckInteger(txt, false))
+ {
+ UcsXml_CB_OnError("key='%s' contained invalid integer='%s'", 2, key, txt);
+ return false;
+ }
+ value = strtol( txt, NULL, 0 );
+ if (value > 0xFF)
+ {
+ UcsXml_CB_OnError("key='%s' is out of range='%d'", 2, key, value);
+ return false;
+ }
+ *out = value;
+ return true;
+}
+
+static bool GetDataType(const char *txt, MDataType_t *out)
+{
+ if (NULL == txt || NULL == out) return false;
+ if (0 == strcmp(SYNC_CONNECTION, txt)) {
+ *out = SYNC_DATA;
+ } else if (0 == strcmp(AVP_CONNECTION, txt)) {
+ *out = AV_PACKETIZED;
+ } else if (0 == strcmp(QOS_CONNECTION, txt)) {
+ *out = QOS_IP;
+ } else if (0 == strcmp(DFP_CONNECTION, txt)) {
+ *out = DISC_FRAME_PHASE;
+ } else if (0 == strcmp(IPC_CONNECTION, txt)) {
+ *out = IPC_PACKET;
+ } else {
+ UcsXml_CB_OnError("Unknown data type : '%s'", 1, txt);
+ return false;
+ }
+ return true;
+}
+
+static bool GetSocketType(const char *txt, MSocketType_t *out)
+{
+ if (0 == strcmp(txt, MOST_SOCKET)) {
+ *out = MSocket_MOST;
+ } else if (0 == strcmp(txt, USB_SOCKET)) {
+ *out = MSocket_USB;
+ } else if (0 == strcmp(txt, MLB_SOCKET)) {
+ *out = MSocket_MLB;
+ } else if (0 == strcmp(txt, STREAM_SOCKET)) {
+ *out = MSocket_STRM;
+ } else if (0 == strcmp(txt, SPLITTER)) {
+ *out = MSocket_SPLITTER;
+ } else if (0 == strcmp(txt, COMBINER)) {
+ *out = MSocket_COMBINER;
+ } else {
+ UcsXml_CB_OnError("Unknown port : '%s'", 1, txt);
+ return false;
+ }
+ return true;
+}
+
+static bool GetPayload(xmlNode *element, const char *name, uint8_t **pPayload, uint8_t *outLen, uint8_t offset, 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, offset + 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;
+ }
+ if (!CheckInteger(token, true))
+ {
+ UcsXml_CB_OnError("Script payload contains non valid hex number='%s'", 1, token);
+ free(txtCopy);
+ assert(false);
+ return 0;
+ }
+ p[offset + len++] = strtol( token, NULL, 16 );
+ token = strtok_r( NULL, " ,.-", &tkPtr );
+ }
+ *outLen = len;
+ return true;
+}
+
+static bool AddJob(struct UcsXmlJobList **joblist, Ucs_Xrm_ResObject_t *job, struct UcsXmlObjectList *objList)
+{
+ struct UcsXmlJobList *tail;
+ if (NULL == joblist || NULL == job)
+ return false;
+ assert(UCS_XRM_RC_TYPE_QOS_CON >= *((Ucs_Xrm_ResourceType_t *)job));
+ if (NULL == joblist[0])
+ {
+ joblist[0] = MCalloc(objList, 1, sizeof(struct UcsXmlJobList));
+ if (NULL == joblist[0]) return false;;
+ joblist[0]->job = job;
+ return true;
+ }
+ tail = joblist[0];
+ while(tail->next) tail = tail->next;
+ tail->next = MCalloc(objList, 1, sizeof(struct UcsXmlJobList));
+ if (NULL == tail->next) return false;
+ tail->next->job = job;
+ return true;
+}
+
+static Ucs_Xrm_ResObject_t **GetJobList(struct UcsXmlJobList *joblist, struct UcsXmlObjectList *objList)
+{
+ Ucs_Xrm_ResObject_t **outJob;
+ uint32_t count = 0;
+ struct UcsXmlJobList *tail;
+ if (NULL == joblist)
+ return false;
+ /*First: Get amount of stored jobs by enumerate all*/
+ tail = joblist;
+ while(tail)
+ {
+ ++count;
+ tail = tail->next;
+ }
+ if (0 == count)
+ return false;
+ /*Second: Allocate count+1 elements (NULL terminated) and copy pointers*/
+ outJob = MCalloc(objList, (count + 1), sizeof(Ucs_Xrm_ResObject_t *));
+ if (NULL == outJob)
+ return false;
+ tail = joblist;
+ count = 0;
+ while(tail)
+ {
+ outJob[count++] = tail->job;
+ tail = tail->next;
+ }
+ return outJob;
+}
+
+static struct UcsXmlJobList *DeepCopyJobList(struct UcsXmlJobList *jobsIn, struct UcsXmlObjectList *objList)
+{
+ struct UcsXmlJobList *jobsOut, *tail;
+ if (NULL == jobsIn || NULL == objList)
+ return NULL;
+ jobsOut = tail = MCalloc(objList, 1, sizeof(struct UcsXmlJobList));
+ if (NULL == jobsOut) { assert(false); return NULL; }
+ while(jobsIn)
+ {
+ tail->job = jobsIn->job;
+ if (jobsIn->next)
+ {
+ tail->next = MCalloc(objList, 1, sizeof(struct UcsXmlJobList));
+ if (NULL == tail->next) { assert(false); return NULL; }
+ tail = tail->next;
+ }
+ jobsIn = jobsIn->next;
+ }
+ return jobsOut;
+}
+
+static void AddRoute(struct UcsXmlRoute **pRtLst, struct UcsXmlRoute *route)
+{
+ struct UcsXmlRoute *tail;
+ if (NULL == pRtLst || NULL == route)
+ {
+ assert(false);
+ 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 UcsXmlScript **pScrLst, struct UcsXmlScript *script)
+{
+ struct UcsXmlScript *tail;
+ if (NULL == pScrLst || NULL == script)
+ {
+ assert(false);
+ 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(xmlNode *tree, UcsXmlVal_t *ucs, PrivateData_t *priv)
+{
+ uint32_t nodeCount;
+ xmlNode *sub;
+ ParseResult_t result;
+ priv->autoRouteId = ROUTE_AUTO_ID_START;
+ if (!GetCount(tree, NODE, &nodeCount, true))
+ RETURN_ASSERT(Parse_XmlError);
+
+ ucs->pNod = MCalloc(&priv->objList, nodeCount, sizeof(Ucs_Rm_Node_t));
+ if (NULL == ucs->pNod) RETURN_ASSERT(Parse_MemoryError);
+
+ if (!GetUInt16(tree, PACKET_BW, &ucs->packetBw, true))
+ RETURN_ASSERT(Parse_XmlError);
+
+ /*Iterate all nodes*/
+ if (!GetElement(tree, NODE, true, &sub, true))
+ RETURN_ASSERT(Parse_XmlError);
+ while(sub)
+ {
+ const char *conType;
+ xmlNode *con;
+ memset(&priv->nodeData, 0, sizeof(NodeData_t));
+ priv->nodeData.nod = &ucs->pNod[ucs->nodSize];
+ if (Parse_Success != (result = ParseNode(sub, priv)))
+ return result;
+ /*/Iterate all connections. Node without any connection is also valid.*/
+ if (GetElementArray(sub->children, ALL_CONNECTIONS, &conType, &con))
+ {
+ while(con)
+ {
+ const char *socTypeStr;
+ MSocketType_t socType;
+ xmlNode *soc;
+ memset(&priv->conData, 0, sizeof(ConnectionData_t));
+ if (Parse_Success != (result = ParseConnection(con, conType, priv)))
+ return result;
+ /*Iterate all sockets*/
+ if(!GetElementArray(con->children, ALL_SOCKETS, &socTypeStr, &soc)) RETURN_ASSERT(Parse_XmlError);
+ while(soc)
+ {
+ if (!GetSocketType(socTypeStr, &socType)) RETURN_ASSERT(Parse_XmlError);
+ if (Parse_Success != (result = ParseSocket(soc, (0 == priv->conData.sockCnt), socType, &priv->conData.jobList, priv)))
+ return result;
+ ++priv->conData.sockCnt;
+ if(!GetElementArray(soc, ALL_SOCKETS, &socTypeStr, &soc))
+ break;
+ }
+ if(!GetElementArray(con, ALL_CONNECTIONS, &conType, &con))
+ break;
+ }
+ }
+ ++ucs->nodSize;
+ if (!GetElement(sub, NODE, false, &sub, false))
+ break;
+ }
+
+ /*Fill route structures*/
+ result = ParseRoutes(ucs, priv);
+ if (Parse_MemoryError == result) RETURN_ASSERT(Parse_MemoryError)
+ else if (Parse_XmlError == result) RETURN_ASSERT(Parse_XmlError);
+
+ /*Iterate all scripts. No scripts at all is allowed*/
+ if(GetElement(tree, SCRIPT, true, &sub, false))
+ {
+ bool found = true;
+ struct UcsXmlScript *scrlist = priv->pScrLst;
+ while(sub)
+ {
+ result = ParseScript(sub, priv);
+ if (Parse_MemoryError == result) RETURN_ASSERT(Parse_MemoryError)
+ else if (Parse_XmlError == result) RETURN_ASSERT(Parse_XmlError);
+ if(!GetElement(sub, SCRIPT, false, &sub, false))
+ break;
+ }
+ /* Check if all scripts where referenced */
+ while(NULL != scrlist)
+ {
+ if (!scrlist->inUse)
+ {
+ UcsXml_CB_OnError("Script not defined:'%s', used by node=0x%X", 1, scrlist->scriptName, scrlist->node->signature_ptr->node_address);
+ found = false;
+ }
+ scrlist = scrlist->next;
+ }
+ if (!found)
+ RETURN_ASSERT(Parse_XmlError);
+ }
+ return result;
+}
+
+static ParseResult_t ParseNode(xmlNode *node, PrivateData_t *priv)
+{
+ const char *txt;
+ xmlNode *port;
+ Ucs_Signature_t *signature;
+ assert(NULL != node && NULL != priv);
+ priv->nodeData.nod->signature_ptr = MCalloc(&priv->objList, 1, sizeof(Ucs_Signature_t));
+ signature = priv->nodeData.nod->signature_ptr;
+ if(NULL == signature) RETURN_ASSERT(Parse_MemoryError);
+ if (!GetUInt16(node, ADDRESS, &signature->node_address, true))
+ RETURN_ASSERT(Parse_XmlError);
+ if (GetString(node, SCRIPT, &txt, false))
+ {
+ struct UcsXmlScript *scr = MCalloc(&priv->objList, 1, sizeof(struct UcsXmlScript));
+ if (NULL == scr) RETURN_ASSERT(Parse_MemoryError);
+ scr->node = priv->nodeData.nod;
+ strncpy(scr->scriptName, txt, sizeof(scr->scriptName));
+ AddScript(&priv->pScrLst, scr);
+ }
+ /*Iterate all ports*/
+ if(GetElementArray(node->children, ALL_PORTS, &txt, &port))
+ {
+ while(port)
+ {
+ if (0 == (strcmp(txt, MLB_PORT)))
+ {
+ struct MlbPortParameters p;
+ p.list = &priv->objList;
+ if (!GetString(port, CLOCK_CONFIG, &p.clockConfig, true)) RETURN_ASSERT(Parse_XmlError);
+ if (!GetMlbPort(&priv->nodeData.mlbPort, &p)) RETURN_ASSERT(Parse_XmlError);
+ }
+ else if (0 == (strcmp(txt, USB_PORT)))
+ {
+ struct UsbPortParameters p;
+ p.list = &priv->objList;
+ if (!GetString(port, PHYSICAL_LAYER, &p.physicalLayer, true)) RETURN_ASSERT(Parse_XmlError);
+ if (!GetString(port, DEVICE_INTERFACES, &p.deviceInterfaces, true)) RETURN_ASSERT(Parse_XmlError);
+ if (!GetString(port, STRM_IN_COUNT, &p.streamInCount, true)) RETURN_ASSERT(Parse_XmlError);
+ if (!GetString(port, STRM_OUT_COUNT, &p.streamOutCount, true)) RETURN_ASSERT(Parse_XmlError);
+ if (!GetUsbPort(&priv->nodeData.usbPort, &p)) RETURN_ASSERT(Parse_XmlError);
+ }
+ else if (0 == (strcmp(txt, STRM_PORT)))
+ {
+ struct StrmPortParameters p;
+ p.list = &priv->objList;
+ p.index = 0;
+ if (!GetString(port, CLOCK_CONFIG, &p.clockConfig, true)) RETURN_ASSERT(Parse_XmlError);
+ if (!GetString(port, STRM_ALIGN, &p.dataAlignment, true)) RETURN_ASSERT(Parse_XmlError);
+ if (!GetStrmPort(&priv->nodeData.strmPortA, &p)) RETURN_ASSERT(Parse_XmlError);
+ p.index = 1;
+ if (!GetStrmPort(&priv->nodeData.strmPortB, &p)) RETURN_ASSERT(Parse_XmlError);
+ }
+ else
+ {
+ UcsXml_CB_OnError("Unknown Port:'%s'", 1, txt);
+ RETURN_ASSERT(Parse_XmlError);
+ }
+ if(!GetElementArray(port, ALL_PORTS, &txt, &port))
+ break;
+ }
+ }
+ return Parse_Success;;
+}
+
+static ParseResult_t ParseConnection(xmlNode * node, const char *conType, PrivateData_t *priv)
+{
+ assert(NULL != node && NULL != priv);
+ if (NULL == conType) RETURN_ASSERT(Parse_XmlError);
+ if (!GetDataType(conType, &priv->conData.dataType)) RETURN_ASSERT(Parse_XmlError);
+ switch (priv->conData.dataType)
+ {
+ case SYNC_DATA:
+ {
+ const char *txt;
+ if (GetString(node, MUTE_MODE, &txt, false))
+ {
+ if (0 == strcmp(txt, MUTE_MODE_NO_MUTING))
+ priv->conData.muteMode = UCS_SYNC_MUTE_MODE_NO_MUTING;
+ else if (0 == strcmp(txt, MUTE_MODE_MUTE_SIGNAL))
+ priv->conData.muteMode = UCS_SYNC_MUTE_MODE_MUTE_SIGNAL;
+ else
+ {
+ UcsXml_CB_OnError("ParseConnection: MuteMode='%s' not implemented", 1, txt);
+ RETURN_ASSERT(Parse_XmlError);
+ }
+ }
+ else
+ {
+ /*Be tolerant, this is an optional feature*/
+ priv->conData.muteMode = UCS_SYNC_MUTE_MODE_NO_MUTING;
+ }
+ break;
+ }
+ case AV_PACKETIZED:
+ {
+ uint16_t size;
+ if (GetUInt16(node, AVP_PACKET_SIZE, &size, false))
+ {
+ switch(size)
+ {
+ case 188:
+ priv->conData.isocPacketSize = UCS_ISOC_PCKT_SIZE_188;
+ break;
+ case 196:
+ priv->conData.isocPacketSize = UCS_ISOC_PCKT_SIZE_196;
+ break;
+ case 206:
+ priv->conData.isocPacketSize = UCS_ISOC_PCKT_SIZE_206;
+ break;
+ default:
+ UcsXml_CB_OnError("ParseConnection: %s='%d' not implemented", 2, AVP_PACKET_SIZE, size);
+ RETURN_ASSERT(Parse_XmlError);
+ }
+ }
+ else
+ {
+ /*Be tolerant, this is an optional feature*/
+ priv->conData.isocPacketSize = UCS_ISOC_PCKT_SIZE_188;
+ }
+ break;
+ }
+ default:
+ UcsXml_CB_OnError("ParseConnection: Datatype='%s' not implemented", 1, conType);
+ RETURN_ASSERT(Parse_XmlError);
+ break;
+ }
+ return Parse_Success;
+}
+
+static ParseResult_t ParseSocket(xmlNode *soc, bool isSource, MSocketType_t socketType, struct UcsXmlJobList **jobList, PrivateData_t *priv)
+{
+ Ucs_Xrm_ResObject_t **targetSock;
+ assert(NULL != soc && NULL != priv);
+ targetSock = isSource ? &priv->conData.inSocket : &priv->conData.outSocket;
+ switch(socketType)
+ {
+ case MSocket_MOST:
+ {
+ const char* txt;
+ struct MostSocketParameters p;
+ /* If there is an combiner stored, add it now into job list (right before MOST socket) */
+ if (priv->conData.combiner)
+ if (!AddJob(jobList, priv->conData.combiner, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
+
+ p.list = &priv->objList;
+ p.isSource = isSource;
+ p.dataType = priv->conData.dataType;
+ if (!GetUInt16(soc, BANDWIDTH, &p.bandwidth, true)) RETURN_ASSERT(Parse_XmlError);
+ if (!GetString(soc, ROUTE, &priv->conData.routeName, true)) RETURN_ASSERT(Parse_XmlError);
+ if (GetString(soc, ROUTE_IS_ACTIVE, &txt, false))
+ {
+ if (0 == strcmp(txt, VALUE_TRUE) || 0 == strcmp(txt, VALUE_1))
+ priv->conData.isDeactivated = false;
+ else if (0 == strcmp(txt, VALUE_FALSE) || 0 == strcmp(txt, VALUE_0))
+ priv->conData.isDeactivated = true;
+ else RETURN_ASSERT(Parse_XmlError);
+ } else {
+ priv->conData.isDeactivated = false;
+ }
+ if (!GetUInt16(soc, ROUTE_ID, &priv->conData.routeId, false))
+ priv->conData.routeId = ++priv->autoRouteId;
+ if (priv->conData.syncOffsetNeeded)
+ {
+ if (!GetUInt16(soc, OFFSET, &priv->conData.syncOffset, true)) RETURN_ASSERT(Parse_XmlError);
+ }
+ if (!GetMostSocket((Ucs_Xrm_MostSocket_t **)targetSock, &p)) RETURN_ASSERT(Parse_XmlError);
+ if (!AddJob(jobList, *targetSock, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
+ break;
+ }
+ case MSocket_USB:
+ {
+ struct UsbSocketParameters p;
+ p.list = &priv->objList;
+ p.isSource = isSource;
+ p.dataType = priv->conData.dataType;
+ if (priv->nodeData.usbPort)
+ {
+ p.usbPort = priv->nodeData.usbPort;
+ } else {
+ if (!GetUsbPortDefaultCreated(&p.usbPort, &priv->objList))
+ RETURN_ASSERT(Parse_XmlError);
+ priv->nodeData.usbPort = (Ucs_Xrm_UsbPort_t *)p.usbPort;
+ }
+ if(!AddJob(jobList, p.usbPort, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
+ if (!GetString(soc, ENDPOINT_ADDRESS, &p.endpointAddress, true)) RETURN_ASSERT(Parse_XmlError);
+ if (!GetString(soc, FRAMES_PER_TRANSACTION, &p.framesPerTrans, true)) RETURN_ASSERT(Parse_XmlError);
+ if (!GetUsbSocket((Ucs_Xrm_UsbSocket_t **)targetSock, &p)) RETURN_ASSERT(Parse_XmlError);
+ if (!AddJob(jobList, *targetSock, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
+ break;
+ }
+ case MSocket_MLB:
+ {
+ struct MlbSocketParameters p;
+ p.list = &priv->objList;
+ p.isSource = isSource;
+ p.dataType = priv->conData.dataType;
+ if (priv->nodeData.mlbPort)
+ {
+ p.mlbPort = priv->nodeData.mlbPort;
+ } else {
+ if (!GetMlbPortDefaultCreated(&p.mlbPort, &priv->objList))
+ RETURN_ASSERT(Parse_XmlError);
+ priv->nodeData.mlbPort = (Ucs_Xrm_MlbPort_t *)p.mlbPort;
+ }
+ if (!AddJob(jobList, p.mlbPort, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
+ if (!GetUInt16(soc, BANDWIDTH, &p.bandwidth, true)) RETURN_ASSERT(Parse_XmlError);
+ if (!GetString(soc, CHANNEL_ADDRESS, &p.channelAddress, true)) RETURN_ASSERT(Parse_XmlError);
+ if (!GetMlbSocket((Ucs_Xrm_MlbSocket_t **)targetSock, &p)) RETURN_ASSERT(Parse_XmlError);
+ if (!AddJob(jobList, *targetSock, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
+ break;
+ }
+ case MSocket_STRM:
+ {
+ struct StrmSocketParameters p;
+ p.list = &priv->objList;
+ p.isSource = isSource;
+ p.dataType = priv->conData.dataType;
+ p.streamPortA = priv->nodeData.strmPortA;
+ p.streamPortB = priv->nodeData.strmPortB;
+ if (!AddJob(jobList, p.streamPortA, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
+ if (!AddJob(jobList, p.streamPortB, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
+ if (!GetUInt16(soc, BANDWIDTH, &p.bandwidth, true)) RETURN_ASSERT(Parse_XmlError);
+ if (!GetString(soc, STRM_PIN, &p.streamPin, true)) RETURN_ASSERT(Parse_XmlError);
+ if (!GetStrmSocket((Ucs_Xrm_StrmSocket_t **)targetSock, &p)) RETURN_ASSERT(Parse_XmlError);
+ if (!AddJob(jobList, *targetSock, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
+ break;
+ }
+ case MSocket_SPLITTER:
+ {
+ xmlNode *mostSoc;
+ struct SplitterParameters p;
+ if (isSource)
+ {
+ UcsXml_CB_OnError("Splitter can not be used as input socket", 0);
+ RETURN_ASSERT(Parse_XmlError);
+ }
+ p.list = &priv->objList;
+ if (!GetUInt16(soc, BYTES_PER_FRAME, &p.bytesPerFrame, true)) RETURN_ASSERT(Parse_XmlError);
+ /* Current input socket will be stored inside splitter
+ * and splitter will become the new input socket */
+ if (!(p.inSoc = priv->conData.inSocket)) RETURN_ASSERT(Parse_XmlError);
+ if (!GetSplitter((Ucs_Xrm_Splitter_t **)&priv->conData.inSocket, &p)) RETURN_ASSERT(Parse_XmlError);
+ if (!AddJob(jobList, priv->conData.inSocket, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
+ if (!GetElement(soc->children, MOST_SOCKET, false, &mostSoc, true))
+ RETURN_ASSERT(Parse_XmlError);
+ priv->conData.syncOffsetNeeded = true;
+
+ while(mostSoc)
+ {
+ struct UcsXmlJobList *jobListCopy = DeepCopyJobList(*jobList, &priv->objList);
+ if (!ParseSocket(mostSoc, false, MSocket_MOST, &jobListCopy, priv)) RETURN_ASSERT(Parse_XmlError);
+ if (!GetElement(mostSoc, MOST_SOCKET, false, &mostSoc, false))
+ return Parse_Success; /* Do not break here, otherwise an additional invalid route will be created */
+ }
+ break;
+ }
+ case MSocket_COMBINER:
+ {
+ struct CombinerParameters p;
+ if (!isSource)
+ {
+ UcsXml_CB_OnError("Combiner can not be used as output socket", 0);
+ RETURN_ASSERT(Parse_XmlError);
+ }
+ p.list = &priv->objList;
+ if (!GetUInt16(soc, BYTES_PER_FRAME, &p.bytesPerFrame, true)) RETURN_ASSERT(Parse_XmlError);
+ if (!GetCombiner(&priv->conData.combiner, &p)) RETURN_ASSERT(Parse_XmlError);
+ priv->conData.syncOffsetNeeded = true;
+ if (!GetElement(soc->children, MOST_SOCKET, false, &priv->conData.pendingCombinerMostSockets, true))
+ RETURN_ASSERT(Parse_XmlError);
+ break;
+ }
+ default:
+ RETURN_ASSERT(Parse_XmlError);
+ }
+ /*Handle Pending Combiner Tasks*/
+ if (NULL != priv->conData.outSocket && NULL != priv->conData.combiner &&
+ NULL != priv->conData.pendingCombinerMostSockets)
+ {
+ xmlNode *tmp = priv->conData.pendingCombinerMostSockets;
+ priv->conData.pendingCombinerMostSockets = NULL;
+ /* Current output socket will be stored inside combiner
+ * and combiner will become the new output socket */
+ priv->conData.combiner->port_socket_obj_ptr = priv->conData.outSocket;
+ priv->conData.outSocket = priv->conData.combiner;
+ while(tmp)
+ {
+ struct UcsXmlJobList *jobListCopy = DeepCopyJobList(*jobList, &priv->objList);
+ if (!ParseSocket(tmp, true, MSocket_MOST, &jobListCopy, priv)) RETURN_ASSERT(Parse_XmlError);
+ if (!GetElement(tmp, MOST_SOCKET, false, &tmp, false))
+ return Parse_Success; /* Do not break here, otherwise an additional invalid route will be created */
+ }
+ }
+ /*Connect in and out socket once they are created*/
+ if (priv->conData.inSocket && priv->conData.outSocket)
+ {
+ bool mostIsInput;
+ bool mostIsOutput;
+ Ucs_Rm_EndPoint_t *ep;
+ struct UcsXmlRoute *route;
+ switch(priv->conData.dataType)
+ {
+ case SYNC_DATA:
+ {
+ Ucs_Xrm_SyncCon_t *con = MCalloc(&priv->objList, 1, sizeof(Ucs_Xrm_SyncCon_t));
+ if (NULL == con) RETURN_ASSERT(Parse_MemoryError);
+ if (!AddJob(jobList, con, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
+ con->resource_type = UCS_XRM_RC_TYPE_SYNC_CON;
+ con->socket_in_obj_ptr = priv->conData.inSocket;
+ con->socket_out_obj_ptr = priv->conData.outSocket;
+ con->mute_mode = priv->conData.muteMode;
+ con->offset = priv->conData.syncOffset;
+ break;
+ }
+ case AV_PACKETIZED:
+ {
+ Ucs_Xrm_AvpCon_t *con = MCalloc(&priv->objList, 1, sizeof(Ucs_Xrm_AvpCon_t));
+ if (NULL == con) RETURN_ASSERT(Parse_MemoryError);
+ if (!AddJob(jobList, con, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
+ con->resource_type = UCS_XRM_RC_TYPE_AVP_CON;
+ con->socket_in_obj_ptr = priv->conData.inSocket;
+ con->socket_out_obj_ptr = priv->conData.outSocket;
+ con->isoc_packet_size = priv->conData.isocPacketSize;
+ break;
+ }
+ default:
+ UcsXml_CB_OnError("Could not connect sockets, data type not implemented: %d", 1, priv->conData.dataType);
+ RETURN_ASSERT(Parse_XmlError);
+ break;
+ }
+ ep = MCalloc(&priv->objList, 1, sizeof(Ucs_Rm_EndPoint_t));
+ if (NULL == ep) RETURN_ASSERT(Parse_MemoryError);
+
+ mostIsInput = (UCS_XRM_RC_TYPE_MOST_SOCKET == *((Ucs_Xrm_ResourceType_t *)priv->conData.inSocket));
+ mostIsOutput = (UCS_XRM_RC_TYPE_MOST_SOCKET == *((Ucs_Xrm_ResourceType_t *)priv->conData.outSocket));
+ if (!mostIsInput && !mostIsOutput)
+ {
+ UcsXml_CB_OnError("At least one MOST socket required per connection", 0);
+ RETURN_ASSERT(Parse_XmlError);
+ }
+ ep->endpoint_type = mostIsOutput ? UCS_RM_EP_SOURCE : UCS_RM_EP_SINK;
+ ep->jobs_list_ptr = GetJobList(*jobList, &priv->objList);
+ if(NULL == ep->jobs_list_ptr) RETURN_ASSERT(Parse_MemoryError);
+ ep->node_obj_ptr = priv->nodeData.nod;
+ route = MCalloc(&priv->objList, 1, sizeof(struct UcsXmlRoute));
+ if (NULL == route) RETURN_ASSERT(Parse_MemoryError);
+ route->isSource = mostIsOutput;
+ route->isActive = !priv->conData.isDeactivated;
+ route->routeId = priv->conData.routeId;
+ route->ep = ep;
+ assert(NULL != priv->conData.routeName);
+ strncpy(route->routeName, priv->conData.routeName, sizeof(route->routeName));
+ AddRoute(&priv->pRtLst, route);
+ }
+ return Parse_Success;
+}
+
+static ParseResult_t ParseScript(xmlNode *scr, PrivateData_t *priv)
+{
+ bool found = false;
+ xmlNode *act;
+ uint32_t actCnt;
+ uint32_t i = 0;
+ const char *txt;
+ struct UcsXmlScript *scrlist;
+ Ucs_Ns_Script_t *script;
+ assert(NULL != scr && NULL != priv);
+ priv->scriptData.pause = 0;
+ scrlist = priv->pScrLst;
+ if (!GetCountArray(scr->children, ALL_SCRIPTS, &actCnt, false)) RETURN_ASSERT(Parse_XmlError);
+ if (NULL == (script = MCalloc(&priv->objList, actCnt, sizeof(Ucs_Ns_Script_t))))
+ RETURN_ASSERT(Parse_MemoryError);
+ actCnt = 0;
+ /*Iterate all actions*/
+ if (!GetElementArray(scr->children, ALL_SCRIPTS, &txt, &act)) RETURN_ASSERT(Parse_XmlError);
+ while(act)
+ {
+ if (0 == strcmp(txt, SCRIPT_MSG_SEND)) {
+ ParseResult_t result = ParseScriptMsgSend(act, &script[i], priv);
+ if (Parse_Success != result) return result;
+ ++actCnt;
+ } else if (0 == strcmp(txt, SCRIPT_GPIO_PORT_CREATE)) {
+ ParseResult_t result = ParseScriptGpioPortCreate(act, &script[i], priv);
+ if (Parse_Success != result) return result;
+ ++actCnt;
+ } else if (0 == strcmp(txt, SCRIPT_GPIO_PORT_PIN_MODE)) {
+ ParseResult_t result = ParseScriptGpioPinMode(act, &script[i], priv);
+ if (Parse_Success != result) return result;
+ ++actCnt;
+ } else if (0 == strcmp(txt, SCRIPT_GPIO_PIN_STATE)) {
+ ParseResult_t result = ParseScriptGpioPinState(act, &script[i], priv);
+ if (Parse_Success != result) return result;
+ ++actCnt;
+ } else if (0 == strcmp(txt, SCRIPT_I2C_PORT_CREATE)) {
+ ParseResult_t result = ParseScriptPortCreate(act, &script[i], priv);
+ if (Parse_Success != result) return result;
+ ++actCnt;
+ } else if (0 == strcmp(txt, SCRIPT_I2C_PORT_WRITE)) {
+ ParseResult_t result = ParseScriptPortWrite(act, &script[i], priv);
+ if (Parse_Success != result) return result;
+ ++actCnt;
+ } else if (0 == strcmp(txt, SCRIPT_I2C_PORT_READ)) {
+ ParseResult_t result = ParseScriptPortRead(act, &script[i], priv);
+ if (Parse_Success != result) return result;
+ ++actCnt;
+ } else if (0 == strcmp(txt, SCRIPT_PAUSE)) {
+ ParseResult_t result = ParseScriptPause(act, &script[i], priv);
+ if (Parse_Success != result) return result;
+ } else {
+ UcsXml_CB_OnError("Unknown script action:'%s'", 1, txt);
+ RETURN_ASSERT(Parse_XmlError);
+ }
+ if (!GetElementArray(act, ALL_SCRIPTS, &txt, &act))
+ break;
+ ++i;
+ }
+ if (!GetString(scr, NAME, &txt, true))
+ RETURN_ASSERT(Parse_XmlError);
+ while(NULL != scrlist)
+ {
+ if (0 == strcmp(txt, scrlist->scriptName))
+ {
+ Ucs_Rm_Node_t *node = scrlist->node;
+ node->script_list_ptr = script;
+ node->script_list_size = actCnt;
+ scrlist->inUse = true;
+ found = true;
+ }
+ scrlist = scrlist->next;
+ }
+ if(!found)
+ {
+ UcsXml_CB_OnError("Script defined:'%s', which was never referenced", 1, txt);
+ RETURN_ASSERT(Parse_XmlError);
+ }
+ return Parse_Success;
+}
+
+static bool FillScriptInitialValues(Ucs_Ns_Script_t *scr, PrivateData_t *priv)
+{
+ assert(NULL != scr && NULL != priv);
+ scr->send_cmd = MCalloc(&priv->objList, 1, sizeof(Ucs_Ns_ConfigMsg_t));
+ scr->exp_result = MCalloc(&priv->objList, 1, sizeof(Ucs_Ns_ConfigMsg_t));
+ assert(scr->send_cmd && scr->exp_result);
+ if (NULL == scr->send_cmd || NULL == scr->exp_result) return false;
+ scr->pause = priv->scriptData.pause;
+ priv->scriptData.pause = 0;
+ return true;
+}
+
+static ParseResult_t ParseScriptMsgSend(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)
+{
+ Ucs_Ns_ConfigMsg_t *req, *res;
+ assert(NULL != act && NULL != scr && NULL != priv);
+ if (!FillScriptInitialValues(scr, priv)) return Parse_MemoryError;
+ req = scr->send_cmd;
+ res = scr->exp_result;
+ req->InstId = res->InstId = 1;
+ if (!GetUInt8(act, FBLOCK_ID, &req->FBlockId, true))
+ RETURN_ASSERT(Parse_XmlError);
+
+ if (!GetUInt16(act, FUNCTION_ID, &req->FunktId, true))
+ RETURN_ASSERT(Parse_XmlError);
+
+ if (!GetUInt8(act, OP_TYPE_REQUEST, &req->OpCode, true))
+ RETURN_ASSERT(Parse_XmlError);
+
+ res->FBlockId = req->FBlockId;
+ res->FunktId = req->FunktId;
+
+ if (GetUInt8(act, OP_TYPE_RESPONSE, &res->OpCode, false))
+ GetPayload(act, PAYLOAD_RES_HEX, &res->DataPtr, &res->DataLen, 0, &priv->objList, false);
+
+ if (!GetPayload(act, PAYLOAD_REQ_HEX, &req->DataPtr, &req->DataLen, 0, &priv->objList, true))
+ RETURN_ASSERT(Parse_XmlError);
+ if (0 == req->DataLen || NULL == req->DataPtr)
+ RETURN_ASSERT(Parse_XmlError);
+ return Parse_Success;
+}
+
+static ParseResult_t ParseScriptGpioPortCreate(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)
+{
+ uint16_t debounce;
+ Ucs_Ns_ConfigMsg_t *req, *res;
+ assert(NULL != act && NULL != scr && NULL != priv);
+ if (!FillScriptInitialValues(scr, priv))
+ RETURN_ASSERT(Parse_MemoryError);
+ if (!GetUInt16(act, DEBOUNCE_TIME, &debounce, true))
+ RETURN_ASSERT(Parse_XmlError);
+ req = scr->send_cmd;
+ res = scr->exp_result;
+ req->InstId = res->InstId = 1;
+ req->FunktId = res->FunktId = 0x701;
+ req->OpCode = 0x2;
+ res->OpCode = 0xC;
+ req->DataLen = 3;
+ res->DataLen = 2;
+ req->DataPtr = MCalloc(&priv->objList, req->DataLen, 1);
+ if (NULL == req->DataPtr) return Parse_MemoryError;
+ res->DataPtr = MCalloc(&priv->objList, res->DataLen, 1);
+ if (NULL == res->DataPtr) return Parse_MemoryError;
+ req->DataPtr[0] = 0; /*GPIO Port instance, always 0*/
+ req->DataPtr[1] = MISC_HB(debounce);
+ req->DataPtr[2] = MISC_LB(debounce);
+
+ res->DataPtr[0] = 0x1D;
+ res->DataPtr[1] = 0x00;
+ return Parse_Success;
+}
+
+static ParseResult_t ParseScriptGpioPinMode(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)
+{
+#define PORT_HANDLE_OFFSET (2)
+ uint8_t *payload;
+ uint8_t payloadLen = 0;
+ Ucs_Ns_ConfigMsg_t *req, *res;
+ assert(NULL != act && NULL != scr && NULL != priv);
+ if (!FillScriptInitialValues(scr, priv))
+ RETURN_ASSERT(Parse_MemoryError);
+ req = scr->send_cmd;
+ res = scr->exp_result;
+ req->InstId = res->InstId = 1;
+ req->FunktId = res->FunktId = 0x703;
+ req->OpCode = 0x2;
+ res->OpCode = 0xC;
+ if (!GetPayload(act, PIN_CONFIG, &payload, &payloadLen,
+ PORT_HANDLE_OFFSET, /* First two bytes are reserved for port handle */
+ &priv->objList, true)) RETURN_ASSERT(Parse_XmlError);
+ payload[0] = 0x1D;
+ payload[1] = 0x00;
+ req->DataPtr = payload;
+ res->DataPtr = payload;
+ req->DataLen = payloadLen + PORT_HANDLE_OFFSET;
+ res->DataLen = payloadLen + PORT_HANDLE_OFFSET;
+ return Parse_Success;
+}
+
+static ParseResult_t ParseScriptGpioPinState(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)
+{
+ uint16_t mask, data;
+ Ucs_Ns_ConfigMsg_t *req, *res;
+ assert(NULL != act && NULL != scr && NULL != priv);
+ if (!FillScriptInitialValues(scr, priv))
+ RETURN_ASSERT(Parse_MemoryError);
+ if (!GetUInt16(act, PIN_MASK, &mask, true))
+ RETURN_ASSERT(Parse_XmlError);
+ if (!GetUInt16(act, PIN_DATA, &data, true))
+ RETURN_ASSERT(Parse_XmlError);
+ req = scr->send_cmd;
+ res = scr->exp_result;
+ req->InstId = res->InstId = 1;
+ req->FunktId = res->FunktId = 0x704;
+ req->OpCode = 0x2;
+ res->OpCode = 0xC;
+ req->DataLen = 6;
+ res->DataLen = 8;
+ req->DataPtr = MCalloc(&priv->objList, req->DataLen, 1);
+ if (NULL == req->DataPtr) return Parse_MemoryError;
+ res->DataPtr = MCalloc(&priv->objList, res->DataLen, 1);
+ if (NULL == res->DataPtr) return Parse_MemoryError;
+ req->DataPtr[0] = 0x1D;
+ req->DataPtr[1] = 0x00;
+ req->DataPtr[2] = MISC_HB(mask);
+ req->DataPtr[3] = MISC_LB(mask);
+ req->DataPtr[4] = MISC_HB(data);
+ req->DataPtr[5] = MISC_LB(data);
+ memcpy(res->DataPtr, req->DataPtr, req->DataLen);
+ res->DataPtr[6] = 0x00;
+ res->DataPtr[7] = 0x00;
+ return Parse_Success;
+}
+
+static ParseResult_t ParseScriptPortCreate(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)
+{
+ const char *txt;
+ uint8_t speed;
+ Ucs_Ns_ConfigMsg_t *req, *res;
+ assert(NULL != act && NULL != scr && NULL != priv);
+ if (!FillScriptInitialValues(scr, priv))
+ RETURN_ASSERT(Parse_MemoryError);
+ if (!GetString(act, I2C_SPEED, &txt, true))
+ RETURN_ASSERT(Parse_XmlError);
+ if (0 == strcmp(txt, I2C_SPEED_SLOW))
+ speed = 0;
+ else if (0 == strcmp(txt, I2C_SPEED_FAST))
+ speed = 1;
+ else
+ {
+ UcsXml_CB_OnError("Invalid I2C speed:'%s'", 1, txt);
+ RETURN_ASSERT(Parse_XmlError);
+ }
+ req = scr->send_cmd;
+ res = scr->exp_result;
+ req->InstId = res->InstId = 1;
+ req->FunktId = res->FunktId = 0x6C1;
+ req->OpCode = 0x2;
+ res->OpCode = 0xC;
+ req->DataLen = 4;
+ res->DataLen = 2;
+ req->DataPtr = MCalloc(&priv->objList, req->DataLen, 1);
+ if (NULL == req->DataPtr) return Parse_MemoryError;
+ res->DataPtr = MCalloc(&priv->objList, res->DataLen, 1);
+ if (NULL == res->DataPtr) return Parse_MemoryError;
+ req->DataPtr[0] = 0x00; /* I2C Port Instance always 0 */
+ req->DataPtr[1] = 0x00; /* I2C slave address, always 0, because we are Master */
+ req->DataPtr[2] = 0x01; /* We are Master */
+ req->DataPtr[3] = speed;
+
+ res->DataPtr[0] = 0x0F;
+ res->DataPtr[1] = 0x00;
+ return Parse_Success;
+}
+
+static ParseResult_t ParseScriptPortWrite(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)
+{
+#define HEADER_OFFSET 8
+ const char *txt;
+ uint8_t mode, blockCount, address, length, payloadLength;
+ uint16_t timeout;
+ uint8_t *payload;
+ Ucs_Ns_ConfigMsg_t *req, *res;
+ assert(NULL != act && NULL != scr && NULL != priv);
+ if (GetString(act, I2C_WRITE_MODE, &txt, false))
+ {
+ if (0 == strcmp(txt, I2C_WRITE_MODE_DEFAULT))
+ mode = 0;
+ else if (0 == strcmp(txt, I2C_WRITE_MODE_REPEAT))
+ mode = 1;
+ else if (0 == strcmp(txt, I2C_WRITE_MODE_BURST))
+ mode = 2;
+ else
+ {
+ UcsXml_CB_OnError("Invalid I2C mode:'%s'", 1, txt);
+ RETURN_ASSERT(Parse_XmlError);
+ }
+ } else {
+ mode = 0;
+ }
+ if (!GetUInt8(act, I2C_WRITE_BLOCK_COUNT, &blockCount, false))
+ blockCount = 0;
+ if (!GetUInt8(act, I2C_SLAVE_ADDRESS, &address, true))
+ RETURN_ASSERT(Parse_XmlError);
+ if (!GetUInt8(act, I2C_PAYLOAD_LENGTH, &length, false))
+ length = 0;
+ if (!GetUInt16(act, I2C_TIMEOUT, &timeout, false))
+ timeout = 100;
+ if (!GetPayload(act, I2C_PAYLOAD, &payload, &payloadLength, HEADER_OFFSET, &priv->objList, true))
+ RETURN_ASSERT(Parse_XmlError);
+ if (0 == length)
+ length = payloadLength;
+ if (!FillScriptInitialValues(scr, priv))
+ RETURN_ASSERT(Parse_MemoryError);
+ req = scr->send_cmd;
+ res = scr->exp_result;
+ req->InstId = res->InstId = 1;
+ req->FunktId = res->FunktId = 0x6C4;
+ req->OpCode = 0x2;
+ res->OpCode = 0xC;
+ req->DataLen = payloadLength + HEADER_OFFSET;
+ res->DataLen = 4;
+ req->DataPtr = payload;
+ res->DataPtr = MCalloc(&priv->objList, res->DataLen, 1);
+ if (NULL == res->DataPtr) return Parse_MemoryError;
+
+ req->DataPtr[0] = 0x0F;
+ req->DataPtr[1] = 0x00;
+ req->DataPtr[2] = mode;
+ req->DataPtr[3] = blockCount;
+ req->DataPtr[4] = address;
+ req->DataPtr[5] = length;
+ req->DataPtr[6] = MISC_HB(timeout);
+ req->DataPtr[7] = MISC_LB(timeout);
+
+ res->DataPtr[0] = 0x0F;
+ res->DataPtr[1] = 0x00;
+ res->DataPtr[2] = address;
+ if (2 == mode)
+ res->DataPtr[3] = blockCount * length;
+ else
+ res->DataPtr[3] = length;
+ return Parse_Success;
+}
+
+static ParseResult_t ParseScriptPortRead(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)
+{
+ uint8_t address, length;
+ uint16_t timeout;
+ Ucs_Ns_ConfigMsg_t *req, *res;
+ assert(NULL != act && NULL != scr && NULL != priv);
+ if (!GetUInt8(act, I2C_SLAVE_ADDRESS, &address, true))
+ RETURN_ASSERT(Parse_XmlError);
+ if (!GetUInt8(act, I2C_PAYLOAD_LENGTH, &length, true))
+ RETURN_ASSERT(Parse_XmlError);
+ if (!GetUInt16(act, I2C_TIMEOUT, &timeout, false))
+ timeout = 100;
+ if (!FillScriptInitialValues(scr, priv))
+ RETURN_ASSERT(Parse_MemoryError);
+ req = scr->send_cmd;
+ res = scr->exp_result;
+ req->InstId = res->InstId = 1;
+ req->FunktId = res->FunktId = 0x6C3;
+ req->OpCode = 0x2;
+ res->OpCode = 0xC;
+ req->DataLen = 6;
+ res->DataLen = 4;
+ req->DataPtr = MCalloc(&priv->objList, req->DataLen, 1);
+ if (NULL == req->DataPtr) return Parse_MemoryError;
+ res->DataPtr = MCalloc(&priv->objList, res->DataLen, 1);
+ if (NULL == res->DataPtr) return Parse_MemoryError;
+
+ req->DataPtr[0] = 0x0F;
+ req->DataPtr[1] = 0x00;
+ req->DataPtr[2] = address;
+ req->DataPtr[3] = length;
+ req->DataPtr[4] = MISC_HB(timeout);
+ req->DataPtr[5] = MISC_LB(timeout);
+
+ res->DataPtr[0] = 0x0F;
+ res->DataPtr[1] = 0x00;
+ res->DataPtr[2] = address;
+ res->DataPtr[3] = length;
+ return Parse_Success;
+}
+
+static ParseResult_t ParseScriptPause(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)
+{
+ assert(NULL != act && NULL != priv);
+ if (!GetUInt16(act, PAUSE_MS, &priv->scriptData.pause, true))
+ RETURN_ASSERT(Parse_XmlError);
+ return Parse_Success;
+}
+
+static ParseResult_t ParseRoutes(UcsXmlVal_t *ucs, PrivateData_t *priv)
+{
+ uint16_t routeAmount = 0;
+ struct UcsXmlRoute *sourceRoute;
+ assert(NULL != ucs && NULL != priv);
+ /*First: Count the amount of routes and allocate the correct amount*/
+ sourceRoute = priv->pRtLst;
+ while (NULL != sourceRoute)
+ {
+ if (sourceRoute->isSource)
+ {
+ struct UcsXmlRoute *sinkRoute = priv->pRtLst;
+ while (NULL != sinkRoute)
+ {
+ if (sourceRoute != sinkRoute
+ && !sinkRoute->isSource
+ && (0 == strncmp(sourceRoute->routeName, sinkRoute->routeName, sizeof(sourceRoute->routeName))))
+ {
+ routeAmount++;
+ }
+ sinkRoute = sinkRoute->next;
+ }
+ }
+ sourceRoute = sourceRoute->next;
+ }
+ if (0 == routeAmount)
+ return Parse_Success; /*Its okay to have no routes at all (e.g. MEP traffic only)*/
+ ucs->pRoutes = MCalloc(&priv->objList, routeAmount, sizeof(Ucs_Rm_Route_t));
+ if (NULL == ucs->pRoutes) RETURN_ASSERT(Parse_MemoryError);
+
+ /*Second: Fill allocated structure now*/
+ sourceRoute = priv->pRtLst;
+ while (NULL != sourceRoute)
+ {
+ if (sourceRoute->isSource)
+ {
+ struct UcsXmlRoute *sinkRoute = priv->pRtLst;
+ while (NULL != sinkRoute)
+ {
+ if (sourceRoute != sinkRoute
+ && !sinkRoute->isSource
+ && (0 == strncmp(sourceRoute->routeName, sinkRoute->routeName, sizeof(sourceRoute->routeName))))
+ {
+ Ucs_Rm_Route_t *route;
+ if(ucs->routesSize >= routeAmount)
+ {
+ RETURN_ASSERT(Parse_MemoryError);
+ }
+ route = &ucs->pRoutes[ucs->routesSize++];
+ route->source_endpoint_ptr = sourceRoute->ep;
+ route->sink_endpoint_ptr = sinkRoute->ep;
+ if (!IsAutoRouteId(sourceRoute->routeId, priv))
+ {
+ route->active = sourceRoute->isActive;
+ route->route_id = sourceRoute->routeId;
+ }
+ else
+ {
+ route->active = sinkRoute->isActive;
+ route->route_id = sinkRoute->routeId;
+ }
+ }
+ sinkRoute = sinkRoute->next;
+ }
+ }
+ sourceRoute = sourceRoute->next;
+ }
+
+#ifdef DEBUG
+ /* Third perform checks when running in debug mode*/
+ {
+ Ucs_Xrm_ResourceType_t *job;
+ uint16_t i, j;
+ for (i = 0; i < routeAmount; i++)
+ {
+ Ucs_Rm_Route_t *route = &ucs->pRoutes[i];
+ assert(NULL != route->source_endpoint_ptr);
+ assert(NULL != route->sink_endpoint_ptr);
+ assert(NULL != route->source_endpoint_ptr->jobs_list_ptr);
+ assert(UCS_RM_EP_SOURCE == route->source_endpoint_ptr->endpoint_type);
+ assert(UCS_RM_EP_SINK == route->sink_endpoint_ptr->endpoint_type);
+ assert(NULL != route->source_endpoint_ptr->node_obj_ptr);
+ assert(NULL != route->sink_endpoint_ptr->node_obj_ptr);
+ assert(NULL != route->source_endpoint_ptr->node_obj_ptr->signature_ptr);
+ assert(NULL != route->sink_endpoint_ptr->node_obj_ptr->signature_ptr);
+ j = 0;
+ while((job = ((Ucs_Xrm_ResourceType_t *)route->source_endpoint_ptr->jobs_list_ptr[j])))
+ {
+ assert(UCS_XRM_RC_TYPE_QOS_CON >= *job);
+ ++j;
+ }
+ j = 0;
+ while((job = ((Ucs_Xrm_ResourceType_t *)route->sink_endpoint_ptr->jobs_list_ptr[j])))
+ {
+ assert(UCS_XRM_RC_TYPE_QOS_CON >= *job);
+ ++j;
+ }
+ }
+ }
+#endif
+ return Parse_Success;
+}
+
+static bool IsAutoRouteId(uint16_t id, PrivateData_t *priv)
+{
+ assert(NULL != priv);
+ return (id >= ROUTE_AUTO_ID_START && id <= priv->autoRouteId);
+}