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