Change all UNICENS words to upper case
[apps/agl-service-unicens.git] / ucs2-interface / ucs-xml / UcsXml.c
1 /*------------------------------------------------------------------------------------------------*/\r
2 /* UNICENS XML Parser                                                                             */\r
3 /* Copyright 2017, Microchip Technology Inc. and its subsidiaries.                                */\r
4 /*                                                                                                */\r
5 /* Redistribution and use in source and binary forms, with or without                             */\r
6 /* modification, are permitted provided that the following conditions are met:                    */\r
7 /*                                                                                                */\r
8 /* 1. Redistributions of source code must retain the above copyright notice, this                 */\r
9 /*    list of conditions and the following disclaimer.                                            */\r
10 /*                                                                                                */\r
11 /* 2. Redistributions in binary form must reproduce the above copyright notice,                   */\r
12 /*    this list of conditions and the following disclaimer in the documentation                   */\r
13 /*    and/or other materials provided with the distribution.                                      */\r
14 /*                                                                                                */\r
15 /* 3. Neither the name of the copyright holder nor the names of its                               */\r
16 /*    contributors may be used to endorse or promote products derived from                        */\r
17 /*    this software without specific prior written permission.                                    */\r
18 /*                                                                                                */\r
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"                    */\r
20 /* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE                      */\r
21 /* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE                 */\r
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE                   */\r
23 /* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL                     */\r
24 /* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR                     */\r
25 /* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER                     */\r
26 /* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,                  */\r
27 /* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE                  */\r
28 /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           */\r
29 /*------------------------------------------------------------------------------------------------*/\r
30 #include <assert.h>\r
31 #include <string.h>\r
32 #include "mxml.h"\r
33 #include "UcsXml_Private.h"\r
34 #include "UcsXml.h"\r
35 \r
36 /************************************************************************/\r
37 /* PRIVATE DECLARATIONS                                                 */\r
38 /************************************************************************/\r
39 \r
40 #define COMPILETIME_CHECK(cond)  (void)sizeof(int[2 * !!(cond) - 1])\r
41 #define RETURN_ASSERT(result) { assert(false); return result; }\r
42 #define MISC_HB(value)      ((uint8_t)((uint16_t)(value) >> 8))\r
43 #define MISC_LB(value)      ((uint8_t)((uint16_t)(value) & (uint16_t)0xFF))\r
44 \r
45 struct UcsXmlRoute\r
46 {\r
47     bool isSource;\r
48     bool isActive;\r
49     uint16_t routeId;\r
50     char routeName[32];\r
51     Ucs_Rm_EndPoint_t *ep;\r
52     struct UcsXmlRoute *next;\r
53 };\r
54 \r
55 struct UcsXmlScript\r
56 {\r
57     char scriptName[32];\r
58     Ucs_Rm_Node_t *node;\r
59     struct UcsXmlScript *next;\r
60 };\r
61 \r
62 struct UcsXmlJobList\r
63 {\r
64     Ucs_Xrm_ResObject_t *job;\r
65     struct UcsXmlJobList *next;\r
66 };\r
67 \r
68 typedef enum\r
69 {\r
70     MSocket_MOST = 20,\r
71     MSocket_USB,\r
72     MSocket_MLB,\r
73     MSocket_STRM,\r
74     MSocket_SPLITTER,\r
75     MSocket_COMBINER\r
76 } MSocketType_t;\r
77 \r
78 typedef enum\r
79 {\r
80     Parse_Success = 10,\r
81     Parse_MemoryError,\r
82     Parse_XmlError\r
83 } ParseResult_t;\r
84 \r
85 typedef struct\r
86 {\r
87     Ucs_Rm_Node_t *nod;\r
88     Ucs_Xrm_UsbPort_t *usbPort;\r
89     Ucs_Xrm_MlbPort_t *mlbPort;\r
90     Ucs_Xrm_StrmPort_t *strmPortA;\r
91     Ucs_Xrm_StrmPort_t *strmPortB;\r
92 } NodeData_t;\r
93 \r
94 typedef struct\r
95 {\r
96     MDataType_t dataType;\r
97     uint8_t sockCnt;\r
98     bool syncOffsetNeeded;\r
99     bool isDeactivated;\r
100     uint16_t routeId;\r
101     uint16_t syncOffset;\r
102     const char *routeName;\r
103     Ucs_Xrm_ResObject_t *inSocket;\r
104     Ucs_Xrm_ResObject_t *outSocket;\r
105     struct UcsXmlJobList *jobList;\r
106     Ucs_Xrm_Combiner_t *combiner;\r
107     mxml_node_t *pendingCombinerMostSockets;\r
108     Ucs_Sync_MuteMode_t muteMode;\r
109     Ucs_Avp_IsocPacketSize_t isocPacketSize;\r
110 } ConnectionData_t;\r
111 \r
112 typedef struct\r
113 {\r
114     uint16_t pause;\r
115 } ScriptData_t;\r
116 \r
117 typedef struct {\r
118     uint16_t autoRouteId;\r
119     struct UcsXmlObjectList objList;\r
120     struct UcsXmlRoute *pRtLst;\r
121     struct UcsXmlScript *pScrLst;\r
122     NodeData_t nodeData;\r
123     ConnectionData_t conData;\r
124     ScriptData_t scriptData;\r
125 } PrivateData_t;\r
126 \r
127 /************************************************************************/\r
128 /* Constants                                                            */\r
129 /************************************************************************/\r
130 \r
131 /*Key section*/\r
132 static const char* UNICENS =                "Unicens";\r
133 static const char* PACKET_BW =              "AsyncBandwidth";\r
134 static const char* NAME =                   "Name";\r
135 static const char* ROUTE =                  "Route";\r
136 static const char* ROUTE_ID =               "RouteId";\r
137 static const char* ROUTE_IS_ACTIVE =        "IsActive";\r
138 static const char* ENDPOINT_ADDRESS =       "EndpointAddress";\r
139 static const char* CHANNEL_ADDRESS =        "ChannelAddress";\r
140 static const char* BANDWIDTH =              "Bandwidth";\r
141 static const char* BYTES_PER_FRAME =        "BytesPerFrame";\r
142 static const char* OFFSET =                 "Offset";\r
143 static const char* NODE =                   "Node";\r
144 static const char* CLOCK_CONFIG =           "ClockConfig";\r
145 static const char* ADDRESS =                "Address";\r
146 static const char* FRAMES_PER_TRANSACTION = "FramesPerTransaction";\r
147 static const char* MUTE_MODE =              "MuteMode";\r
148 static const char* MUTE_MODE_NO_MUTING =    "NoMuting";\r
149 static const char* MUTE_MODE_MUTE_SIGNAL =  "MuteSignal";\r
150 static const char* AVP_PACKET_SIZE =        "IsocPacketSize";\r
151 #define SYNC_CONNECTION                     "SyncConnection"\r
152 #define AVP_CONNECTION                      "AVPConnection"\r
153 #define DFP_CONNECTION                      "DFPhaseConnection"\r
154 #define QOS_CONNECTION                      "QoSConnection"\r
155 #define IPC_CONNECTION                      "IPCConnection"\r
156 \r
157 static const char* ALL_CONNECTIONS[] = { SYNC_CONNECTION, AVP_CONNECTION,\r
158                         DFP_CONNECTION, QOS_CONNECTION, IPC_CONNECTION, NULL };\r
159 \r
160 #define MOST_SOCKET                         "MOSTSocket"\r
161 #define USB_SOCKET                          "USBSocket"\r
162 #define MLB_SOCKET                          "MediaLBSocket"\r
163 #define STREAM_SOCKET                       "StreamSocket"\r
164 #define SPLITTER                            "Splitter"\r
165 #define COMBINER                            "Combiner"\r
166 static const char* ALL_SOCKETS[] = { MOST_SOCKET, USB_SOCKET, MLB_SOCKET,\r
167                         STREAM_SOCKET, SPLITTER, COMBINER, NULL };\r
168 \r
169 #define MLB_PORT                            "MediaLBPort"\r
170 #define USB_PORT                            "USBPort"\r
171 #define STRM_PORT                           "StreamPort"\r
172 static const char* ALL_PORTS[] = { MLB_PORT, USB_PORT, STRM_PORT, NULL };\r
173 \r
174 static const char* PHYSICAL_LAYER =         "PhysicalLayer";\r
175 static const char* DEVICE_INTERFACES =      "DeviceInterfaces";\r
176 static const char* STRM_IN_COUNT =          "StreamingIfEpInCount";\r
177 static const char* STRM_OUT_COUNT =         "StreamingIfEpOutCount";\r
178 \r
179 static const char* STRM_PIN =                "StreamPinID";\r
180 static const char* STRM_ALIGN =              "DataAlignment";\r
181 \r
182 static const char* SCRIPT =                 "Script";\r
183 static const char* FBLOCK_ID =              "FBlockId";\r
184 static const char* FUNCTION_ID =            "FunctionId";\r
185 static const char* OP_TYPE_REQUEST =        "OpTypeRequest";\r
186 static const char* OP_TYPE_RESPONSE =       "OpTypeResponse";\r
187 static const char* PAYLOAD_REQ_HEX =        "PayloadRequest";\r
188 static const char* PAYLOAD_RES_HEX =        "PayloadResponse";\r
189 static const char* PAUSE_MS =               "WaitTime";\r
190 static const char* DEBOUNCE_TIME =          "DebounceTime";\r
191 static const char* PIN_CONFIG =             "PinConfiguration";\r
192 static const char* PIN_MASK =               "Mask";\r
193 static const char* PIN_DATA =               "Data";\r
194 static const char* I2C_SPEED =              "Speed";\r
195 static const char* I2C_SPEED_SLOW =         "SlowMode";\r
196 static const char* I2C_SPEED_FAST =         "FastMode";\r
197 static const char* I2C_WRITE_MODE =         "Mode";\r
198 static const char* I2C_WRITE_MODE_DEFAULT = "DefaultMode";\r
199 static const char* I2C_WRITE_MODE_REPEAT =  "RepeatedStartMode";\r
200 static const char* I2C_WRITE_MODE_BURST =   "BurstMode";\r
201 static const char* I2C_WRITE_BLOCK_COUNT =  "BlockCount";\r
202 static const char* I2C_SLAVE_ADDRESS =      "Address";\r
203 static const char* I2C_PAYLOAD_LENGTH =     "Length";\r
204 static const char* I2C_PAYLOAD =            "Payload";\r
205 static const char* I2C_TIMEOUT =            "Timeout";\r
206 \r
207 #define SCRIPT_MSG_SEND                     "MsgSend"\r
208 #define SCRIPT_PAUSE                        "Pause"\r
209 #define SCRIPT_GPIO_PORT_CREATE             "GPIOPortCreate"\r
210 #define SCRIPT_GPIO_PORT_PIN_MODE           "GPIOPortPinMode"\r
211 #define SCRIPT_GPIO_PIN_STATE               "GPIOPinState"\r
212 #define SCRIPT_I2C_PORT_CREATE              "I2CPortCreate"\r
213 #define SCRIPT_I2C_PORT_WRITE               "I2CPortWrite"\r
214 #define SCRIPT_I2C_PORT_READ                "I2CPortRead"\r
215 static const char* ALL_SCRIPTS[] = { SCRIPT_MSG_SEND, SCRIPT_PAUSE,\r
216     SCRIPT_GPIO_PORT_CREATE, SCRIPT_GPIO_PORT_PIN_MODE, SCRIPT_GPIO_PIN_STATE,\r
217     SCRIPT_I2C_PORT_CREATE, SCRIPT_I2C_PORT_WRITE, SCRIPT_I2C_PORT_READ, NULL };\r
218 \r
219 static const char* VALUE_TRUE =             "true";\r
220 static const char* VALUE_FALSE =            "false";\r
221 static const char* VALUE_1 =                "1";\r
222 static const char* VALUE_0 =                "0";\r
223 \r
224 /************************************************************************/\r
225 /* Private Function Prototypes                                          */\r
226 /************************************************************************/\r
227 \r
228 static void FreeVal(UcsXmlVal_t *ucs);\r
229 static bool GetElement(mxml_node_t *element, const char *name, bool goDeep, mxml_node_t **out, bool mandatory);\r
230 static bool GetElementArray(mxml_node_t *element, const char *array[], const char **foundName, mxml_node_t **out);\r
231 static bool GetCount(mxml_node_t *element, const char *name, uint32_t *out, bool mandatory);\r
232 static bool GetCountArray(mxml_node_t *element, const char *array[], uint32_t *out, bool mandatory);\r
233 static bool GetString(mxml_node_t *element, const char *key, const char **out, bool mandatory);\r
234 static bool GetUInt16(mxml_node_t *element, const char *key, uint16_t *out, bool mandatory);\r
235 static bool GetUInt8(mxml_node_t *element, const char *key, uint8_t *out, bool mandatory);\r
236 static bool GetSocketType(const char *txt, MSocketType_t *out);\r
237 static bool GetPayload(mxml_node_t *element, const char *name, uint8_t **pPayload, uint8_t *len, uint8_t offset,\r
238             struct UcsXmlObjectList *obj, bool mandatory);\r
239 static bool AddJob(struct UcsXmlJobList **joblist, Ucs_Xrm_ResObject_t *job, struct UcsXmlObjectList *objList);\r
240 static Ucs_Xrm_ResObject_t **GetJobList(struct UcsXmlJobList *joblist, struct UcsXmlObjectList *objList);\r
241 static struct UcsXmlJobList *DeepCopyJobList(struct UcsXmlJobList *jobsIn, struct UcsXmlObjectList *objList);\r
242 static void AddRoute(struct UcsXmlRoute **pRtLst, struct UcsXmlRoute *route);\r
243 static void AddScript(struct UcsXmlScript **pScrLst, struct UcsXmlScript *script);\r
244 static ParseResult_t ParseAll(mxml_node_t *tree, UcsXmlVal_t *ucs, PrivateData_t *priv);\r
245 static ParseResult_t ParseNode(mxml_node_t * node, PrivateData_t *priv);\r
246 static ParseResult_t ParseConnection(mxml_node_t * node, const char *conType, PrivateData_t *priv);\r
247 static ParseResult_t ParseSocket(mxml_node_t *soc, bool isSource, MSocketType_t socketType, struct UcsXmlJobList **jobList, PrivateData_t *priv);\r
248 static ParseResult_t ParseScript(mxml_node_t *scr, PrivateData_t *priv);\r
249 static bool FillScriptInitialValues(Ucs_Ns_Script_t *scr, PrivateData_t *priv);\r
250 static ParseResult_t ParseScriptMsgSend(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);\r
251 static ParseResult_t ParseScriptGpioPortCreate(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);\r
252 static ParseResult_t ParseScriptGpioPinMode(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);\r
253 static ParseResult_t ParseScriptGpioPinState(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);\r
254 static ParseResult_t ParseScriptPortCreate(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);\r
255 static ParseResult_t ParseScriptPortWrite(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);\r
256 static ParseResult_t ParseScriptPortRead(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);\r
257 static ParseResult_t ParseScriptPause(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);\r
258 static ParseResult_t ParseRoutes(UcsXmlVal_t *ucs, PrivateData_t *priv);\r
259 \r
260 /************************************************************************/\r
261 /* Public Functions                                                     */\r
262 /************************************************************************/\r
263 \r
264 UcsXmlVal_t *UcsXml_Parse(const char *xmlString)\r
265 {\r
266     UcsXmlVal_t *val = NULL;\r
267     ParseResult_t result = Parse_MemoryError;\r
268     mxml_node_t *tree;\r
269     if (!(tree = mxmlLoadString(NULL, xmlString, MXML_NO_CALLBACK))) goto ERROR;\r
270     if (!GetElement(tree, UNICENS, true, &tree, true)) goto ERROR;\r
271     /*Do not use MCalloc for the root element*/\r
272     val = calloc(1, sizeof(UcsXmlVal_t));\r
273     if (!val) goto ERROR;\r
274     val->pInternal = calloc(1, sizeof(PrivateData_t));\r
275     if (!val->pInternal) goto ERROR;\r
276     result = ParseAll(tree, val, val->pInternal);\r
277     if (Parse_Success == result)\r
278         return val;\r
279 ERROR:\r
280     if (Parse_MemoryError == result)\r
281         UcsXml_CB_OnError("XML error, aborting..", 0);\r
282     else\r
283         UcsXml_CB_OnError("Allocation error, aborting..", 0);\r
284     assert(false);\r
285     if (!tree)\r
286         mxmlDelete(tree);\r
287     if (val)\r
288         FreeVal(val);\r
289     return NULL;\r
290 }\r
291 \r
292 void UcsXml_FreeVal(UcsXmlVal_t *val)\r
293 {\r
294     FreeVal(val);\r
295 }\r
296 \r
297 /************************************************************************/\r
298 /* Private Function Implementations                                     */\r
299 /************************************************************************/\r
300 \r
301 void FreeVal(UcsXmlVal_t *ucs)\r
302 {\r
303     PrivateData_t *priv;\r
304     if (NULL == ucs || NULL == ucs->pInternal)\r
305         return;\r
306     priv = ucs->pInternal;\r
307     FreeObjList(&priv->objList);\r
308     free(ucs->pInternal);\r
309     free(ucs);\r
310 }\r
311 \r
312 static bool GetElement(mxml_node_t *element, const char *name, bool goDeep, mxml_node_t **out, bool mandatory)\r
313 {\r
314     mxml_node_t *n = element;\r
315     if (NULL == n || NULL == name || NULL == out) return false;\r
316     if (goDeep)\r
317     {\r
318         *out = mxmlFindElement(n, n, name, NULL, NULL, MXML_DESCEND);\r
319         return (NULL != *out);\r
320     }\r
321     while ((n = n->next))\r
322     {\r
323         if (MXML_ELEMENT != n->type)\r
324             continue;\r
325         if (0 == strcmp(name, n->value.opaque))\r
326         {\r
327             *out = n;\r
328             return true;\r
329         }\r
330     }\r
331     if (mandatory)\r
332         UcsXml_CB_OnError("Can not find tag <%s>", 1, name);\r
333     return false;\r
334 }\r
335 \r
336 static bool GetElementArray(mxml_node_t *element, const char *array[], const char **foundName, mxml_node_t **out)\r
337 {\r
338     mxml_node_t *n = element;\r
339     if (NULL == n || NULL == array || NULL == foundName || NULL == out) return false;\r
340     while ((n = n->next))\r
341     {\r
342         uint32_t i;\r
343         if (MXML_ELEMENT != n->type)\r
344             continue;\r
345         for (i = 0; NULL != array[i]; i++)\r
346         {\r
347             if (0 == strcmp(array[i], n->value.opaque))\r
348             {\r
349                 *foundName = array[i];\r
350                 *out = n;\r
351                 return true;\r
352             }\r
353         }\r
354     }\r
355     return false;\r
356 }\r
357 \r
358 static bool GetCount(mxml_node_t *element, const char *name, uint32_t *out, bool mandatory)\r
359 {\r
360     uint32_t cnt = 0;\r
361     mxml_node_t *n;\r
362     if (NULL == element || NULL == name) return false;\r
363     if(!GetElement(element, name, true, &n, false))\r
364         return false;\r
365     while(NULL != n)\r
366     {\r
367         ++cnt;\r
368         if(!GetElement(n, name, false, &n, false))\r
369             break;\r
370     }\r
371     if (mandatory && 0 == cnt)\r
372     {\r
373         UcsXml_CB_OnError("element count of <%s> is zero", 1, name);\r
374         return false;\r
375     }\r
376     *out = cnt;\r
377     return true;\r
378 }\r
379 \r
380 static bool GetCountArray(mxml_node_t *element, const char *array[], uint32_t *out, bool mandatory)\r
381 {\r
382     const char *tmp;\r
383     uint32_t cnt = 0;\r
384     mxml_node_t *n;\r
385     if (NULL == element || NULL == array) return false;\r
386     n = element;\r
387     while(NULL != n)\r
388     {\r
389         if(!GetElementArray(n, array, &tmp, &n))\r
390             break;\r
391         ++cnt;\r
392     }\r
393     if (mandatory && 0 == cnt)\r
394     {\r
395         UcsXml_CB_OnError("element count is zero, searched with string array", 0);\r
396         return false;\r
397     }\r
398     *out = cnt;\r
399     return true;\r
400 }\r
401 \r
402 static bool GetString(mxml_node_t *element, const char *key, const char **out, bool mandatory)\r
403 {\r
404     int32_t i;\r
405     if (NULL == element || NULL == key) return false;\r
406     for (i = 0; i < element->value.element.num_attrs; i++)\r
407     {\r
408         mxml_attr_t *attr = &element->value.element.attrs[i];\r
409         if (0 == strcmp(key, attr->name))\r
410         {\r
411             *out = attr->value;\r
412             return true;\r
413         }\r
414     }\r
415     if (mandatory)\r
416         UcsXml_CB_OnError("Can not find attribute='%s' from element <%s>",\r
417             2, key, element->value.element.name);\r
418     return false;\r
419 }\r
420 \r
421 static bool GetUInt16(mxml_node_t *element, const char *key, uint16_t *out, bool mandatory)\r
422 {\r
423     const char* txt;\r
424     if (!GetString(element, key, &txt, mandatory)) return false;\r
425     *out = strtol( txt, NULL, 0 );\r
426     return true;\r
427 }\r
428 \r
429 static bool GetUInt8(mxml_node_t *element, const char *key, uint8_t *out, bool mandatory)\r
430 {\r
431     const char* txt;\r
432     if (!GetString(element, key, &txt, mandatory)) return false;\r
433     *out = strtol( txt, NULL, 0 );\r
434     return true;\r
435 }\r
436 \r
437 static bool GetDataType(const char *txt, MDataType_t *out)\r
438 {\r
439     if (NULL == txt || NULL == out) return false;\r
440     if (0 == strcmp(SYNC_CONNECTION, txt)) {\r
441         *out = SYNC_DATA;\r
442     } else if (0 == strcmp(AVP_CONNECTION, txt)) {\r
443         *out = AV_PACKETIZED;\r
444     } else if (0 == strcmp(QOS_CONNECTION, txt)) {\r
445         *out = QOS_IP;\r
446     } else if (0 == strcmp(DFP_CONNECTION, txt)) {\r
447         *out = DISC_FRAME_PHASE;\r
448     } else if (0 == strcmp(IPC_CONNECTION, txt)) {\r
449         *out = IPC_PACKET;\r
450     } else {\r
451         UcsXml_CB_OnError("Unknown data type : '%s'", 1, txt);\r
452         return false;\r
453     }\r
454     return true;\r
455 }\r
456 \r
457 static bool GetSocketType(const char *txt, MSocketType_t *out)\r
458 {\r
459     if (0 == strcmp(txt, MOST_SOCKET)) {\r
460             *out = MSocket_MOST;\r
461     } else if (0 == strcmp(txt, USB_SOCKET)) {\r
462         *out = MSocket_USB;\r
463     } else if (0 == strcmp(txt, MLB_SOCKET)) {\r
464         *out = MSocket_MLB;\r
465     } else if (0 == strcmp(txt, STREAM_SOCKET)) {\r
466         *out = MSocket_STRM;\r
467     } else if (0 == strcmp(txt, SPLITTER)) {\r
468         *out = MSocket_SPLITTER;\r
469     } else if (0 == strcmp(txt, COMBINER)) {\r
470         *out = MSocket_COMBINER;\r
471     } else {\r
472         UcsXml_CB_OnError("Unknown port : '%s'", 1, txt);\r
473         return false;\r
474     }\r
475     return true;\r
476 }\r
477 \r
478 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
479 {\r
480     uint32_t tempLen, len = 0;\r
481     uint8_t *p;\r
482     const char *txt;\r
483     char *txtCopy;\r
484     char *tkPtr;\r
485     char *token;\r
486     if (!GetString(element, name, &txt, mandatory))\r
487         return false;\r
488     tempLen = strlen(txt) + 1;\r
489     txtCopy = malloc(tempLen);\r
490     if (NULL == txtCopy)\r
491         return false;\r
492     strncpy(txtCopy, txt, tempLen);\r
493     tempLen = tempLen / 3; /* 2 chars hex value plus space (AA )  */\r
494     p = MCalloc(obj, offset + tempLen, 1);\r
495     if (NULL == p)\r
496     {\r
497         free(txtCopy);\r
498         return false;\r
499     }\r
500     *pPayload = p;\r
501     token = strtok_r( txtCopy, " ,.-", &tkPtr );\r
502     while( NULL != token )\r
503     {\r
504         if( len >= tempLen )\r
505         {\r
506             UcsXml_CB_OnError("Script payload values must be stuffed to two characters", 0);\r
507             free(txtCopy);\r
508             assert(false);\r
509             return 0;\r
510         }\r
511         p[offset + len++] = strtol( token, NULL, 16 );\r
512         token = strtok_r( NULL, " ,.-", &tkPtr );\r
513     }\r
514     *outLen = len;\r
515     return true;\r
516 }\r
517 \r
518 static bool AddJob(struct UcsXmlJobList **joblist, Ucs_Xrm_ResObject_t *job, struct UcsXmlObjectList *objList)\r
519 {\r
520     struct UcsXmlJobList *tail;\r
521     if (NULL == joblist || NULL == job)\r
522         return false;\r
523     assert(UCS_XRM_RC_TYPE_QOS_CON >= *((Ucs_Xrm_ResourceType_t *)job));\r
524     if (NULL == joblist[0])\r
525     {\r
526         joblist[0] = MCalloc(objList, 1, sizeof(struct UcsXmlJobList));\r
527         if (NULL == joblist[0]) return false;;\r
528         joblist[0]->job = job;\r
529         return true;\r
530     }\r
531     tail = joblist[0];\r
532     while(tail->next) tail = tail->next;\r
533     tail->next = MCalloc(objList, 1, sizeof(struct UcsXmlJobList));\r
534     if (NULL == tail->next) return false;\r
535     tail->next->job = job;\r
536     return true;\r
537 }\r
538 \r
539 static Ucs_Xrm_ResObject_t **GetJobList(struct UcsXmlJobList *joblist, struct UcsXmlObjectList *objList)\r
540 {\r
541     Ucs_Xrm_ResObject_t **outJob;\r
542     uint32_t count = 0;\r
543     struct UcsXmlJobList *tail;\r
544     if (NULL == joblist)\r
545         return false;\r
546     /*First: Get amount of stored jobs by enumerate all*/\r
547     tail = joblist;\r
548     while(tail)\r
549     {\r
550         ++count;\r
551         tail = tail->next;\r
552     }\r
553     if (0 == count)\r
554         return false;\r
555     /*Second: Allocate count+1 elements (NULL terminated) and copy pointers*/\r
556     outJob = MCalloc(objList, (count + 1), sizeof(Ucs_Xrm_ResObject_t *));\r
557     if (NULL == outJob)\r
558         return false;\r
559     tail = joblist;\r
560     count = 0;\r
561     while(tail)\r
562     {\r
563         outJob[count++] = tail->job;\r
564         tail = tail->next;\r
565     }\r
566     return outJob;\r
567 }\r
568 \r
569 static struct UcsXmlJobList *DeepCopyJobList(struct UcsXmlJobList *jobsIn, struct UcsXmlObjectList *objList)\r
570 {\r
571     struct UcsXmlJobList *jobsOut, *tail;\r
572     if (NULL == jobsIn || NULL == objList)\r
573         return NULL;\r
574     jobsOut = tail = MCalloc(objList, 1, sizeof(struct UcsXmlJobList));\r
575     if (NULL == jobsOut) { assert(false); return NULL; }\r
576     while(jobsIn)\r
577     {\r
578         tail->job = jobsIn->job;\r
579         if (jobsIn->next)\r
580         {\r
581             tail->next = MCalloc(objList, 1, sizeof(struct UcsXmlJobList));\r
582             if (NULL == tail->next) { assert(false); return NULL; }\r
583             tail = tail->next;\r
584         }\r
585         jobsIn = jobsIn->next;\r
586     }\r
587     return jobsOut;\r
588 }\r
589 \r
590 static void AddRoute(struct UcsXmlRoute **pRtLst, struct UcsXmlRoute *route)\r
591 {\r
592     struct UcsXmlRoute *tail;\r
593     if (NULL == pRtLst || NULL == route)\r
594     {\r
595         assert(false);\r
596         return;\r
597     }\r
598     if (NULL == pRtLst[0])\r
599     {\r
600         pRtLst[0] = route;\r
601         return;\r
602     }\r
603     tail = pRtLst[0];\r
604     while(tail->next) tail = tail->next;\r
605     tail->next = route;\r
606 }\r
607 \r
608 static void AddScript(struct UcsXmlScript **pScrLst, struct UcsXmlScript *script)\r
609 {\r
610     struct UcsXmlScript *tail;\r
611     if (NULL == pScrLst || NULL == script)\r
612     {\r
613         assert(false);\r
614         return;\r
615     }\r
616     if (NULL == pScrLst[0])\r
617     {\r
618         pScrLst[0] = script;\r
619         return;\r
620     }\r
621     tail = pScrLst[0];\r
622     while(tail->next) tail = tail->next;\r
623     tail->next = script;\r
624 }\r
625 \r
626 static ParseResult_t ParseAll(mxml_node_t *tree, UcsXmlVal_t *ucs, PrivateData_t *priv)\r
627 {\r
628     uint32_t nodeCount;\r
629     mxml_node_t *sub;\r
630     ParseResult_t result;\r
631     priv->autoRouteId = 0x8000;\r
632     if (!GetCount(tree, NODE, &nodeCount, true))\r
633         RETURN_ASSERT(Parse_XmlError);\r
634 \r
635     ucs->pNod = MCalloc(&priv->objList, nodeCount, sizeof(Ucs_Rm_Node_t));\r
636     if (NULL == ucs->pNod) RETURN_ASSERT(Parse_MemoryError);\r
637 \r
638     if (!GetUInt16(tree, PACKET_BW, &ucs->packetBw, true))\r
639         RETURN_ASSERT(Parse_XmlError);\r
640 \r
641     /*Iterate all nodes*/\r
642     if (!GetElement(tree, NODE, true, &sub, true))\r
643         RETURN_ASSERT(Parse_XmlError);\r
644     while(sub)\r
645     {\r
646         const char *conType;\r
647         mxml_node_t *con;\r
648         memset(&priv->nodeData, 0, sizeof(NodeData_t));\r
649         priv->nodeData.nod = &ucs->pNod[ucs->nodSize];\r
650         if (Parse_Success != (result = ParseNode(sub, priv)))\r
651             return result;\r
652         /*/Iterate all connections. Node without any connection is also valid.*/\r
653         if (!GetElementArray(sub->child, ALL_CONNECTIONS, &conType, &con))\r
654             continue;\r
655         while(con)\r
656         {\r
657             const char *socTypeStr;\r
658             MSocketType_t socType;\r
659             mxml_node_t *soc;\r
660             memset(&priv->conData, 0, sizeof(ConnectionData_t));\r
661             if (Parse_Success != (result = ParseConnection(con, conType, priv)))\r
662                 return result;\r
663             /*Iterate all sockets*/\r
664             if(!GetElementArray(con->child, ALL_SOCKETS, &socTypeStr, &soc)) RETURN_ASSERT(Parse_XmlError);\r
665             while(soc)\r
666             {\r
667                 if (!GetSocketType(socTypeStr, &socType)) RETURN_ASSERT(Parse_XmlError);\r
668                 if (Parse_Success != (result = ParseSocket(soc, (0 == priv->conData.sockCnt), socType, &priv->conData.jobList, priv)))\r
669                     return result;\r
670                 ++priv->conData.sockCnt;\r
671                 if(!GetElementArray(soc, ALL_SOCKETS, &socTypeStr, &soc))\r
672                     break;\r
673             }\r
674             if(!GetElementArray(con, ALL_CONNECTIONS, &conType, &con))\r
675                 break;\r
676         }\r
677         ++ucs->nodSize;\r
678         if (!GetElement(sub, NODE, false, &sub, false))\r
679             break;\r
680     }\r
681 \r
682     /*Fill route structures*/\r
683     result = ParseRoutes(ucs, priv);\r
684     if (Parse_MemoryError == result) RETURN_ASSERT(Parse_MemoryError)\r
685     else if (Parse_XmlError == result) RETURN_ASSERT(Parse_XmlError);\r
686 \r
687     /*Iterate all scripts. No scripts at all is allowed*/\r
688     if(GetElement(tree, SCRIPT, true, &sub, false))\r
689     {\r
690         while(sub)\r
691         {\r
692             result = ParseScript(sub, priv);\r
693             if (Parse_MemoryError == result) RETURN_ASSERT(Parse_MemoryError)\r
694             else if (Parse_XmlError == result) RETURN_ASSERT(Parse_XmlError);\r
695             if(!GetElement(sub, SCRIPT, false, &sub, false))\r
696                 break;\r
697         }\r
698     }\r
699     return result;\r
700 }\r
701 \r
702 static ParseResult_t ParseNode(mxml_node_t *node, PrivateData_t *priv)\r
703 {\r
704     const char *txt;\r
705     mxml_node_t *port;\r
706     Ucs_Signature_t *signature;\r
707     assert(NULL != node && NULL != priv);\r
708     priv->nodeData.nod->signature_ptr = MCalloc(&priv->objList, 1, sizeof(Ucs_Signature_t));\r
709     signature = priv->nodeData.nod->signature_ptr;\r
710     if(NULL == signature) RETURN_ASSERT(Parse_MemoryError);\r
711     if (!GetUInt16(node, ADDRESS, &signature->node_address, true))\r
712         RETURN_ASSERT(Parse_XmlError);\r
713     if (GetString(node, SCRIPT, &txt, false))\r
714     {\r
715         struct UcsXmlScript *scr = MCalloc(&priv->objList, 1, sizeof(struct UcsXmlScript));\r
716         if (NULL == scr) RETURN_ASSERT(Parse_MemoryError);\r
717         scr->node = priv->nodeData.nod;\r
718         strncpy(scr->scriptName, txt, sizeof(scr->scriptName));\r
719         AddScript(&priv->pScrLst, scr);\r
720     }\r
721     /*Iterate all ports*/\r
722     if(GetElementArray(node->child, ALL_PORTS, &txt, &port))\r
723     {\r
724         while(port)\r
725         {\r
726             if (0 == (strcmp(txt, MLB_PORT)))\r
727             {\r
728                 struct MlbPortParameters p;\r
729                 p.list = &priv->objList;\r
730                 if (!GetString(port, CLOCK_CONFIG, &p.clockConfig, true)) RETURN_ASSERT(Parse_XmlError);\r
731                 if (!GetMlbPort(&priv->nodeData.mlbPort, &p)) RETURN_ASSERT(Parse_XmlError);\r
732             }\r
733             else if (0 == (strcmp(txt, USB_PORT)))\r
734             {\r
735                 struct UsbPortParameters p;\r
736                 p.list = &priv->objList;\r
737                 if (!GetString(port, PHYSICAL_LAYER, &p.physicalLayer, true)) RETURN_ASSERT(Parse_XmlError);\r
738                 if (!GetString(port, DEVICE_INTERFACES, &p.deviceInterfaces, true)) RETURN_ASSERT(Parse_XmlError);\r
739                 if (!GetString(port, STRM_IN_COUNT, &p.streamInCount, true)) RETURN_ASSERT(Parse_XmlError);\r
740                 if (!GetString(port, STRM_OUT_COUNT, &p.streamOutCount, true)) RETURN_ASSERT(Parse_XmlError);\r
741                 if (!GetUsbPort(&priv->nodeData.usbPort, &p)) RETURN_ASSERT(Parse_XmlError);\r
742             }\r
743             else if (0 == (strcmp(txt, STRM_PORT)))\r
744             {\r
745                 struct StrmPortParameters p;\r
746                 p.list = &priv->objList;\r
747                 p.index = 0;\r
748                 if (!GetString(port, CLOCK_CONFIG, &p.clockConfig, true)) RETURN_ASSERT(Parse_XmlError);\r
749                 if (!GetString(port, STRM_ALIGN, &p.dataAlignment, true)) RETURN_ASSERT(Parse_XmlError);\r
750                 if (!GetStrmPort(&priv->nodeData.strmPortA, &p)) RETURN_ASSERT(Parse_XmlError);\r
751                 p.index = 1;\r
752                 if (!GetStrmPort(&priv->nodeData.strmPortB, &p)) RETURN_ASSERT(Parse_XmlError);\r
753             }\r
754             else\r
755             {\r
756                 UcsXml_CB_OnError("Unknown Port:'%s'", 1, txt);\r
757                 RETURN_ASSERT(Parse_XmlError);\r
758             }\r
759             if(!GetElementArray(port, ALL_PORTS, &txt, &port))\r
760                 break;\r
761         }\r
762     }\r
763     return Parse_Success;;\r
764 }\r
765 \r
766 static ParseResult_t ParseConnection(mxml_node_t * node, const char *conType, PrivateData_t *priv)\r
767 {\r
768     assert(NULL != node && NULL != priv);\r
769     if (NULL == conType) RETURN_ASSERT(Parse_XmlError);\r
770     if (!GetDataType(conType, &priv->conData.dataType)) RETURN_ASSERT(Parse_XmlError);\r
771     switch (priv->conData.dataType)\r
772     {\r
773     case SYNC_DATA:\r
774     {\r
775         const char *txt;\r
776         if (GetString(node, MUTE_MODE, &txt, false))\r
777         {\r
778             if (0 == strcmp(txt, MUTE_MODE_NO_MUTING))\r
779                 priv->conData.muteMode = UCS_SYNC_MUTE_MODE_NO_MUTING;\r
780             else if (0 == strcmp(txt, MUTE_MODE_MUTE_SIGNAL))\r
781                 priv->conData.muteMode = UCS_SYNC_MUTE_MODE_MUTE_SIGNAL;\r
782             else\r
783             {\r
784                 UcsXml_CB_OnError("ParseConnection: MuteMode='%s' not implemented", 1, txt);\r
785                 RETURN_ASSERT(Parse_XmlError);\r
786             }\r
787         }\r
788         else\r
789         {\r
790             /*Be tolerant, this is an optional feature*/\r
791             priv->conData.muteMode = UCS_SYNC_MUTE_MODE_NO_MUTING;\r
792         }\r
793         break;\r
794     }\r
795     case AV_PACKETIZED:\r
796     {\r
797         uint16_t size;\r
798         if (GetUInt16(node, AVP_PACKET_SIZE, &size, false))\r
799         {\r
800             switch(size)\r
801             {\r
802             case 188:\r
803                 priv->conData.isocPacketSize = UCS_ISOC_PCKT_SIZE_188;\r
804                 break;\r
805             case 196:\r
806                 priv->conData.isocPacketSize = UCS_ISOC_PCKT_SIZE_196;\r
807                 break;\r
808             case 206:\r
809                 priv->conData.isocPacketSize = UCS_ISOC_PCKT_SIZE_206;\r
810                 break;\r
811             default:\r
812                 UcsXml_CB_OnError("ParseConnection: %s='%d' not implemented", 2, AVP_PACKET_SIZE, size);\r
813                 RETURN_ASSERT(Parse_XmlError);\r
814             }\r
815         }\r
816         else\r
817         {\r
818             /*Be tolerant, this is an optional feature*/\r
819             priv->conData.isocPacketSize = UCS_ISOC_PCKT_SIZE_188;\r
820         }\r
821         break;\r
822     }\r
823     default:\r
824         UcsXml_CB_OnError("ParseConnection: Datatype='%s' not implemented", 1, conType);\r
825         RETURN_ASSERT(Parse_XmlError);\r
826         break;\r
827     }\r
828     return Parse_Success;\r
829 }\r
830 \r
831 static ParseResult_t ParseSocket(mxml_node_t *soc, bool isSource, MSocketType_t socketType, struct UcsXmlJobList **jobList, PrivateData_t *priv)\r
832 {\r
833     Ucs_Xrm_ResObject_t **targetSock;\r
834     assert(NULL != soc && NULL != priv);\r
835     targetSock = isSource ? &priv->conData.inSocket : &priv->conData.outSocket;\r
836     switch(socketType)\r
837     {\r
838     case MSocket_MOST:\r
839     {\r
840         const char* txt;\r
841         struct MostSocketParameters p;\r
842         /* If there is an combiner stored, add it now into job list (right before MOST socket) */\r
843         if (priv->conData.combiner)\r
844             if (!AddJob(jobList, priv->conData.combiner, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
845 \r
846         p.list = &priv->objList;\r
847         p.isSource = isSource;\r
848         p.dataType = priv->conData.dataType;\r
849         if (!GetUInt16(soc, BANDWIDTH, &p.bandwidth, true)) RETURN_ASSERT(Parse_XmlError);\r
850         if (!GetString(soc, ROUTE, &priv->conData.routeName, true)) RETURN_ASSERT(Parse_XmlError);\r
851         if (GetString(soc, ROUTE_IS_ACTIVE, &txt, false))\r
852         {\r
853             if (0 == strcmp(txt, VALUE_TRUE) || 0 == strcmp(txt, VALUE_1))\r
854                 priv->conData.isDeactivated = false;\r
855             else if (0 == strcmp(txt, VALUE_FALSE) || 0 == strcmp(txt, VALUE_0))\r
856                 priv->conData.isDeactivated = true;\r
857             else RETURN_ASSERT(Parse_XmlError);\r
858         } else {\r
859             priv->conData.isDeactivated = false;\r
860         }\r
861         if (!GetUInt16(soc, ROUTE_ID, &priv->conData.routeId, false))\r
862             priv->conData.routeId = ++priv->autoRouteId;\r
863         if (priv->conData.syncOffsetNeeded)\r
864         {\r
865             if (!GetUInt16(soc, OFFSET, &priv->conData.syncOffset, true)) RETURN_ASSERT(Parse_XmlError);\r
866         }\r
867         if (!GetMostSocket((Ucs_Xrm_MostSocket_t **)targetSock, &p)) RETURN_ASSERT(Parse_XmlError);\r
868         if (!AddJob(jobList, *targetSock, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
869         break;\r
870     }\r
871     case MSocket_USB:\r
872     {\r
873         struct UsbSocketParameters p;\r
874         p.list = &priv->objList;\r
875         p.isSource = isSource;\r
876         p.dataType = priv->conData.dataType;\r
877         if (priv->nodeData.usbPort)\r
878         {\r
879             p.usbPort = priv->nodeData.usbPort;\r
880         } else {\r
881             if (!GetUsbPortDefaultCreated(&p.usbPort, &priv->objList))\r
882                 RETURN_ASSERT(Parse_XmlError);\r
883             priv->nodeData.usbPort = (Ucs_Xrm_UsbPort_t *)p.usbPort;\r
884         }\r
885         if(!AddJob(jobList, p.usbPort, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
886         if (!GetString(soc, ENDPOINT_ADDRESS, &p.endpointAddress, true)) RETURN_ASSERT(Parse_XmlError);\r
887         if (!GetString(soc, FRAMES_PER_TRANSACTION, &p.framesPerTrans, true)) RETURN_ASSERT(Parse_XmlError);\r
888         if (!GetUsbSocket((Ucs_Xrm_UsbSocket_t **)targetSock, &p)) RETURN_ASSERT(Parse_XmlError);\r
889         if (!AddJob(jobList, *targetSock, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
890         break;\r
891     }\r
892     case MSocket_MLB:\r
893     {\r
894         struct MlbSocketParameters p;\r
895         p.list = &priv->objList;\r
896         p.isSource = isSource;\r
897         p.dataType = priv->conData.dataType;\r
898         if (priv->nodeData.mlbPort)\r
899         {\r
900             p.mlbPort = priv->nodeData.mlbPort;\r
901         } else {\r
902             if (!GetMlbPortDefaultCreated(&p.mlbPort, &priv->objList))\r
903                 RETURN_ASSERT(Parse_XmlError);\r
904             priv->nodeData.mlbPort = (Ucs_Xrm_MlbPort_t *)p.mlbPort;\r
905         }\r
906         if (!AddJob(jobList, p.mlbPort, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
907         if (!GetUInt16(soc, BANDWIDTH, &p.bandwidth, true)) RETURN_ASSERT(Parse_XmlError);\r
908         if (!GetString(soc, CHANNEL_ADDRESS, &p.channelAddress, true)) RETURN_ASSERT(Parse_XmlError);\r
909         if (!GetMlbSocket((Ucs_Xrm_MlbSocket_t **)targetSock, &p)) RETURN_ASSERT(Parse_XmlError);\r
910         if (!AddJob(jobList, *targetSock, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
911         break;\r
912     }\r
913     case MSocket_STRM:\r
914     {\r
915         struct StrmSocketParameters p;\r
916         p.list = &priv->objList;\r
917         p.isSource = isSource;\r
918         p.dataType = priv->conData.dataType;\r
919         p.streamPortA = priv->nodeData.strmPortA;\r
920         p.streamPortB = priv->nodeData.strmPortB;\r
921         if (!AddJob(jobList, p.streamPortA, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
922         if (!AddJob(jobList, p.streamPortB, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
923         if (!GetUInt16(soc, BANDWIDTH, &p.bandwidth, true)) RETURN_ASSERT(Parse_XmlError);\r
924         if (!GetString(soc, STRM_PIN, &p.streamPin, true)) RETURN_ASSERT(Parse_XmlError);\r
925         if (!GetStrmSocket((Ucs_Xrm_StrmSocket_t **)targetSock, &p)) RETURN_ASSERT(Parse_XmlError);\r
926         if (!AddJob(jobList, *targetSock, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
927         break;\r
928     }\r
929     case MSocket_SPLITTER:\r
930     {\r
931         mxml_node_t *mostSoc;\r
932         struct SplitterParameters p;\r
933         if (isSource)\r
934         {\r
935             UcsXml_CB_OnError("Splitter can not be used as input socket", 0);\r
936             RETURN_ASSERT(Parse_XmlError);\r
937         }\r
938         p.list = &priv->objList;\r
939         if (!GetUInt16(soc, BYTES_PER_FRAME, &p.bytesPerFrame, true)) RETURN_ASSERT(Parse_XmlError);\r
940         /* Current input socket will be stored inside splitter\r
941          * and splitter will become the new input socket */\r
942         if (!(p.inSoc = priv->conData.inSocket)) RETURN_ASSERT(Parse_XmlError);\r
943         if (!GetSplitter((Ucs_Xrm_Splitter_t **)&priv->conData.inSocket, &p)) RETURN_ASSERT(Parse_XmlError);\r
944         if (!AddJob(jobList, priv->conData.inSocket, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
945         if (!GetElement(soc->child, MOST_SOCKET, false, &mostSoc, true))\r
946             RETURN_ASSERT(Parse_XmlError);\r
947         priv->conData.syncOffsetNeeded = true;\r
948 \r
949         while(mostSoc)\r
950         {\r
951             struct UcsXmlJobList *jobListCopy = DeepCopyJobList(*jobList, &priv->objList);\r
952             if (!ParseSocket(mostSoc, false, MSocket_MOST, &jobListCopy, priv)) RETURN_ASSERT(Parse_XmlError);\r
953             if (!GetElement(mostSoc, MOST_SOCKET, false, &mostSoc, false))\r
954                 return Parse_Success; /* Do not break here, otherwise an additional invalid route will be created */\r
955         }\r
956         break;\r
957     }\r
958     case MSocket_COMBINER:\r
959     {\r
960         struct CombinerParameters p;\r
961         if (!isSource)\r
962         {\r
963             UcsXml_CB_OnError("Combiner can not be used as output socket", 0);\r
964             RETURN_ASSERT(Parse_XmlError);\r
965         }\r
966         p.list = &priv->objList;\r
967         if (!GetUInt16(soc, BYTES_PER_FRAME, &p.bytesPerFrame, true)) RETURN_ASSERT(Parse_XmlError);\r
968         if (!GetCombiner(&priv->conData.combiner, &p)) RETURN_ASSERT(Parse_XmlError);\r
969         priv->conData.syncOffsetNeeded = true;\r
970         if (!GetElement(soc->child, MOST_SOCKET, false, &priv->conData.pendingCombinerMostSockets, true))\r
971             RETURN_ASSERT(Parse_XmlError);\r
972         break;\r
973     }\r
974     default:\r
975         RETURN_ASSERT(Parse_XmlError);\r
976     }\r
977     /*Handle Pending Combiner Tasks*/\r
978     if (NULL != priv->conData.outSocket && NULL != priv->conData.combiner &&\r
979         NULL != priv->conData.pendingCombinerMostSockets)\r
980     {\r
981         mxml_node_t *tmp = priv->conData.pendingCombinerMostSockets;\r
982         priv->conData.pendingCombinerMostSockets = NULL;\r
983         /* Current output socket will be stored inside combiner\r
984          * and combiner will become the new output socket */\r
985         priv->conData.combiner->port_socket_obj_ptr = priv->conData.outSocket;\r
986         priv->conData.outSocket = priv->conData.combiner;\r
987         while(tmp)\r
988         {\r
989             struct UcsXmlJobList *jobListCopy = DeepCopyJobList(*jobList, &priv->objList);\r
990             if (!ParseSocket(tmp, true, MSocket_MOST, &jobListCopy, priv)) RETURN_ASSERT(Parse_XmlError);\r
991             if (!GetElement(tmp, MOST_SOCKET, false, &tmp, false))\r
992                 return Parse_Success; /* Do not break here, otherwise an additional invalid route will be created */\r
993         }\r
994     }\r
995     /*Connect in and out socket once they are created*/\r
996     if (priv->conData.inSocket && priv->conData.outSocket)\r
997     {\r
998         bool mostIsOutput;\r
999         Ucs_Rm_EndPoint_t *ep;\r
1000         struct UcsXmlRoute *route;\r
1001         switch(priv->conData.dataType)\r
1002         {\r
1003         case SYNC_DATA:\r
1004         {\r
1005             Ucs_Xrm_SyncCon_t *con = MCalloc(&priv->objList, 1, sizeof(Ucs_Xrm_SyncCon_t));\r
1006             if (NULL == con) RETURN_ASSERT(Parse_MemoryError);\r
1007             if (!AddJob(jobList, con, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
1008             con->resource_type = UCS_XRM_RC_TYPE_SYNC_CON;\r
1009             con->socket_in_obj_ptr = priv->conData.inSocket;\r
1010             con->socket_out_obj_ptr = priv->conData.outSocket;\r
1011             con->mute_mode = priv->conData.muteMode;\r
1012             con->offset = priv->conData.syncOffset;\r
1013             break;\r
1014         }\r
1015         case AV_PACKETIZED:\r
1016         {\r
1017             Ucs_Xrm_AvpCon_t *con = MCalloc(&priv->objList, 1, sizeof(Ucs_Xrm_AvpCon_t));\r
1018             if (NULL == con) RETURN_ASSERT(Parse_MemoryError);\r
1019             if (!AddJob(jobList, con, &priv->objList)) RETURN_ASSERT(Parse_XmlError);\r
1020             con->resource_type = UCS_XRM_RC_TYPE_AVP_CON;\r
1021             con->socket_in_obj_ptr = priv->conData.inSocket;\r
1022             con->socket_out_obj_ptr = priv->conData.outSocket;\r
1023             con->isoc_packet_size = priv->conData.isocPacketSize;\r
1024             break;\r
1025         }\r
1026         default:\r
1027             UcsXml_CB_OnError("Could not connect sockets, data type not implemented: %d", 1, priv->conData.dataType);\r
1028             RETURN_ASSERT(Parse_XmlError);\r
1029             break;\r
1030         }\r
1031         ep = MCalloc(&priv->objList, 1, sizeof(Ucs_Rm_EndPoint_t));\r
1032         if (NULL == ep) RETURN_ASSERT(Parse_MemoryError);\r
1033 \r
1034         mostIsOutput = (UCS_XRM_RC_TYPE_MOST_SOCKET == *((Ucs_Xrm_ResourceType_t *)priv->conData.outSocket));\r
1035         ep->endpoint_type = mostIsOutput ? UCS_RM_EP_SOURCE : UCS_RM_EP_SINK;\r
1036         ep->jobs_list_ptr = GetJobList(*jobList, &priv->objList);\r
1037         if(NULL == ep->jobs_list_ptr) RETURN_ASSERT(Parse_MemoryError);\r
1038         ep->node_obj_ptr = priv->nodeData.nod;\r
1039         route = MCalloc(&priv->objList, 1, sizeof(struct UcsXmlRoute));\r
1040         if (NULL == route) RETURN_ASSERT(Parse_MemoryError);\r
1041         route->isSource = mostIsOutput;\r
1042         route->isActive = !priv->conData.isDeactivated;\r
1043         route->routeId = priv->conData.routeId;\r
1044         route->ep = ep;\r
1045         assert(NULL != priv->conData.routeName);\r
1046         strncpy(route->routeName, priv->conData.routeName, sizeof(route->routeName));\r
1047         AddRoute(&priv->pRtLst, route);\r
1048     }\r
1049     return Parse_Success;\r
1050 }\r
1051 \r
1052 static ParseResult_t ParseScript(mxml_node_t *scr, PrivateData_t *priv)\r
1053 {\r
1054     bool found = false;\r
1055     mxml_node_t *act;\r
1056     uint32_t actCnt;\r
1057     uint32_t i = 0;\r
1058     const char *txt;\r
1059     struct UcsXmlScript *scrlist;\r
1060     Ucs_Ns_Script_t *script;\r
1061     assert(NULL != scr && NULL != priv);\r
1062     priv->scriptData.pause = 0;\r
1063     scrlist = priv->pScrLst;\r
1064     if (!GetCountArray(scr->child, ALL_SCRIPTS, &actCnt, false)) RETURN_ASSERT(Parse_XmlError);\r
1065     if (NULL == (script = MCalloc(&priv->objList, actCnt, sizeof(Ucs_Ns_Script_t))))\r
1066         RETURN_ASSERT(Parse_MemoryError);\r
1067     actCnt = 0;\r
1068     /*Iterate all actions*/\r
1069     if (!GetElementArray(scr->child, ALL_SCRIPTS, &txt, &act)) RETURN_ASSERT(Parse_XmlError);\r
1070     while(act)\r
1071     {\r
1072         if (0 == strcmp(txt, SCRIPT_MSG_SEND)) {\r
1073             ParseResult_t result = ParseScriptMsgSend(act, &script[i], priv);\r
1074             if (Parse_Success != result) return result;\r
1075             ++actCnt;\r
1076         } else if (0 == strcmp(txt, SCRIPT_GPIO_PORT_CREATE)) {\r
1077             ParseResult_t result = ParseScriptGpioPortCreate(act, &script[i], priv);\r
1078             if (Parse_Success != result) return result;\r
1079             ++actCnt;\r
1080         } else if (0 == strcmp(txt, SCRIPT_GPIO_PORT_PIN_MODE)) {\r
1081             ParseResult_t result = ParseScriptGpioPinMode(act, &script[i], priv);\r
1082             if (Parse_Success != result) return result;\r
1083             ++actCnt;\r
1084         } else if (0 == strcmp(txt, SCRIPT_GPIO_PIN_STATE)) {\r
1085             ParseResult_t result = ParseScriptGpioPinState(act, &script[i], priv);\r
1086             if (Parse_Success != result) return result;\r
1087             ++actCnt;\r
1088         } else if (0 == strcmp(txt, SCRIPT_I2C_PORT_CREATE)) {\r
1089             ParseResult_t result = ParseScriptPortCreate(act, &script[i], priv);\r
1090             if (Parse_Success != result) return result;\r
1091             ++actCnt;\r
1092         } else if (0 == strcmp(txt, SCRIPT_I2C_PORT_WRITE)) {\r
1093             ParseResult_t result = ParseScriptPortWrite(act, &script[i], priv);\r
1094             if (Parse_Success != result) return result;\r
1095             ++actCnt;\r
1096         } else if (0 == strcmp(txt, SCRIPT_I2C_PORT_READ)) {\r
1097             ParseResult_t result = ParseScriptPortRead(act, &script[i], priv);\r
1098             if (Parse_Success != result) return result;\r
1099             ++actCnt;\r
1100         } else if (0 == strcmp(txt, SCRIPT_PAUSE)) {\r
1101             ParseResult_t result = ParseScriptPause(act, &script[i], priv);\r
1102             if (Parse_Success != result) return result;\r
1103         } else {\r
1104             UcsXml_CB_OnError("Unknown script action:'%s'", 1, txt);\r
1105             /*RETURN_ASSERT(Parse_XmlError);*/\r
1106         }\r
1107         if (!GetElementArray(act, ALL_SCRIPTS, &txt, &act))\r
1108             break;\r
1109         ++i;\r
1110     }\r
1111     if (!GetString(scr, NAME, &txt, true))\r
1112         RETURN_ASSERT(Parse_XmlError);\r
1113     while(NULL != scrlist)\r
1114     {\r
1115         if (0 == strcmp(txt, scrlist->scriptName))\r
1116         {\r
1117             Ucs_Rm_Node_t *node = scrlist->node;\r
1118             node->script_list_ptr = script;\r
1119             node->script_list_size = actCnt;\r
1120             found = true;\r
1121         }\r
1122         scrlist = scrlist->next;\r
1123     }\r
1124     if(!found)\r
1125     {\r
1126         UcsXml_CB_OnError("Script defined:'%s', which was never referenced", 1, txt);\r
1127         RETURN_ASSERT(Parse_XmlError);\r
1128     }\r
1129     return Parse_Success;\r
1130 }\r
1131 \r
1132 static bool FillScriptInitialValues(Ucs_Ns_Script_t *scr, PrivateData_t *priv)\r
1133 {\r
1134     assert(NULL != scr && NULL != priv);\r
1135     scr->send_cmd = MCalloc(&priv->objList, 1, sizeof(Ucs_Ns_ConfigMsg_t));\r
1136     scr->exp_result = MCalloc(&priv->objList, 1, sizeof(Ucs_Ns_ConfigMsg_t));\r
1137     assert(scr->send_cmd && scr->exp_result);\r
1138     if (NULL == scr->send_cmd || NULL == scr->exp_result) return false;\r
1139     scr->pause = priv->scriptData.pause;\r
1140     priv->scriptData.pause = 0;\r
1141     return true;\r
1142 }\r
1143 \r
1144 static ParseResult_t ParseScriptMsgSend(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)\r
1145 {\r
1146     Ucs_Ns_ConfigMsg_t *req, *res;\r
1147     assert(NULL != act && NULL != scr && NULL != priv);\r
1148     if (!FillScriptInitialValues(scr, priv)) return Parse_MemoryError;\r
1149     req = scr->send_cmd;\r
1150     res = scr->exp_result;\r
1151     req->InstId = res->InstId = 1;\r
1152     if (!GetUInt8(act, FBLOCK_ID, &req->FBlockId, true))\r
1153         RETURN_ASSERT(Parse_XmlError);\r
1154 \r
1155     if (!GetUInt16(act, FUNCTION_ID, &req->FunktId, true))\r
1156         RETURN_ASSERT(Parse_XmlError);\r
1157 \r
1158     if (!GetUInt8(act, OP_TYPE_REQUEST, &req->OpCode, true))\r
1159         RETURN_ASSERT(Parse_XmlError);\r
1160 \r
1161     res->FBlockId = req->FBlockId;\r
1162     res->FunktId = req->FunktId;\r
1163 \r
1164     if (GetUInt8(act, OP_TYPE_RESPONSE, &res->OpCode, false))\r
1165         GetPayload(act, PAYLOAD_RES_HEX, &res->DataPtr, &res->DataLen, 0, &priv->objList, false);\r
1166 \r
1167     if (!GetPayload(act, PAYLOAD_REQ_HEX, &req->DataPtr, &req->DataLen, 0, &priv->objList, true))\r
1168         RETURN_ASSERT(Parse_XmlError);\r
1169     if (0 == req->DataLen || NULL == req->DataPtr)\r
1170         RETURN_ASSERT(Parse_XmlError);\r
1171     return Parse_Success;\r
1172 }\r
1173 \r
1174 static ParseResult_t ParseScriptGpioPortCreate(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)\r
1175 {\r
1176     uint16_t debounce;\r
1177     Ucs_Ns_ConfigMsg_t *req, *res;\r
1178     assert(NULL != act && NULL != scr && NULL != priv);\r
1179     if (!FillScriptInitialValues(scr, priv))\r
1180         RETURN_ASSERT(Parse_MemoryError);\r
1181     if (!GetUInt16(act, DEBOUNCE_TIME, &debounce, true))\r
1182         RETURN_ASSERT(Parse_XmlError);\r
1183     req = scr->send_cmd;\r
1184     res = scr->exp_result;\r
1185     req->InstId = res->InstId = 1;\r
1186     req->FunktId = res->FunktId = 0x701;\r
1187     req->OpCode = 0x2;\r
1188     res->OpCode = 0xC;\r
1189     req->DataLen = 3;\r
1190     res->DataLen = 2;\r
1191     req->DataPtr = MCalloc(&priv->objList, req->DataLen, 1);\r
1192     if (NULL == req->DataPtr) return Parse_MemoryError;\r
1193     res->DataPtr = MCalloc(&priv->objList, res->DataLen, 1);\r
1194     if (NULL == res->DataPtr) return Parse_MemoryError;\r
1195     req->DataPtr[0] = 0; /*GPIO Port instance, always 0*/\r
1196     req->DataPtr[1] = MISC_HB(debounce);\r
1197     req->DataPtr[2] = MISC_LB(debounce);\r
1198 \r
1199     res->DataPtr[0] = 0x1D;\r
1200     res->DataPtr[1] = 0x00;\r
1201     return Parse_Success;\r
1202 }\r
1203 \r
1204 static ParseResult_t ParseScriptGpioPinMode(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)\r
1205 {\r
1206 #define PORT_HANDLE_OFFSET (2)\r
1207     uint8_t *payload;\r
1208     uint8_t payloadLen = 0;\r
1209     Ucs_Ns_ConfigMsg_t *req, *res;\r
1210     assert(NULL != act && NULL != scr && NULL != priv);\r
1211     if (!FillScriptInitialValues(scr, priv))\r
1212         RETURN_ASSERT(Parse_MemoryError);\r
1213     req = scr->send_cmd;\r
1214     res = scr->exp_result;\r
1215     req->InstId = res->InstId = 1;\r
1216     req->FunktId = res->FunktId = 0x703;\r
1217     req->OpCode = 0x2;\r
1218     res->OpCode = 0xC;\r
1219     if (!GetPayload(act, PIN_CONFIG, &payload, &payloadLen,\r
1220         PORT_HANDLE_OFFSET, /* First two bytes are reserved for port handle */\r
1221         &priv->objList, true)) RETURN_ASSERT(Parse_XmlError);\r
1222     payload[0] = 0x1D;\r
1223     payload[1] = 0x00;\r
1224     req->DataPtr = payload;\r
1225     res->DataPtr = payload;\r
1226     req->DataLen = payloadLen + PORT_HANDLE_OFFSET;\r
1227     res->DataLen = payloadLen + PORT_HANDLE_OFFSET;\r
1228     return Parse_Success;\r
1229 }\r
1230 \r
1231 static ParseResult_t ParseScriptGpioPinState(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)\r
1232 {\r
1233     uint16_t mask, data;\r
1234     Ucs_Ns_ConfigMsg_t *req, *res;\r
1235     assert(NULL != act && NULL != scr && NULL != priv);\r
1236     if (!FillScriptInitialValues(scr, priv))\r
1237         RETURN_ASSERT(Parse_MemoryError);\r
1238     if (!GetUInt16(act, PIN_MASK, &mask, true))\r
1239         RETURN_ASSERT(Parse_XmlError);\r
1240     if (!GetUInt16(act, PIN_DATA, &data, true))\r
1241         RETURN_ASSERT(Parse_XmlError);\r
1242     req = scr->send_cmd;\r
1243     res = scr->exp_result;\r
1244     req->InstId = res->InstId = 1;\r
1245     req->FunktId = res->FunktId = 0x704;\r
1246     req->OpCode = 0x2;\r
1247     res->OpCode = 0xC;\r
1248     req->DataLen = 6;\r
1249     res->DataLen = 8;\r
1250     req->DataPtr = MCalloc(&priv->objList, req->DataLen, 1);\r
1251     if (NULL == req->DataPtr) return Parse_MemoryError;\r
1252     res->DataPtr = MCalloc(&priv->objList, res->DataLen, 1);\r
1253     if (NULL == res->DataPtr) return Parse_MemoryError;\r
1254     req->DataPtr[0] = 0x1D;\r
1255     req->DataPtr[1] = 0x00;\r
1256     req->DataPtr[2] = MISC_HB(mask);\r
1257     req->DataPtr[3] = MISC_LB(mask);\r
1258     req->DataPtr[4] = MISC_HB(data);\r
1259     req->DataPtr[5] = MISC_LB(data);\r
1260     memcpy(res->DataPtr, req->DataPtr, req->DataLen);\r
1261     res->DataPtr[6] = 0x00;\r
1262     res->DataPtr[7] = 0x00;\r
1263     return Parse_Success;\r
1264 }\r
1265 \r
1266 static ParseResult_t ParseScriptPortCreate(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)\r
1267 {\r
1268     const char *txt;\r
1269     uint8_t speed;\r
1270     Ucs_Ns_ConfigMsg_t *req, *res;\r
1271     assert(NULL != act && NULL != scr && NULL != priv);\r
1272     if (!FillScriptInitialValues(scr, priv))\r
1273         RETURN_ASSERT(Parse_MemoryError);\r
1274     if (!GetString(act, I2C_SPEED, &txt, true))\r
1275         RETURN_ASSERT(Parse_XmlError);\r
1276     if (0 == strcmp(txt, I2C_SPEED_SLOW))\r
1277         speed = 0;\r
1278     else if (0 == strcmp(txt, I2C_SPEED_FAST))\r
1279         speed = 1;\r
1280     else RETURN_ASSERT(Parse_XmlError);\r
1281     req = scr->send_cmd;\r
1282     res = scr->exp_result;\r
1283     req->InstId = res->InstId = 1;\r
1284     req->FunktId = res->FunktId = 0x6C1;\r
1285     req->OpCode = 0x2;\r
1286     res->OpCode = 0xC;\r
1287     req->DataLen = 4;\r
1288     res->DataLen = 2;\r
1289     req->DataPtr = MCalloc(&priv->objList, req->DataLen, 1);\r
1290     if (NULL == req->DataPtr) return Parse_MemoryError;\r
1291     res->DataPtr = MCalloc(&priv->objList, res->DataLen, 1);\r
1292     if (NULL == res->DataPtr) return Parse_MemoryError;\r
1293     req->DataPtr[0] = 0x00; /* I2C Port Instance always 0 */\r
1294     req->DataPtr[1] = 0x00; /* I2C slave address, always 0, because we are Master */\r
1295     req->DataPtr[2] = 0x01; /* We are Master */\r
1296     req->DataPtr[3] = speed;\r
1297 \r
1298     res->DataPtr[0] = 0x0F;\r
1299     res->DataPtr[1] = 0x00;\r
1300     return Parse_Success;\r
1301 }\r
1302 \r
1303 static ParseResult_t ParseScriptPortWrite(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)\r
1304 {\r
1305 #define HEADER_OFFSET 8\r
1306     const char *txt;\r
1307     uint8_t mode, blockCount, address, length, payloadLength;\r
1308     uint16_t timeout;\r
1309     uint8_t *payload;\r
1310     Ucs_Ns_ConfigMsg_t *req, *res;\r
1311     assert(NULL != act && NULL != scr && NULL != priv);\r
1312     if (GetString(act, I2C_WRITE_MODE, &txt, false))\r
1313     {\r
1314         if (0 == strcmp(txt, I2C_WRITE_MODE_DEFAULT))\r
1315             mode = 0;\r
1316         else if (0 == strcmp(txt, I2C_WRITE_MODE_REPEAT))\r
1317             mode = 1;\r
1318         else if (0 == strcmp(txt, I2C_WRITE_MODE_BURST))\r
1319             mode = 2;\r
1320     } else {\r
1321         mode = 0;\r
1322     }\r
1323     if (!GetUInt8(act, I2C_WRITE_BLOCK_COUNT, &blockCount, false))\r
1324         blockCount = 0;\r
1325     if (!GetUInt8(act, I2C_SLAVE_ADDRESS, &address, true))\r
1326         RETURN_ASSERT(Parse_XmlError);\r
1327     if (!GetUInt8(act, I2C_PAYLOAD_LENGTH, &length, false))\r
1328         length = 0;\r
1329     if (!GetUInt16(act, I2C_TIMEOUT, &timeout, false))\r
1330         timeout = 100;\r
1331     if (!GetPayload(act, I2C_PAYLOAD, &payload, &payloadLength, HEADER_OFFSET, &priv->objList, true))\r
1332         RETURN_ASSERT(Parse_XmlError);\r
1333     if (0 == length)\r
1334         length = payloadLength;\r
1335     if (!FillScriptInitialValues(scr, priv))\r
1336         RETURN_ASSERT(Parse_MemoryError);\r
1337     req = scr->send_cmd;\r
1338     res = scr->exp_result;\r
1339     req->InstId = res->InstId = 1;\r
1340     req->FunktId = res->FunktId = 0x6C4;\r
1341     req->OpCode = 0x2;\r
1342     res->OpCode = 0xC;\r
1343     req->DataLen = payloadLength + HEADER_OFFSET;\r
1344     res->DataLen = 4;\r
1345     req->DataPtr = payload;\r
1346     res->DataPtr = MCalloc(&priv->objList, res->DataLen, 1);\r
1347     if (NULL == res->DataPtr) return Parse_MemoryError;\r
1348 \r
1349     req->DataPtr[0] = 0x0F;\r
1350     req->DataPtr[1] = 0x00;\r
1351     req->DataPtr[2] = mode;\r
1352     req->DataPtr[3] = blockCount;\r
1353     req->DataPtr[4] = address;\r
1354     req->DataPtr[5] = length;\r
1355     req->DataPtr[6] = MISC_HB(timeout);\r
1356     req->DataPtr[7] = MISC_LB(timeout);\r
1357 \r
1358     res->DataPtr[0] = 0x0F;\r
1359     res->DataPtr[1] = 0x00;\r
1360     res->DataPtr[2] = address;\r
1361     if (2 == mode)\r
1362         res->DataPtr[3] = blockCount * length;\r
1363     else\r
1364         res->DataPtr[3] = length;\r
1365     return Parse_Success;\r
1366 }\r
1367 \r
1368 static ParseResult_t ParseScriptPortRead(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)\r
1369 {\r
1370     uint8_t address, length;\r
1371     uint16_t timeout;\r
1372     Ucs_Ns_ConfigMsg_t *req, *res;\r
1373     assert(NULL != act && NULL != scr && NULL != priv);\r
1374     if (!GetUInt8(act, I2C_SLAVE_ADDRESS, &address, true))\r
1375         RETURN_ASSERT(Parse_XmlError);\r
1376     if (!GetUInt8(act, I2C_PAYLOAD_LENGTH, &length, true))\r
1377         RETURN_ASSERT(Parse_XmlError);\r
1378     if (!GetUInt16(act, I2C_TIMEOUT, &timeout, false))\r
1379         timeout = 100;\r
1380     if (!FillScriptInitialValues(scr, priv))\r
1381         RETURN_ASSERT(Parse_MemoryError);\r
1382     req = scr->send_cmd;\r
1383     res = scr->exp_result;\r
1384     req->InstId = res->InstId = 1;\r
1385     req->FunktId = res->FunktId = 0x6C3;\r
1386     req->OpCode = 0x2;\r
1387     res->OpCode = 0xC;\r
1388     req->DataLen = 6;\r
1389     res->DataLen = 4;\r
1390     req->DataPtr = MCalloc(&priv->objList, req->DataLen, 1);\r
1391     if (NULL == req->DataPtr) return Parse_MemoryError;\r
1392     res->DataPtr = MCalloc(&priv->objList, res->DataLen, 1);\r
1393     if (NULL == res->DataPtr) return Parse_MemoryError;\r
1394 \r
1395     req->DataPtr[0] = 0x0F;\r
1396     req->DataPtr[1] = 0x00;\r
1397     req->DataPtr[2] = address;\r
1398     req->DataPtr[3] = length;\r
1399     req->DataPtr[4] = MISC_HB(timeout);\r
1400     req->DataPtr[5] = MISC_LB(timeout);\r
1401 \r
1402     res->DataPtr[0] = 0x0F;\r
1403     res->DataPtr[1] = 0x00;\r
1404     res->DataPtr[2] = address;\r
1405     res->DataPtr[3] = length;\r
1406     return Parse_Success;\r
1407 }\r
1408 \r
1409 static ParseResult_t ParseScriptPause(mxml_node_t *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)\r
1410 {\r
1411     assert(NULL != act && NULL != priv);\r
1412     if (!GetUInt16(act, PAUSE_MS, &priv->scriptData.pause, true))\r
1413             RETURN_ASSERT(Parse_XmlError);\r
1414     return Parse_Success;\r
1415 }\r
1416 \r
1417 static ParseResult_t ParseRoutes(UcsXmlVal_t *ucs, PrivateData_t *priv)\r
1418 {\r
1419     uint16_t routeAmount = 0;\r
1420     struct UcsXmlRoute *sourceRoute;\r
1421     assert(NULL != ucs && NULL != priv);\r
1422     /*First: Count the amount of routes and allocate the correct amount*/\r
1423     sourceRoute = priv->pRtLst;\r
1424     while (NULL != sourceRoute)\r
1425     {\r
1426         if (!sourceRoute->isSource) /*There can be more sinks than sources, so count them*/\r
1427         {\r
1428             ++routeAmount;\r
1429         }\r
1430         sourceRoute = sourceRoute->next;\r
1431     }\r
1432     if (0 == routeAmount)\r
1433         return Parse_Success; /*Its okay to have no routes at all (e.g. MEP traffic only)*/\r
1434     ucs->pRoutes = MCalloc(&priv->objList, routeAmount, sizeof(Ucs_Rm_Route_t));\r
1435     if (NULL == ucs->pRoutes) RETURN_ASSERT(Parse_MemoryError);\r
1436 \r
1437     /*Second: Fill allocated structure now*/\r
1438     sourceRoute = priv->pRtLst;\r
1439     while (NULL != sourceRoute)\r
1440     {\r
1441         if (sourceRoute->isSource)\r
1442         {\r
1443             struct UcsXmlRoute *sinkRoute = priv->pRtLst;\r
1444             while (NULL != sinkRoute)\r
1445             {\r
1446                 if (sourceRoute != sinkRoute\r
1447                     && !sinkRoute->isSource\r
1448                     && (0 == strncmp(sourceRoute->routeName, sinkRoute->routeName, sizeof(sourceRoute->routeName))))\r
1449                 {\r
1450                     Ucs_Rm_Route_t *route = &ucs->pRoutes[ucs->routesSize++];\r
1451                     route->source_endpoint_ptr = sourceRoute->ep;\r
1452                     route->sink_endpoint_ptr = sinkRoute->ep;\r
1453                     route->active = sinkRoute->isActive;\r
1454                     route->route_id = sinkRoute->routeId;\r
1455                 }\r
1456                 sinkRoute = sinkRoute->next;\r
1457             }\r
1458         }\r
1459         sourceRoute = sourceRoute->next;\r
1460     }\r
1461     assert(routeAmount == ucs->routesSize);\r
1462 \r
1463 #ifdef DEBUG\r
1464     /* Third perform checks when running in debug mode*/\r
1465     {\r
1466         Ucs_Xrm_ResourceType_t *job;\r
1467         uint16_t i, j;\r
1468         for (i = 0; i < routeAmount; i++)\r
1469         {\r
1470             Ucs_Rm_Route_t *route = &ucs->pRoutes[i];\r
1471             assert(NULL != route->source_endpoint_ptr);\r
1472             assert(NULL != route->sink_endpoint_ptr);\r
1473             assert(NULL != route->source_endpoint_ptr->jobs_list_ptr);\r
1474             assert(UCS_RM_EP_SOURCE == route->source_endpoint_ptr->endpoint_type);\r
1475             assert(UCS_RM_EP_SINK == route->sink_endpoint_ptr->endpoint_type);\r
1476             assert(NULL != route->source_endpoint_ptr->node_obj_ptr);\r
1477             assert(NULL != route->sink_endpoint_ptr->node_obj_ptr);\r
1478             assert(NULL != route->source_endpoint_ptr->node_obj_ptr->signature_ptr);\r
1479             assert(NULL != route->sink_endpoint_ptr->node_obj_ptr->signature_ptr);\r
1480             j = 0;\r
1481             while((job = ((Ucs_Xrm_ResourceType_t *)route->source_endpoint_ptr->jobs_list_ptr[j])))\r
1482             {\r
1483                 assert(UCS_XRM_RC_TYPE_QOS_CON >= *job);\r
1484                 ++j;\r
1485             }\r
1486             j = 0;\r
1487             while((job = ((Ucs_Xrm_ResourceType_t *)route->sink_endpoint_ptr->jobs_list_ptr[j])))\r
1488             {\r
1489                 assert(UCS_XRM_RC_TYPE_QOS_CON >= *job);\r
1490                 ++j;\r
1491             }\r
1492         }\r
1493     }\r
1494 #endif\r
1495     return Parse_Success;\r
1496 }\r