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