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