1 /*------------------------------------------------------------------------------------------------*/
2 /* UNICENS XML Parser */
3 /* Copyright 2017, Microchip Technology Inc. and its subsidiaries. */
5 /* Redistribution and use in source and binary forms, with or without */
6 /* modification, are permitted provided that the following conditions are met: */
8 /* 1. Redistributions of source code must retain the above copyright notice, this */
9 /* list of conditions and the following disclaimer. */
11 /* 2. Redistributions in binary form must reproduce the above copyright notice, */
12 /* this list of conditions and the following disclaimer in the documentation */
13 /* and/or other materials provided with the distribution. */
15 /* 3. Neither the name of the copyright holder nor the names of its */
16 /* contributors may be used to endorse or promote products derived from */
17 /* this software without specific prior written permission. */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" */
20 /* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE */
21 /* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE */
23 /* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL */
24 /* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR */
25 /* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */
26 /* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, */
27 /* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
28 /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /*------------------------------------------------------------------------------------------------*/
32 #include <libxml/tree.h>
33 #include <libxml/parser.h>
34 #include "UcsXml_Private.h"
37 /************************************************************************/
38 /* PRIVATE DECLARATIONS */
39 /************************************************************************/
41 #define COMPILETIME_CHECK(cond) (void)sizeof(int[2 * !!(cond) - 1])
42 #define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__)
43 #define RETURN_ASSERT(result) { UcsXml_CB_OnError("Assertion in file=%s, line=%d", 2, __FILENAME__, __LINE__); return result; }
44 #define MISC_HB(value) ((uint8_t)((uint16_t)(value) >> 8))
45 #define MISC_LB(value) ((uint8_t)((uint16_t)(value) & (uint16_t)0xFF))
46 #define ROUTE_AUTO_ID_START (0x8000)
54 Ucs_Rm_EndPoint_t *ep;
55 struct UcsXmlRoute *next;
63 struct UcsXmlScript *next;
68 Ucs_Xrm_ResObject_t *job;
69 struct UcsXmlJobList *next;
92 Ucs_Xrm_UsbPort_t *usbPort;
93 Ucs_Xrm_MlbPort_t *mlbPort;
94 Ucs_Xrm_StrmPort_t *strmPortA;
95 Ucs_Xrm_StrmPort_t *strmPortB;
100 MDataType_t dataType;
102 bool syncOffsetNeeded;
106 const char *routeName;
107 Ucs_Xrm_ResObject_t *inSocket;
108 Ucs_Xrm_ResObject_t *outSocket;
109 struct UcsXmlJobList *jobList;
110 Ucs_Xrm_Combiner_t *combiner;
111 xmlNode *pendingCombinerMostSockets;
112 Ucs_Sync_MuteMode_t muteMode;
113 Ucs_Avp_IsocPacketSize_t isocPacketSize;
123 uint16_t autoRouteId;
124 struct UcsXmlObjectList objList;
125 struct UcsXmlRoute *pRtLst;
126 struct UcsXmlScript *pScrLst;
128 ConnectionData_t conData;
129 ScriptData_t scriptData;
132 /************************************************************************/
134 /************************************************************************/
137 static const char* UNICENS = "Unicens";
138 static const char* PACKET_BW = "AsyncBandwidth";
139 static const char* NAME = "Name";
140 static const char* ROUTE = "Route";
141 static const char* ROUTE_ID = "RouteId";
142 static const char* ROUTE_IS_ACTIVE = "IsActive";
143 static const char* ENDPOINT_ADDRESS = "EndpointAddress";
144 static const char* CHANNEL_ADDRESS = "ChannelAddress";
145 static const char* BANDWIDTH = "Bandwidth";
146 static const char* BYTES_PER_FRAME = "BytesPerFrame";
147 static const char* OFFSET = "Offset";
148 static const char* NODE = "Node";
149 static const char* CLOCK_CONFIG = "ClockConfig";
150 static const char* ADDRESS = "Address";
151 static const char* FRAMES_PER_TRANSACTION = "FramesPerTransaction";
152 static const char* MUTE_MODE = "MuteMode";
153 static const char* MUTE_MODE_NO_MUTING = "NoMuting";
154 static const char* MUTE_MODE_MUTE_SIGNAL = "MuteSignal";
155 static const char* AVP_PACKET_SIZE = "IsocPacketSize";
156 #define SYNC_CONNECTION "SyncConnection"
157 #define AVP_CONNECTION "AVPConnection"
158 #define DFP_CONNECTION "DFPhaseConnection"
159 #define QOS_CONNECTION "QoSConnection"
160 #define IPC_CONNECTION "IPCConnection"
162 static const char* ALL_CONNECTIONS[] = { SYNC_CONNECTION, AVP_CONNECTION,
163 DFP_CONNECTION, QOS_CONNECTION, IPC_CONNECTION, NULL };
165 #define MOST_SOCKET "MOSTSocket"
166 #define USB_SOCKET "USBSocket"
167 #define MLB_SOCKET "MediaLBSocket"
168 #define STREAM_SOCKET "StreamSocket"
169 #define SPLITTER "Splitter"
170 #define COMBINER "Combiner"
171 static const char* ALL_SOCKETS[] = { MOST_SOCKET, USB_SOCKET, MLB_SOCKET,
172 STREAM_SOCKET, SPLITTER, COMBINER, NULL };
174 #define MLB_PORT "MediaLBPort"
175 #define USB_PORT "USBPort"
176 #define STRM_PORT "StreamPort"
177 static const char* ALL_PORTS[] = { MLB_PORT, USB_PORT, STRM_PORT, NULL };
179 static const char* PHYSICAL_LAYER = "PhysicalLayer";
180 static const char* DEVICE_INTERFACES = "DeviceInterfaces";
181 static const char* STRM_IN_COUNT = "StreamingIfEpInCount";
182 static const char* STRM_OUT_COUNT = "StreamingIfEpOutCount";
184 static const char* STRM_PIN = "StreamPinID";
185 static const char* STRM_ALIGN = "DataAlignment";
187 static const char* SCRIPT = "Script";
188 static const char* FBLOCK_ID = "FBlockId";
189 static const char* FUNCTION_ID = "FunctionId";
190 static const char* OP_TYPE_REQUEST = "OpTypeRequest";
191 static const char* OP_TYPE_RESPONSE = "OpTypeResponse";
192 static const char* PAYLOAD_REQ_HEX = "PayloadRequest";
193 static const char* PAYLOAD_RES_HEX = "PayloadResponse";
194 static const char* PAUSE_MS = "WaitTime";
195 static const char* DEBOUNCE_TIME = "DebounceTime";
196 static const char* PIN_CONFIG = "PinConfiguration";
197 static const char* PIN_MASK = "Mask";
198 static const char* PIN_DATA = "Data";
199 static const char* I2C_SPEED = "Speed";
200 static const char* I2C_SPEED_SLOW = "SlowMode";
201 static const char* I2C_SPEED_FAST = "FastMode";
202 static const char* I2C_WRITE_MODE = "Mode";
203 static const char* I2C_WRITE_MODE_DEFAULT = "DefaultMode";
204 static const char* I2C_WRITE_MODE_REPEAT = "RepeatedStartMode";
205 static const char* I2C_WRITE_MODE_BURST = "BurstMode";
206 static const char* I2C_WRITE_BLOCK_COUNT = "BlockCount";
207 static const char* I2C_SLAVE_ADDRESS = "Address";
208 static const char* I2C_PAYLOAD_LENGTH = "Length";
209 static const char* I2C_PAYLOAD = "Payload";
210 static const char* I2C_TIMEOUT = "Timeout";
212 #define SCRIPT_MSG_SEND "MsgSend"
213 #define SCRIPT_PAUSE "Pause"
214 #define SCRIPT_GPIO_PORT_CREATE "GPIOPortCreate"
215 #define SCRIPT_GPIO_PORT_PIN_MODE "GPIOPortPinMode"
216 #define SCRIPT_GPIO_PIN_STATE "GPIOPinState"
217 #define SCRIPT_I2C_PORT_CREATE "I2CPortCreate"
218 #define SCRIPT_I2C_PORT_WRITE "I2CPortWrite"
219 #define SCRIPT_I2C_PORT_READ "I2CPortRead"
220 static const char* ALL_SCRIPTS[] = { SCRIPT_MSG_SEND, SCRIPT_PAUSE,
221 SCRIPT_GPIO_PORT_CREATE, SCRIPT_GPIO_PORT_PIN_MODE, SCRIPT_GPIO_PIN_STATE,
222 SCRIPT_I2C_PORT_CREATE, SCRIPT_I2C_PORT_WRITE, SCRIPT_I2C_PORT_READ, NULL };
224 static const char* VALUE_TRUE = "true";
225 static const char* VALUE_FALSE = "false";
226 static const char* VALUE_1 = "1";
227 static const char* VALUE_0 = "0";
229 /************************************************************************/
230 /* Private Function Prototypes */
231 /************************************************************************/
233 static void FreeVal(UcsXmlVal_t *ucs);
234 static bool GetElement(xmlNode *element, const char *name, bool goDeep, xmlNode **out, bool mandatory);
235 static bool GetElementArray(xmlNode *element, const char *array[], const char **foundName, xmlNode **out);
236 static bool GetCount(xmlNode *element, const char *name, uint32_t *out, bool mandatory);
237 static bool GetCountArray(xmlNode *element, const char *array[], uint32_t *out, bool mandatory);
238 static bool GetString(xmlNode *element, const char *key, const char **out, bool mandatory);
239 static bool CheckInteger(const char *val, bool forceHex);
240 static bool GetUInt16(xmlNode *element, const char *key, uint16_t *out, bool mandatory);
241 static bool GetUInt8(xmlNode *element, const char *key, uint8_t *out, bool mandatory);
242 static bool GetSocketType(const char *txt, MSocketType_t *out);
243 static bool GetPayload(xmlNode *element, const char *name, uint8_t **pPayload, uint8_t *len, uint8_t offset,
244 struct UcsXmlObjectList *obj, bool mandatory);
245 static bool AddJob(struct UcsXmlJobList **joblist, Ucs_Xrm_ResObject_t *job, struct UcsXmlObjectList *objList);
246 static Ucs_Xrm_ResObject_t **GetJobList(struct UcsXmlJobList *joblist, struct UcsXmlObjectList *objList);
247 static struct UcsXmlJobList *DeepCopyJobList(struct UcsXmlJobList *jobsIn, struct UcsXmlObjectList *objList);
248 static void AddRoute(struct UcsXmlRoute **pRtLst, struct UcsXmlRoute *route);
249 static void AddScript(struct UcsXmlScript **pScrLst, struct UcsXmlScript *script);
250 static ParseResult_t ParseAll(xmlNode * node, UcsXmlVal_t *ucs, PrivateData_t *priv);
251 static ParseResult_t ParseNode(xmlNode * node, PrivateData_t *priv);
252 static ParseResult_t ParseConnection(xmlNode * node, const char *conType, PrivateData_t *priv);
253 static ParseResult_t ParseSocket(xmlNode *soc, bool isSource, MSocketType_t socketType, struct UcsXmlJobList **jobList, PrivateData_t *priv);
254 static ParseResult_t ParseScript(xmlNode *scr, PrivateData_t *priv);
255 static bool FillScriptInitialValues(Ucs_Ns_Script_t *scr, PrivateData_t *priv);
256 static ParseResult_t ParseScriptMsgSend(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);
257 static ParseResult_t ParseScriptGpioPortCreate(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);
258 static ParseResult_t ParseScriptGpioPinMode(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);
259 static ParseResult_t ParseScriptGpioPinState(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);
260 static ParseResult_t ParseScriptPortCreate(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);
261 static ParseResult_t ParseScriptPortWrite(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);
262 static ParseResult_t ParseScriptPortRead(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);
263 static ParseResult_t ParseScriptPause(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv);
264 static ParseResult_t ParseRoutes(UcsXmlVal_t *ucs, PrivateData_t *priv);
265 static bool IsAutoRouteId(uint16_t id, PrivateData_t *priv);
267 /************************************************************************/
268 /* Public Functions */
269 /************************************************************************/
271 UcsXmlVal_t *UcsXml_Parse(const char *xmlString)
274 UcsXmlVal_t *val = NULL;
275 ParseResult_t result = Parse_MemoryError;
277 if (NULL == (root = xmlReadMemory( xmlString, strlen( xmlString ), "config.xml", NULL, 0 ))) goto ERROR;
278 tree = xmlDocGetRootElement(root);
279 if (0 != strcmp(UNICENS, (const char *)tree->name)) goto ERROR;
280 /*Do not use MCalloc for the root element*/
281 val = calloc(1, sizeof(UcsXmlVal_t));
282 if (!val) goto ERROR;
283 val->pInternal = calloc(1, sizeof(PrivateData_t));
284 if (!val->pInternal) goto ERROR;
285 ((PrivateData_t *)val->pInternal)->root = root;
286 result = ParseAll(tree, val, val->pInternal);
287 if (Parse_Success == result)
290 if (Parse_MemoryError == result)
291 UcsXml_CB_OnError("XML memory error, aborting..", 0);
293 UcsXml_CB_OnError("XML parsing error, aborting..", 0);
302 void UcsXml_FreeVal(UcsXmlVal_t *val)
307 /************************************************************************/
308 /* Private Function Implementations */
309 /************************************************************************/
311 void FreeVal(UcsXmlVal_t *ucs)
314 if (NULL == ucs || NULL == ucs->pInternal)
316 priv = ucs->pInternal;
317 FreeObjList(&priv->objList);
320 xmlFreeDoc(priv->root);
322 free(ucs->pInternal);
326 static bool GetElement(xmlNode *element, const char *name, bool goDeep, xmlNode **out, bool mandatory)
328 xmlNode *n = element;
329 if (NULL == n || NULL == name || NULL == out) return false;
330 if (goDeep && GetElement(n->children, name, goDeep, out, false))
334 while ((n = n->next))
336 if (XML_ELEMENT_NODE != n->type)
338 if (0 == strcmp(name, (const char *)n->name))
343 else if (goDeep && GetElement(n->children, name, goDeep, out, false))
349 UcsXml_CB_OnError("Can not find tag <%s>", 1, name);
353 static bool GetElementArray(xmlNode *element, const char *array[], const char **foundName, xmlNode **out)
355 xmlNode *n = element;
356 if (NULL == n || NULL == array || NULL == foundName || NULL == out) return false;
357 while ((n = n->next))
360 for (i = 0; NULL != array[i]; i++)
362 if (0 == strcmp(array[i], (const char *)n->name))
364 *foundName = array[i];
373 static bool GetCount(xmlNode *element, const char *name, uint32_t *out, bool mandatory)
377 if (NULL == element || NULL == name) return false;
378 if(!GetElement(element, name, true, &n, false))
383 if(!GetElement(n, name, false, &n, false))
386 if (mandatory && 0 == cnt)
388 UcsXml_CB_OnError("element count of <%s> is zero", 1, name);
395 static bool GetCountArray(xmlNode *element, const char *array[], uint32_t *out, bool mandatory)
400 if (NULL == element || NULL == array) return false;
404 if(!GetElementArray(n, array, &tmp, &n))
408 if (mandatory && 0 == cnt)
410 UcsXml_CB_OnError("element count is zero, searched with string array", 0);
417 static bool GetString(xmlNode *element, const char *key, const char **out, bool mandatory)
419 struct _xmlAttr *curAttr;
420 if (NULL == element || NULL == key) return false;
421 curAttr = element->properties;
424 if (XML_ATTRIBUTE_NODE != curAttr->type)
426 if (0 == strcmp(key, (const char *)curAttr->name))
428 struct _xmlNode *valAttr = curAttr->children;
431 if (XML_TEXT_NODE != valAttr->type)
433 *out = (const char *)valAttr->content;
436 while (NULL != (valAttr = valAttr->next));
439 while (NULL != (curAttr = curAttr->next));
441 UcsXml_CB_OnError("Can not find attribute='%s' from element <%s>",
442 2, key, element->name);
446 static bool CheckInteger(const char *value, bool forceHex)
450 if (!value) return false;
452 if (len >= 3 && '0' == value[0] && 'x' == value[1])
460 uint8_t v = value[0];
461 if (v >= '0' && v <= '9') valid = true;
464 if (v >= 'a' && v <= 'f') valid = true;
465 if (v >= 'A' && v <= 'F') valid = true;
467 if (!valid) return false;
473 static bool GetUInt16(xmlNode *element, const char *key, uint16_t *out, bool mandatory)
477 if (!GetString(element, key, &txt, mandatory)) return false;
478 if (!CheckInteger(txt, false))
480 UcsXml_CB_OnError("key='%s' contained invalid integer='%s'", 2, key, txt);
483 value = strtol( txt, NULL, 0 );
486 UcsXml_CB_OnError("key='%s' is out of range='%d'", 2, key, value);
493 static bool GetUInt8(xmlNode *element, const char *key, uint8_t *out, bool mandatory)
497 if (!GetString(element, key, &txt, mandatory)) return false;
498 if (!CheckInteger(txt, false))
500 UcsXml_CB_OnError("key='%s' contained invalid integer='%s'", 2, key, txt);
503 value = strtol( txt, NULL, 0 );
506 UcsXml_CB_OnError("key='%s' is out of range='%d'", 2, key, value);
513 static bool GetDataType(const char *txt, MDataType_t *out)
515 if (NULL == txt || NULL == out) return false;
516 if (0 == strcmp(SYNC_CONNECTION, txt)) {
518 } else if (0 == strcmp(AVP_CONNECTION, txt)) {
519 *out = AV_PACKETIZED;
520 } else if (0 == strcmp(QOS_CONNECTION, txt)) {
522 } else if (0 == strcmp(DFP_CONNECTION, txt)) {
523 *out = DISC_FRAME_PHASE;
524 } else if (0 == strcmp(IPC_CONNECTION, txt)) {
527 UcsXml_CB_OnError("Unknown data type : '%s'", 1, txt);
533 static bool GetSocketType(const char *txt, MSocketType_t *out)
535 if (0 == strcmp(txt, MOST_SOCKET)) {
537 } else if (0 == strcmp(txt, USB_SOCKET)) {
539 } else if (0 == strcmp(txt, MLB_SOCKET)) {
541 } else if (0 == strcmp(txt, STREAM_SOCKET)) {
543 } else if (0 == strcmp(txt, SPLITTER)) {
544 *out = MSocket_SPLITTER;
545 } else if (0 == strcmp(txt, COMBINER)) {
546 *out = MSocket_COMBINER;
548 UcsXml_CB_OnError("Unknown port : '%s'", 1, txt);
554 static bool GetPayload(xmlNode *element, const char *name, uint8_t **pPayload, uint8_t *outLen, uint8_t offset, struct UcsXmlObjectList *obj, bool mandatory)
556 uint32_t tempLen, len = 0;
562 if (!GetString(element, name, &txt, mandatory))
564 tempLen = strlen(txt) + 1;
565 txtCopy = malloc(tempLen);
568 strncpy(txtCopy, txt, tempLen);
569 tempLen = tempLen / 3; /* 2 chars hex value plus space (AA ) */
570 p = MCalloc(obj, offset + tempLen, 1);
577 token = strtok_r( txtCopy, " ,.-", &tkPtr );
578 while( NULL != token )
582 UcsXml_CB_OnError("Script payload values must be stuffed to two characters", 0);
587 if (!CheckInteger(token, true))
589 UcsXml_CB_OnError("Script payload contains non valid hex number='%s'", 1, token);
594 p[offset + len++] = strtol( token, NULL, 16 );
595 token = strtok_r( NULL, " ,.-", &tkPtr );
601 static bool AddJob(struct UcsXmlJobList **joblist, Ucs_Xrm_ResObject_t *job, struct UcsXmlObjectList *objList)
603 struct UcsXmlJobList *tail;
604 if (NULL == joblist || NULL == job)
606 assert(UCS_XRM_RC_TYPE_QOS_CON >= *((Ucs_Xrm_ResourceType_t *)job));
607 if (NULL == joblist[0])
609 joblist[0] = MCalloc(objList, 1, sizeof(struct UcsXmlJobList));
610 if (NULL == joblist[0]) return false;;
611 joblist[0]->job = job;
615 while(tail->next) tail = tail->next;
616 tail->next = MCalloc(objList, 1, sizeof(struct UcsXmlJobList));
617 if (NULL == tail->next) return false;
618 tail->next->job = job;
622 static Ucs_Xrm_ResObject_t **GetJobList(struct UcsXmlJobList *joblist, struct UcsXmlObjectList *objList)
624 Ucs_Xrm_ResObject_t **outJob;
626 struct UcsXmlJobList *tail;
629 /*First: Get amount of stored jobs by enumerate all*/
638 /*Second: Allocate count+1 elements (NULL terminated) and copy pointers*/
639 outJob = MCalloc(objList, (count + 1), sizeof(Ucs_Xrm_ResObject_t *));
646 outJob[count++] = tail->job;
652 static struct UcsXmlJobList *DeepCopyJobList(struct UcsXmlJobList *jobsIn, struct UcsXmlObjectList *objList)
654 struct UcsXmlJobList *jobsOut, *tail;
655 if (NULL == jobsIn || NULL == objList)
657 jobsOut = tail = MCalloc(objList, 1, sizeof(struct UcsXmlJobList));
658 if (NULL == jobsOut) { assert(false); return NULL; }
661 tail->job = jobsIn->job;
664 tail->next = MCalloc(objList, 1, sizeof(struct UcsXmlJobList));
665 if (NULL == tail->next) { assert(false); return NULL; }
668 jobsIn = jobsIn->next;
673 static void AddRoute(struct UcsXmlRoute **pRtLst, struct UcsXmlRoute *route)
675 struct UcsXmlRoute *tail;
676 if (NULL == pRtLst || NULL == route)
681 if (NULL == pRtLst[0])
687 while(tail->next) tail = tail->next;
691 static void AddScript(struct UcsXmlScript **pScrLst, struct UcsXmlScript *script)
693 struct UcsXmlScript *tail;
694 if (NULL == pScrLst || NULL == script)
699 if (NULL == pScrLst[0])
705 while(tail->next) tail = tail->next;
709 static ParseResult_t ParseAll(xmlNode *tree, UcsXmlVal_t *ucs, PrivateData_t *priv)
713 ParseResult_t result;
714 priv->autoRouteId = ROUTE_AUTO_ID_START;
715 if (!GetCount(tree, NODE, &nodeCount, true))
716 RETURN_ASSERT(Parse_XmlError);
718 ucs->pNod = MCalloc(&priv->objList, nodeCount, sizeof(Ucs_Rm_Node_t));
719 if (NULL == ucs->pNod) RETURN_ASSERT(Parse_MemoryError);
721 if (!GetUInt16(tree, PACKET_BW, &ucs->packetBw, true))
722 RETURN_ASSERT(Parse_XmlError);
724 /*Iterate all nodes*/
725 if (!GetElement(tree, NODE, true, &sub, true))
726 RETURN_ASSERT(Parse_XmlError);
731 memset(&priv->nodeData, 0, sizeof(NodeData_t));
732 priv->nodeData.nod = &ucs->pNod[ucs->nodSize];
733 if (Parse_Success != (result = ParseNode(sub, priv)))
735 /*/Iterate all connections. Node without any connection is also valid.*/
736 if (GetElementArray(sub->children, ALL_CONNECTIONS, &conType, &con))
740 const char *socTypeStr;
741 MSocketType_t socType;
743 memset(&priv->conData, 0, sizeof(ConnectionData_t));
744 if (Parse_Success != (result = ParseConnection(con, conType, priv)))
746 /*Iterate all sockets*/
747 if(!GetElementArray(con->children, ALL_SOCKETS, &socTypeStr, &soc)) RETURN_ASSERT(Parse_XmlError);
750 if (!GetSocketType(socTypeStr, &socType)) RETURN_ASSERT(Parse_XmlError);
751 if (Parse_Success != (result = ParseSocket(soc, (0 == priv->conData.sockCnt), socType, &priv->conData.jobList, priv)))
753 ++priv->conData.sockCnt;
754 if(!GetElementArray(soc, ALL_SOCKETS, &socTypeStr, &soc))
757 if(!GetElementArray(con, ALL_CONNECTIONS, &conType, &con))
762 if (!GetElement(sub, NODE, false, &sub, false))
766 /*Fill route structures*/
767 result = ParseRoutes(ucs, priv);
768 if (Parse_MemoryError == result) RETURN_ASSERT(Parse_MemoryError)
769 else if (Parse_XmlError == result) RETURN_ASSERT(Parse_XmlError);
771 /*Iterate all scripts. No scripts at all is allowed*/
772 if(GetElement(tree, SCRIPT, true, &sub, false))
775 struct UcsXmlScript *scrlist = priv->pScrLst;
778 result = ParseScript(sub, priv);
779 if (Parse_MemoryError == result) RETURN_ASSERT(Parse_MemoryError)
780 else if (Parse_XmlError == result) RETURN_ASSERT(Parse_XmlError);
781 if(!GetElement(sub, SCRIPT, false, &sub, false))
784 /* Check if all scripts where referenced */
785 while(NULL != scrlist)
789 UcsXml_CB_OnError("Script not defined:'%s', used by node=0x%X", 1, scrlist->scriptName, scrlist->node->signature_ptr->node_address);
792 scrlist = scrlist->next;
795 RETURN_ASSERT(Parse_XmlError);
800 static ParseResult_t ParseNode(xmlNode *node, PrivateData_t *priv)
804 Ucs_Signature_t *signature;
805 assert(NULL != node && NULL != priv);
806 priv->nodeData.nod->signature_ptr = MCalloc(&priv->objList, 1, sizeof(Ucs_Signature_t));
807 signature = priv->nodeData.nod->signature_ptr;
808 if(NULL == signature) RETURN_ASSERT(Parse_MemoryError);
809 if (!GetUInt16(node, ADDRESS, &signature->node_address, true))
810 RETURN_ASSERT(Parse_XmlError);
811 if (GetString(node, SCRIPT, &txt, false))
813 struct UcsXmlScript *scr = MCalloc(&priv->objList, 1, sizeof(struct UcsXmlScript));
814 if (NULL == scr) RETURN_ASSERT(Parse_MemoryError);
815 scr->node = priv->nodeData.nod;
816 strncpy(scr->scriptName, txt, sizeof(scr->scriptName));
817 AddScript(&priv->pScrLst, scr);
819 /*Iterate all ports*/
820 if(GetElementArray(node->children, ALL_PORTS, &txt, &port))
824 if (0 == (strcmp(txt, MLB_PORT)))
826 struct MlbPortParameters p;
827 p.list = &priv->objList;
828 if (!GetString(port, CLOCK_CONFIG, &p.clockConfig, true)) RETURN_ASSERT(Parse_XmlError);
829 if (!GetMlbPort(&priv->nodeData.mlbPort, &p)) RETURN_ASSERT(Parse_XmlError);
831 else if (0 == (strcmp(txt, USB_PORT)))
833 struct UsbPortParameters p;
834 p.list = &priv->objList;
835 if (!GetString(port, PHYSICAL_LAYER, &p.physicalLayer, true)) RETURN_ASSERT(Parse_XmlError);
836 if (!GetString(port, DEVICE_INTERFACES, &p.deviceInterfaces, true)) RETURN_ASSERT(Parse_XmlError);
837 if (!GetString(port, STRM_IN_COUNT, &p.streamInCount, true)) RETURN_ASSERT(Parse_XmlError);
838 if (!GetString(port, STRM_OUT_COUNT, &p.streamOutCount, true)) RETURN_ASSERT(Parse_XmlError);
839 if (!GetUsbPort(&priv->nodeData.usbPort, &p)) RETURN_ASSERT(Parse_XmlError);
841 else if (0 == (strcmp(txt, STRM_PORT)))
843 struct StrmPortParameters p;
844 p.list = &priv->objList;
846 if (!GetString(port, CLOCK_CONFIG, &p.clockConfig, true)) RETURN_ASSERT(Parse_XmlError);
847 if (!GetString(port, STRM_ALIGN, &p.dataAlignment, true)) RETURN_ASSERT(Parse_XmlError);
848 if (!GetStrmPort(&priv->nodeData.strmPortA, &p)) RETURN_ASSERT(Parse_XmlError);
850 if (!GetStrmPort(&priv->nodeData.strmPortB, &p)) RETURN_ASSERT(Parse_XmlError);
854 UcsXml_CB_OnError("Unknown Port:'%s'", 1, txt);
855 RETURN_ASSERT(Parse_XmlError);
857 if(!GetElementArray(port, ALL_PORTS, &txt, &port))
861 return Parse_Success;;
864 static ParseResult_t ParseConnection(xmlNode * node, const char *conType, PrivateData_t *priv)
866 assert(NULL != node && NULL != priv);
867 if (NULL == conType) RETURN_ASSERT(Parse_XmlError);
868 if (!GetDataType(conType, &priv->conData.dataType)) RETURN_ASSERT(Parse_XmlError);
869 switch (priv->conData.dataType)
874 if (GetString(node, MUTE_MODE, &txt, false))
876 if (0 == strcmp(txt, MUTE_MODE_NO_MUTING))
877 priv->conData.muteMode = UCS_SYNC_MUTE_MODE_NO_MUTING;
878 else if (0 == strcmp(txt, MUTE_MODE_MUTE_SIGNAL))
879 priv->conData.muteMode = UCS_SYNC_MUTE_MODE_MUTE_SIGNAL;
882 UcsXml_CB_OnError("ParseConnection: MuteMode='%s' not implemented", 1, txt);
883 RETURN_ASSERT(Parse_XmlError);
888 /*Be tolerant, this is an optional feature*/
889 priv->conData.muteMode = UCS_SYNC_MUTE_MODE_NO_MUTING;
896 if (GetUInt16(node, AVP_PACKET_SIZE, &size, false))
901 priv->conData.isocPacketSize = UCS_ISOC_PCKT_SIZE_188;
904 priv->conData.isocPacketSize = UCS_ISOC_PCKT_SIZE_196;
907 priv->conData.isocPacketSize = UCS_ISOC_PCKT_SIZE_206;
910 UcsXml_CB_OnError("ParseConnection: %s='%d' not implemented", 2, AVP_PACKET_SIZE, size);
911 RETURN_ASSERT(Parse_XmlError);
916 /*Be tolerant, this is an optional feature*/
917 priv->conData.isocPacketSize = UCS_ISOC_PCKT_SIZE_188;
922 UcsXml_CB_OnError("ParseConnection: Datatype='%s' not implemented", 1, conType);
923 RETURN_ASSERT(Parse_XmlError);
926 return Parse_Success;
929 static ParseResult_t ParseSocket(xmlNode *soc, bool isSource, MSocketType_t socketType, struct UcsXmlJobList **jobList, PrivateData_t *priv)
931 Ucs_Xrm_ResObject_t **targetSock;
932 assert(NULL != soc && NULL != priv);
933 targetSock = isSource ? &priv->conData.inSocket : &priv->conData.outSocket;
939 struct MostSocketParameters p;
940 /* If there is an combiner stored, add it now into job list (right before MOST socket) */
941 if (priv->conData.combiner)
942 if (!AddJob(jobList, priv->conData.combiner, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
944 p.list = &priv->objList;
945 p.isSource = isSource;
946 p.dataType = priv->conData.dataType;
947 if (!GetUInt16(soc, BANDWIDTH, &p.bandwidth, true)) RETURN_ASSERT(Parse_XmlError);
948 if (!GetString(soc, ROUTE, &priv->conData.routeName, true)) RETURN_ASSERT(Parse_XmlError);
949 if (GetString(soc, ROUTE_IS_ACTIVE, &txt, false))
951 if (0 == strcmp(txt, VALUE_TRUE) || 0 == strcmp(txt, VALUE_1))
952 priv->conData.isDeactivated = false;
953 else if (0 == strcmp(txt, VALUE_FALSE) || 0 == strcmp(txt, VALUE_0))
954 priv->conData.isDeactivated = true;
955 else RETURN_ASSERT(Parse_XmlError);
957 priv->conData.isDeactivated = false;
959 if (!GetUInt16(soc, ROUTE_ID, &priv->conData.routeId, false))
960 priv->conData.routeId = ++priv->autoRouteId;
961 if (priv->conData.syncOffsetNeeded)
963 if (!GetUInt16(soc, OFFSET, &priv->conData.syncOffset, true)) RETURN_ASSERT(Parse_XmlError);
965 if (!GetMostSocket((Ucs_Xrm_MostSocket_t **)targetSock, &p)) RETURN_ASSERT(Parse_XmlError);
966 if (!AddJob(jobList, *targetSock, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
971 struct UsbSocketParameters p;
972 p.list = &priv->objList;
973 p.isSource = isSource;
974 p.dataType = priv->conData.dataType;
975 if (priv->nodeData.usbPort)
977 p.usbPort = priv->nodeData.usbPort;
979 if (!GetUsbPortDefaultCreated(&p.usbPort, &priv->objList))
980 RETURN_ASSERT(Parse_XmlError);
981 priv->nodeData.usbPort = (Ucs_Xrm_UsbPort_t *)p.usbPort;
983 if(!AddJob(jobList, p.usbPort, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
984 if (!GetString(soc, ENDPOINT_ADDRESS, &p.endpointAddress, true)) RETURN_ASSERT(Parse_XmlError);
985 if (!GetString(soc, FRAMES_PER_TRANSACTION, &p.framesPerTrans, true)) RETURN_ASSERT(Parse_XmlError);
986 if (!GetUsbSocket((Ucs_Xrm_UsbSocket_t **)targetSock, &p)) RETURN_ASSERT(Parse_XmlError);
987 if (!AddJob(jobList, *targetSock, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
992 struct MlbSocketParameters p;
993 p.list = &priv->objList;
994 p.isSource = isSource;
995 p.dataType = priv->conData.dataType;
996 if (priv->nodeData.mlbPort)
998 p.mlbPort = priv->nodeData.mlbPort;
1000 if (!GetMlbPortDefaultCreated(&p.mlbPort, &priv->objList))
1001 RETURN_ASSERT(Parse_XmlError);
1002 priv->nodeData.mlbPort = (Ucs_Xrm_MlbPort_t *)p.mlbPort;
1004 if (!AddJob(jobList, p.mlbPort, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
1005 if (!GetUInt16(soc, BANDWIDTH, &p.bandwidth, true)) RETURN_ASSERT(Parse_XmlError);
1006 if (!GetString(soc, CHANNEL_ADDRESS, &p.channelAddress, true)) RETURN_ASSERT(Parse_XmlError);
1007 if (!GetMlbSocket((Ucs_Xrm_MlbSocket_t **)targetSock, &p)) RETURN_ASSERT(Parse_XmlError);
1008 if (!AddJob(jobList, *targetSock, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
1013 struct StrmSocketParameters p;
1014 p.list = &priv->objList;
1015 p.isSource = isSource;
1016 p.dataType = priv->conData.dataType;
1017 p.streamPortA = priv->nodeData.strmPortA;
1018 p.streamPortB = priv->nodeData.strmPortB;
1019 if (!AddJob(jobList, p.streamPortA, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
1020 if (!AddJob(jobList, p.streamPortB, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
1021 if (!GetUInt16(soc, BANDWIDTH, &p.bandwidth, true)) RETURN_ASSERT(Parse_XmlError);
1022 if (!GetString(soc, STRM_PIN, &p.streamPin, true)) RETURN_ASSERT(Parse_XmlError);
1023 if (!GetStrmSocket((Ucs_Xrm_StrmSocket_t **)targetSock, &p)) RETURN_ASSERT(Parse_XmlError);
1024 if (!AddJob(jobList, *targetSock, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
1027 case MSocket_SPLITTER:
1030 struct SplitterParameters p;
1033 UcsXml_CB_OnError("Splitter can not be used as input socket", 0);
1034 RETURN_ASSERT(Parse_XmlError);
1036 p.list = &priv->objList;
1037 if (!GetUInt16(soc, BYTES_PER_FRAME, &p.bytesPerFrame, true)) RETURN_ASSERT(Parse_XmlError);
1038 /* Current input socket will be stored inside splitter
1039 * and splitter will become the new input socket */
1040 if (!(p.inSoc = priv->conData.inSocket)) RETURN_ASSERT(Parse_XmlError);
1041 if (!GetSplitter((Ucs_Xrm_Splitter_t **)&priv->conData.inSocket, &p)) RETURN_ASSERT(Parse_XmlError);
1042 if (!AddJob(jobList, priv->conData.inSocket, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
1043 if (!GetElement(soc->children, MOST_SOCKET, false, &mostSoc, true))
1044 RETURN_ASSERT(Parse_XmlError);
1045 priv->conData.syncOffsetNeeded = true;
1049 struct UcsXmlJobList *jobListCopy = DeepCopyJobList(*jobList, &priv->objList);
1050 if (!ParseSocket(mostSoc, false, MSocket_MOST, &jobListCopy, priv)) RETURN_ASSERT(Parse_XmlError);
1051 if (!GetElement(mostSoc, MOST_SOCKET, false, &mostSoc, false))
1052 return Parse_Success; /* Do not break here, otherwise an additional invalid route will be created */
1056 case MSocket_COMBINER:
1058 struct CombinerParameters p;
1061 UcsXml_CB_OnError("Combiner can not be used as output socket", 0);
1062 RETURN_ASSERT(Parse_XmlError);
1064 p.list = &priv->objList;
1065 if (!GetUInt16(soc, BYTES_PER_FRAME, &p.bytesPerFrame, true)) RETURN_ASSERT(Parse_XmlError);
1066 if (!GetCombiner(&priv->conData.combiner, &p)) RETURN_ASSERT(Parse_XmlError);
1067 priv->conData.syncOffsetNeeded = true;
1068 if (!GetElement(soc->children, MOST_SOCKET, false, &priv->conData.pendingCombinerMostSockets, true))
1069 RETURN_ASSERT(Parse_XmlError);
1073 RETURN_ASSERT(Parse_XmlError);
1075 /*Handle Pending Combiner Tasks*/
1076 if (NULL != priv->conData.outSocket && NULL != priv->conData.combiner &&
1077 NULL != priv->conData.pendingCombinerMostSockets)
1079 xmlNode *tmp = priv->conData.pendingCombinerMostSockets;
1080 priv->conData.pendingCombinerMostSockets = NULL;
1081 /* Current output socket will be stored inside combiner
1082 * and combiner will become the new output socket */
1083 priv->conData.combiner->port_socket_obj_ptr = priv->conData.outSocket;
1084 priv->conData.outSocket = priv->conData.combiner;
1087 struct UcsXmlJobList *jobListCopy = DeepCopyJobList(*jobList, &priv->objList);
1088 if (!ParseSocket(tmp, true, MSocket_MOST, &jobListCopy, priv)) RETURN_ASSERT(Parse_XmlError);
1089 if (!GetElement(tmp, MOST_SOCKET, false, &tmp, false))
1090 return Parse_Success; /* Do not break here, otherwise an additional invalid route will be created */
1093 /*Connect in and out socket once they are created*/
1094 if (priv->conData.inSocket && priv->conData.outSocket)
1098 Ucs_Rm_EndPoint_t *ep;
1099 struct UcsXmlRoute *route;
1100 switch(priv->conData.dataType)
1104 Ucs_Xrm_SyncCon_t *con = MCalloc(&priv->objList, 1, sizeof(Ucs_Xrm_SyncCon_t));
1105 if (NULL == con) RETURN_ASSERT(Parse_MemoryError);
1106 if (!AddJob(jobList, con, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
1107 con->resource_type = UCS_XRM_RC_TYPE_SYNC_CON;
1108 con->socket_in_obj_ptr = priv->conData.inSocket;
1109 con->socket_out_obj_ptr = priv->conData.outSocket;
1110 con->mute_mode = priv->conData.muteMode;
1111 con->offset = priv->conData.syncOffset;
1116 Ucs_Xrm_AvpCon_t *con = MCalloc(&priv->objList, 1, sizeof(Ucs_Xrm_AvpCon_t));
1117 if (NULL == con) RETURN_ASSERT(Parse_MemoryError);
1118 if (!AddJob(jobList, con, &priv->objList)) RETURN_ASSERT(Parse_XmlError);
1119 con->resource_type = UCS_XRM_RC_TYPE_AVP_CON;
1120 con->socket_in_obj_ptr = priv->conData.inSocket;
1121 con->socket_out_obj_ptr = priv->conData.outSocket;
1122 con->isoc_packet_size = priv->conData.isocPacketSize;
1126 UcsXml_CB_OnError("Could not connect sockets, data type not implemented: %d", 1, priv->conData.dataType);
1127 RETURN_ASSERT(Parse_XmlError);
1130 ep = MCalloc(&priv->objList, 1, sizeof(Ucs_Rm_EndPoint_t));
1131 if (NULL == ep) RETURN_ASSERT(Parse_MemoryError);
1133 mostIsInput = (UCS_XRM_RC_TYPE_MOST_SOCKET == *((Ucs_Xrm_ResourceType_t *)priv->conData.inSocket));
1134 mostIsOutput = (UCS_XRM_RC_TYPE_MOST_SOCKET == *((Ucs_Xrm_ResourceType_t *)priv->conData.outSocket));
1135 if (!mostIsInput && !mostIsOutput)
1137 UcsXml_CB_OnError("At least one MOST socket required per connection", 0);
1138 RETURN_ASSERT(Parse_XmlError);
1140 ep->endpoint_type = mostIsOutput ? UCS_RM_EP_SOURCE : UCS_RM_EP_SINK;
1141 ep->jobs_list_ptr = GetJobList(*jobList, &priv->objList);
1142 if(NULL == ep->jobs_list_ptr) RETURN_ASSERT(Parse_MemoryError);
1143 ep->node_obj_ptr = priv->nodeData.nod;
1144 route = MCalloc(&priv->objList, 1, sizeof(struct UcsXmlRoute));
1145 if (NULL == route) RETURN_ASSERT(Parse_MemoryError);
1146 route->isSource = mostIsOutput;
1147 route->isActive = !priv->conData.isDeactivated;
1148 route->routeId = priv->conData.routeId;
1150 assert(NULL != priv->conData.routeName);
1151 strncpy(route->routeName, priv->conData.routeName, sizeof(route->routeName));
1152 AddRoute(&priv->pRtLst, route);
1154 return Parse_Success;
1157 static ParseResult_t ParseScript(xmlNode *scr, PrivateData_t *priv)
1164 struct UcsXmlScript *scrlist;
1165 Ucs_Ns_Script_t *script;
1166 assert(NULL != scr && NULL != priv);
1167 priv->scriptData.pause = 0;
1168 scrlist = priv->pScrLst;
1169 if (!GetCountArray(scr->children, ALL_SCRIPTS, &actCnt, false)) RETURN_ASSERT(Parse_XmlError);
1170 if (NULL == (script = MCalloc(&priv->objList, actCnt, sizeof(Ucs_Ns_Script_t))))
1171 RETURN_ASSERT(Parse_MemoryError);
1173 /*Iterate all actions*/
1174 if (!GetElementArray(scr->children, ALL_SCRIPTS, &txt, &act)) RETURN_ASSERT(Parse_XmlError);
1177 if (0 == strcmp(txt, SCRIPT_MSG_SEND)) {
1178 ParseResult_t result = ParseScriptMsgSend(act, &script[i], priv);
1179 if (Parse_Success != result) return result;
1181 } else if (0 == strcmp(txt, SCRIPT_GPIO_PORT_CREATE)) {
1182 ParseResult_t result = ParseScriptGpioPortCreate(act, &script[i], priv);
1183 if (Parse_Success != result) return result;
1185 } else if (0 == strcmp(txt, SCRIPT_GPIO_PORT_PIN_MODE)) {
1186 ParseResult_t result = ParseScriptGpioPinMode(act, &script[i], priv);
1187 if (Parse_Success != result) return result;
1189 } else if (0 == strcmp(txt, SCRIPT_GPIO_PIN_STATE)) {
1190 ParseResult_t result = ParseScriptGpioPinState(act, &script[i], priv);
1191 if (Parse_Success != result) return result;
1193 } else if (0 == strcmp(txt, SCRIPT_I2C_PORT_CREATE)) {
1194 ParseResult_t result = ParseScriptPortCreate(act, &script[i], priv);
1195 if (Parse_Success != result) return result;
1197 } else if (0 == strcmp(txt, SCRIPT_I2C_PORT_WRITE)) {
1198 ParseResult_t result = ParseScriptPortWrite(act, &script[i], priv);
1199 if (Parse_Success != result) return result;
1201 } else if (0 == strcmp(txt, SCRIPT_I2C_PORT_READ)) {
1202 ParseResult_t result = ParseScriptPortRead(act, &script[i], priv);
1203 if (Parse_Success != result) return result;
1205 } else if (0 == strcmp(txt, SCRIPT_PAUSE)) {
1206 ParseResult_t result = ParseScriptPause(act, &script[i], priv);
1207 if (Parse_Success != result) return result;
1209 UcsXml_CB_OnError("Unknown script action:'%s'", 1, txt);
1210 RETURN_ASSERT(Parse_XmlError);
1212 if (!GetElementArray(act, ALL_SCRIPTS, &txt, &act))
1216 if (!GetString(scr, NAME, &txt, true))
1217 RETURN_ASSERT(Parse_XmlError);
1218 while(NULL != scrlist)
1220 if (0 == strcmp(txt, scrlist->scriptName))
1222 Ucs_Rm_Node_t *node = scrlist->node;
1223 node->script_list_ptr = script;
1224 node->script_list_size = actCnt;
1225 scrlist->inUse = true;
1228 scrlist = scrlist->next;
1232 UcsXml_CB_OnError("Script defined:'%s', which was never referenced", 1, txt);
1233 RETURN_ASSERT(Parse_XmlError);
1235 return Parse_Success;
1238 static bool FillScriptInitialValues(Ucs_Ns_Script_t *scr, PrivateData_t *priv)
1240 assert(NULL != scr && NULL != priv);
1241 scr->send_cmd = MCalloc(&priv->objList, 1, sizeof(Ucs_Ns_ConfigMsg_t));
1242 scr->exp_result = MCalloc(&priv->objList, 1, sizeof(Ucs_Ns_ConfigMsg_t));
1243 assert(scr->send_cmd && scr->exp_result);
1244 if (NULL == scr->send_cmd || NULL == scr->exp_result) return false;
1245 scr->pause = priv->scriptData.pause;
1246 priv->scriptData.pause = 0;
1250 static ParseResult_t ParseScriptMsgSend(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)
1252 Ucs_Ns_ConfigMsg_t *req, *res;
1253 assert(NULL != act && NULL != scr && NULL != priv);
1254 if (!FillScriptInitialValues(scr, priv)) return Parse_MemoryError;
1255 req = scr->send_cmd;
1256 res = scr->exp_result;
1257 req->InstId = res->InstId = 1;
1258 if (!GetUInt8(act, FBLOCK_ID, &req->FBlockId, true))
1259 RETURN_ASSERT(Parse_XmlError);
1261 if (!GetUInt16(act, FUNCTION_ID, &req->FunktId, true))
1262 RETURN_ASSERT(Parse_XmlError);
1264 if (!GetUInt8(act, OP_TYPE_REQUEST, &req->OpCode, true))
1265 RETURN_ASSERT(Parse_XmlError);
1267 res->FBlockId = req->FBlockId;
1268 res->FunktId = req->FunktId;
1270 if (GetUInt8(act, OP_TYPE_RESPONSE, &res->OpCode, false))
1271 GetPayload(act, PAYLOAD_RES_HEX, &res->DataPtr, &res->DataLen, 0, &priv->objList, false);
1273 if (!GetPayload(act, PAYLOAD_REQ_HEX, &req->DataPtr, &req->DataLen, 0, &priv->objList, true))
1274 RETURN_ASSERT(Parse_XmlError);
1275 if (0 == req->DataLen || NULL == req->DataPtr)
1276 RETURN_ASSERT(Parse_XmlError);
1277 return Parse_Success;
1280 static ParseResult_t ParseScriptGpioPortCreate(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)
1283 Ucs_Ns_ConfigMsg_t *req, *res;
1284 assert(NULL != act && NULL != scr && NULL != priv);
1285 if (!FillScriptInitialValues(scr, priv))
1286 RETURN_ASSERT(Parse_MemoryError);
1287 if (!GetUInt16(act, DEBOUNCE_TIME, &debounce, true))
1288 RETURN_ASSERT(Parse_XmlError);
1289 req = scr->send_cmd;
1290 res = scr->exp_result;
1291 req->InstId = res->InstId = 1;
1292 req->FunktId = res->FunktId = 0x701;
1297 req->DataPtr = MCalloc(&priv->objList, req->DataLen, 1);
1298 if (NULL == req->DataPtr) return Parse_MemoryError;
1299 res->DataPtr = MCalloc(&priv->objList, res->DataLen, 1);
1300 if (NULL == res->DataPtr) return Parse_MemoryError;
1301 req->DataPtr[0] = 0; /*GPIO Port instance, always 0*/
1302 req->DataPtr[1] = MISC_HB(debounce);
1303 req->DataPtr[2] = MISC_LB(debounce);
1305 res->DataPtr[0] = 0x1D;
1306 res->DataPtr[1] = 0x00;
1307 return Parse_Success;
1310 static ParseResult_t ParseScriptGpioPinMode(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)
1312 #define PORT_HANDLE_OFFSET (2)
1314 uint8_t payloadLen = 0;
1315 Ucs_Ns_ConfigMsg_t *req, *res;
1316 assert(NULL != act && NULL != scr && NULL != priv);
1317 if (!FillScriptInitialValues(scr, priv))
1318 RETURN_ASSERT(Parse_MemoryError);
1319 req = scr->send_cmd;
1320 res = scr->exp_result;
1321 req->InstId = res->InstId = 1;
1322 req->FunktId = res->FunktId = 0x703;
1325 if (!GetPayload(act, PIN_CONFIG, &payload, &payloadLen,
1326 PORT_HANDLE_OFFSET, /* First two bytes are reserved for port handle */
1327 &priv->objList, true)) RETURN_ASSERT(Parse_XmlError);
1330 req->DataPtr = payload;
1331 res->DataPtr = payload;
1332 req->DataLen = payloadLen + PORT_HANDLE_OFFSET;
1333 res->DataLen = payloadLen + PORT_HANDLE_OFFSET;
1334 return Parse_Success;
1337 static ParseResult_t ParseScriptGpioPinState(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)
1339 uint16_t mask, data;
1340 Ucs_Ns_ConfigMsg_t *req, *res;
1341 assert(NULL != act && NULL != scr && NULL != priv);
1342 if (!FillScriptInitialValues(scr, priv))
1343 RETURN_ASSERT(Parse_MemoryError);
1344 if (!GetUInt16(act, PIN_MASK, &mask, true))
1345 RETURN_ASSERT(Parse_XmlError);
1346 if (!GetUInt16(act, PIN_DATA, &data, true))
1347 RETURN_ASSERT(Parse_XmlError);
1348 req = scr->send_cmd;
1349 res = scr->exp_result;
1350 req->InstId = res->InstId = 1;
1351 req->FunktId = res->FunktId = 0x704;
1356 req->DataPtr = MCalloc(&priv->objList, req->DataLen, 1);
1357 if (NULL == req->DataPtr) return Parse_MemoryError;
1358 res->DataPtr = MCalloc(&priv->objList, res->DataLen, 1);
1359 if (NULL == res->DataPtr) return Parse_MemoryError;
1360 req->DataPtr[0] = 0x1D;
1361 req->DataPtr[1] = 0x00;
1362 req->DataPtr[2] = MISC_HB(mask);
1363 req->DataPtr[3] = MISC_LB(mask);
1364 req->DataPtr[4] = MISC_HB(data);
1365 req->DataPtr[5] = MISC_LB(data);
1366 memcpy(res->DataPtr, req->DataPtr, req->DataLen);
1367 res->DataPtr[6] = 0x00;
1368 res->DataPtr[7] = 0x00;
1369 return Parse_Success;
1372 static ParseResult_t ParseScriptPortCreate(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)
1376 Ucs_Ns_ConfigMsg_t *req, *res;
1377 assert(NULL != act && NULL != scr && NULL != priv);
1378 if (!FillScriptInitialValues(scr, priv))
1379 RETURN_ASSERT(Parse_MemoryError);
1380 if (!GetString(act, I2C_SPEED, &txt, true))
1381 RETURN_ASSERT(Parse_XmlError);
1382 if (0 == strcmp(txt, I2C_SPEED_SLOW))
1384 else if (0 == strcmp(txt, I2C_SPEED_FAST))
1388 UcsXml_CB_OnError("Invalid I2C speed:'%s'", 1, txt);
1389 RETURN_ASSERT(Parse_XmlError);
1391 req = scr->send_cmd;
1392 res = scr->exp_result;
1393 req->InstId = res->InstId = 1;
1394 req->FunktId = res->FunktId = 0x6C1;
1399 req->DataPtr = MCalloc(&priv->objList, req->DataLen, 1);
1400 if (NULL == req->DataPtr) return Parse_MemoryError;
1401 res->DataPtr = MCalloc(&priv->objList, res->DataLen, 1);
1402 if (NULL == res->DataPtr) return Parse_MemoryError;
1403 req->DataPtr[0] = 0x00; /* I2C Port Instance always 0 */
1404 req->DataPtr[1] = 0x00; /* I2C slave address, always 0, because we are Master */
1405 req->DataPtr[2] = 0x01; /* We are Master */
1406 req->DataPtr[3] = speed;
1408 res->DataPtr[0] = 0x0F;
1409 res->DataPtr[1] = 0x00;
1410 return Parse_Success;
1413 static ParseResult_t ParseScriptPortWrite(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)
1415 #define HEADER_OFFSET 8
1417 uint8_t mode, blockCount, address, length, payloadLength;
1420 Ucs_Ns_ConfigMsg_t *req, *res;
1421 assert(NULL != act && NULL != scr && NULL != priv);
1422 if (GetString(act, I2C_WRITE_MODE, &txt, false))
1424 if (0 == strcmp(txt, I2C_WRITE_MODE_DEFAULT))
1426 else if (0 == strcmp(txt, I2C_WRITE_MODE_REPEAT))
1428 else if (0 == strcmp(txt, I2C_WRITE_MODE_BURST))
1432 UcsXml_CB_OnError("Invalid I2C mode:'%s'", 1, txt);
1433 RETURN_ASSERT(Parse_XmlError);
1438 if (!GetUInt8(act, I2C_WRITE_BLOCK_COUNT, &blockCount, false))
1440 if (!GetUInt8(act, I2C_SLAVE_ADDRESS, &address, true))
1441 RETURN_ASSERT(Parse_XmlError);
1442 if (!GetUInt8(act, I2C_PAYLOAD_LENGTH, &length, false))
1444 if (!GetUInt16(act, I2C_TIMEOUT, &timeout, false))
1446 if (!GetPayload(act, I2C_PAYLOAD, &payload, &payloadLength, HEADER_OFFSET, &priv->objList, true))
1447 RETURN_ASSERT(Parse_XmlError);
1449 length = payloadLength;
1450 if (!FillScriptInitialValues(scr, priv))
1451 RETURN_ASSERT(Parse_MemoryError);
1452 req = scr->send_cmd;
1453 res = scr->exp_result;
1454 req->InstId = res->InstId = 1;
1455 req->FunktId = res->FunktId = 0x6C4;
1458 req->DataLen = payloadLength + HEADER_OFFSET;
1460 req->DataPtr = payload;
1461 res->DataPtr = MCalloc(&priv->objList, res->DataLen, 1);
1462 if (NULL == res->DataPtr) return Parse_MemoryError;
1464 req->DataPtr[0] = 0x0F;
1465 req->DataPtr[1] = 0x00;
1466 req->DataPtr[2] = mode;
1467 req->DataPtr[3] = blockCount;
1468 req->DataPtr[4] = address;
1469 req->DataPtr[5] = length;
1470 req->DataPtr[6] = MISC_HB(timeout);
1471 req->DataPtr[7] = MISC_LB(timeout);
1473 res->DataPtr[0] = 0x0F;
1474 res->DataPtr[1] = 0x00;
1475 res->DataPtr[2] = address;
1477 res->DataPtr[3] = blockCount * length;
1479 res->DataPtr[3] = length;
1480 return Parse_Success;
1483 static ParseResult_t ParseScriptPortRead(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)
1485 uint8_t address, length;
1487 Ucs_Ns_ConfigMsg_t *req, *res;
1488 assert(NULL != act && NULL != scr && NULL != priv);
1489 if (!GetUInt8(act, I2C_SLAVE_ADDRESS, &address, true))
1490 RETURN_ASSERT(Parse_XmlError);
1491 if (!GetUInt8(act, I2C_PAYLOAD_LENGTH, &length, true))
1492 RETURN_ASSERT(Parse_XmlError);
1493 if (!GetUInt16(act, I2C_TIMEOUT, &timeout, false))
1495 if (!FillScriptInitialValues(scr, priv))
1496 RETURN_ASSERT(Parse_MemoryError);
1497 req = scr->send_cmd;
1498 res = scr->exp_result;
1499 req->InstId = res->InstId = 1;
1500 req->FunktId = res->FunktId = 0x6C3;
1505 req->DataPtr = MCalloc(&priv->objList, req->DataLen, 1);
1506 if (NULL == req->DataPtr) return Parse_MemoryError;
1507 res->DataPtr = MCalloc(&priv->objList, res->DataLen, 1);
1508 if (NULL == res->DataPtr) return Parse_MemoryError;
1510 req->DataPtr[0] = 0x0F;
1511 req->DataPtr[1] = 0x00;
1512 req->DataPtr[2] = address;
1513 req->DataPtr[3] = length;
1514 req->DataPtr[4] = MISC_HB(timeout);
1515 req->DataPtr[5] = MISC_LB(timeout);
1517 res->DataPtr[0] = 0x0F;
1518 res->DataPtr[1] = 0x00;
1519 res->DataPtr[2] = address;
1520 res->DataPtr[3] = length;
1521 return Parse_Success;
1524 static ParseResult_t ParseScriptPause(xmlNode *act, Ucs_Ns_Script_t *scr, PrivateData_t *priv)
1526 assert(NULL != act && NULL != priv);
1527 if (!GetUInt16(act, PAUSE_MS, &priv->scriptData.pause, true))
1528 RETURN_ASSERT(Parse_XmlError);
1529 return Parse_Success;
1532 static ParseResult_t ParseRoutes(UcsXmlVal_t *ucs, PrivateData_t *priv)
1534 uint16_t routeAmount = 0;
1535 struct UcsXmlRoute *sourceRoute;
1536 assert(NULL != ucs && NULL != priv);
1537 /*First: Count the amount of routes and allocate the correct amount*/
1538 sourceRoute = priv->pRtLst;
1539 while (NULL != sourceRoute)
1541 if (sourceRoute->isSource)
1543 struct UcsXmlRoute *sinkRoute = priv->pRtLst;
1544 while (NULL != sinkRoute)
1546 if (sourceRoute != sinkRoute
1547 && !sinkRoute->isSource
1548 && (0 == strncmp(sourceRoute->routeName, sinkRoute->routeName, sizeof(sourceRoute->routeName))))
1552 sinkRoute = sinkRoute->next;
1555 sourceRoute = sourceRoute->next;
1557 if (0 == routeAmount)
1558 return Parse_Success; /*Its okay to have no routes at all (e.g. MEP traffic only)*/
1559 ucs->pRoutes = MCalloc(&priv->objList, routeAmount, sizeof(Ucs_Rm_Route_t));
1560 if (NULL == ucs->pRoutes) RETURN_ASSERT(Parse_MemoryError);
1562 /*Second: Fill allocated structure now*/
1563 sourceRoute = priv->pRtLst;
1564 while (NULL != sourceRoute)
1566 if (sourceRoute->isSource)
1568 struct UcsXmlRoute *sinkRoute = priv->pRtLst;
1569 while (NULL != sinkRoute)
1571 if (sourceRoute != sinkRoute
1572 && !sinkRoute->isSource
1573 && (0 == strncmp(sourceRoute->routeName, sinkRoute->routeName, sizeof(sourceRoute->routeName))))
1575 Ucs_Rm_Route_t *route;
1576 if(ucs->routesSize >= routeAmount)
1578 RETURN_ASSERT(Parse_MemoryError);
1580 route = &ucs->pRoutes[ucs->routesSize++];
1581 route->source_endpoint_ptr = sourceRoute->ep;
1582 route->sink_endpoint_ptr = sinkRoute->ep;
1583 if (!IsAutoRouteId(sourceRoute->routeId, priv))
1585 route->active = sourceRoute->isActive;
1586 route->route_id = sourceRoute->routeId;
1590 route->active = sinkRoute->isActive;
1591 route->route_id = sinkRoute->routeId;
1594 sinkRoute = sinkRoute->next;
1597 sourceRoute = sourceRoute->next;
1601 /* Third perform checks when running in debug mode*/
1603 Ucs_Xrm_ResourceType_t *job;
1605 for (i = 0; i < routeAmount; i++)
1607 Ucs_Rm_Route_t *route = &ucs->pRoutes[i];
1608 assert(NULL != route->source_endpoint_ptr);
1609 assert(NULL != route->sink_endpoint_ptr);
1610 assert(NULL != route->source_endpoint_ptr->jobs_list_ptr);
1611 assert(UCS_RM_EP_SOURCE == route->source_endpoint_ptr->endpoint_type);
1612 assert(UCS_RM_EP_SINK == route->sink_endpoint_ptr->endpoint_type);
1613 assert(NULL != route->source_endpoint_ptr->node_obj_ptr);
1614 assert(NULL != route->sink_endpoint_ptr->node_obj_ptr);
1615 assert(NULL != route->source_endpoint_ptr->node_obj_ptr->signature_ptr);
1616 assert(NULL != route->sink_endpoint_ptr->node_obj_ptr->signature_ptr);
1618 while((job = ((Ucs_Xrm_ResourceType_t *)route->source_endpoint_ptr->jobs_list_ptr[j])))
1620 assert(UCS_XRM_RC_TYPE_QOS_CON >= *job);
1624 while((job = ((Ucs_Xrm_ResourceType_t *)route->sink_endpoint_ptr->jobs_list_ptr[j])))
1626 assert(UCS_XRM_RC_TYPE_QOS_CON >= *job);
1632 return Parse_Success;
1635 static bool IsAutoRouteId(uint16_t id, PrivateData_t *priv)
1637 assert(NULL != priv);
1638 return (id >= ROUTE_AUTO_ID_START && id <= priv->autoRouteId);