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