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