4 * Copyright (C) 2017 Microchip Technology Germany II GmbH & Co. KG
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 * You may also obtain this software under a propriety license from Microchip.
20 * Please contact Microchip for further information.
28 /************************************************************************/
29 /* USER ADJUSTABLE CONSTANTS */
30 /************************************************************************/
32 #define MAX_JOB_LIST_LEN 6
34 /************************************************************************/
35 /* PRIVATE DECLARATIONS */
36 /************************************************************************/
38 #define COMPILETIME_CHECK(cond) (void)sizeof(int[!!(cond) - 1])
40 struct UcsXmlObjectList
43 struct UcsXmlObjectList *next;
46 struct UcsXmlRouteInfo
50 Ucs_Rm_EndPoint_t *ep;
51 struct UcsXmlRouteInfo *next;
54 struct UcsXmlScriptInfo
58 struct UcsXmlScriptInfo *next;
63 SYNC_DATA = 0, /*!< \brief Specifies the synchronous streaming data type */
64 CONTROL_DATA = 2, /*!< \brief Specifies the control data type */
65 AV_PACKETIZED = 3, /*!< \brief Specifies the A/V Packetized Isochronous
66 streaming data type */
67 QOS_IP = 4, /*!< \brief Specifies the Quality of Service IP
69 DISC_FRAME_PHASE = 5, /*!< \brief Specifies the DiscreteFrame Isochronous
70 streaming phase data type */
71 IPC_PACKET = 7, /*!< \brief Specifies the IPC packet data type */
72 INVALID = 0xFF /*!< \brief Defined invalid value */
92 struct UcsXmlObjectList objList;
93 struct UcsXmlRouteInfo *pRtLst;
94 struct UcsXmlScriptInfo *pScrLst;
96 Ucs_Xrm_ResObject_t *inSocket;
97 Ucs_Xrm_ResObject_t *outSocket;
98 Ucs_Xrm_ResObject_t **jobList;
105 /************************************************************************/
107 /************************************************************************/
110 static const char* UNICENS = "unicens";
111 static const char* ASYNC_BANDWIDTH = "async_bandwidth";
112 static const char* CHANNEL = "channel";
113 static const char* CHANNEL_NAME = "channel_name";
114 static const char* ADDRESS = "channel_addr";
115 static const char* BANDWIDTH = "bandwidth";
116 static const char* OFFSET = "offset";
117 static const char* DATA_TYPE = "data_type";
118 static const char* DEVICE = "device";
119 static const char* DEVICE_MLB_SPEED = "mlb_port_speed";
120 static const char* NODE_ADDR = "node_address";
121 static const char* DIR = "dir";
122 static const char* I2S_PIN = "i2s_pin";
123 static const char* PACKETS_XACT = "packets_per_xact";
124 static const char* PORT = "port";
125 static const char* SOCKET = "socket";
127 static const char* I2S_FS_SPEED = "i2s_fs_speed";
128 static const char* I2S_ALIGN = "i2s_align";
131 static const char* PORT_MOST = "MOST";
132 static const char* PORT_USB = "USB";
133 static const char* PORT_MLB = "MLB";
134 static const char* PORT_I2S = "I2S";
136 static const char* DATATYPE_SYNC = "SYNC";
137 static const char* DATATYPE_AVP = "AVP";
138 static const char* DATATYPE_CTRL = "CTRL";
139 static const char* DATATYPE_QOS = "QOS";
140 static const char* DATATYPE_DFP = "DFP";
141 static const char* DATATYPE_IPC = "IPC";
143 static const char* DIR_IN = "IN";
144 static const char* DIR_OUT = "OUT";
146 static const char* I2S_PIN_SRXA0 = "SRXA0";
147 static const char* I2S_PIN_SRXA1 = "SRXA1";
148 static const char* I2S_PIN_SRXB0 = "SRXB0";
149 static const char* I2S_PIN_SRXB1 = "SRXB1";
151 static const char* I2S_ALIGN_L16 = "Left16";
152 static const char* I2S_ALIGN_L24 = "Left24";
153 static const char* I2S_ALIGN_R16 = "Right16";
154 static const char* I2S_ALIGN_R24 = "Right24";
155 static const char* I2S_ALIGN_SEQUENTIAL = "Seq";
157 static const char* SCRIPT = "script";
158 static const char* ACTION = "action";
159 static const char* NAME = "name";
160 static const char* TYPE = "type";
161 static const char* FBLOCK_ID = "fblock_id";
162 static const char* FUNCTION_ID = "function_id";
163 static const char* OP_TYPE_REQUEST = "op_request";
164 static const char* OP_TYPE_RESPONSE = "op_response";
165 static const char* PAYLOAD_REQ_HEX = "load_req_hex";
166 static const char* PAYLOAD_RES_HEX = "load_res_hex";
167 static const char* PAUSE_MS = "pause_ms";
169 static const char* SEND_MSG = "SEND_MSG";
170 static const char* PAUSE = "PAUSE";
172 /************************************************************************/
173 /* Private Function Prototypes */
174 /************************************************************************/
176 static void *MCalloc(struct UcsXmlObjectList *list, uint32_t nElem, uint32_t elemSize);
177 static void FreeObjList(struct UcsXmlObjectList *cur);
178 static void FreeVal(UcsXmlVal_t *v);
179 static bool GetElement(mxml_node_t *element, const char *name, bool goDeep, mxml_node_t **out, bool mandatory);
180 static bool GetCount(mxml_node_t *element, const char *name, uint32_t *out, bool mandatory);
181 static bool GetString(mxml_node_t *element, const char *key, const char **out, bool mandatory);
182 static bool GetUInt16(mxml_node_t *element, const char *key, uint16_t *out, bool mandatory);
183 static bool GetUInt8(mxml_node_t *element, const char *key, uint8_t *out, bool mandatory);
184 static bool GetMlbSpeed(mxml_node_t *element, const char *key, Ucs_Mlb_ClockConfig_t *clock, bool mandatory);
185 static bool GetI2SSpeed(mxml_node_t *element, const char *key, Ucs_Stream_PortClockConfig_t *clock, bool mandatory);
186 static bool GetI2SPin(mxml_node_t *element, Ucs_Stream_PortPinId_t *pin, uint8_t *portIndex, bool mandatory);
187 static bool GetI2SAlignment(mxml_node_t *element, Ucs_Stream_PortDataAlign_t *align, bool mandatory);
188 static bool GetDirection(mxml_node_t *element, Ucs_SocketDirection_t *out);
189 static bool GetDataType(mxml_node_t *element, MData_t *out);
190 static bool GetPort(mxml_node_t *element, MPort_t *out);
191 static bool GetPayload(mxml_node_t *element, const char *name, uint8_t **pPayload, uint8_t *len,
192 struct UcsXmlObjectList *obj, bool mandatory);
193 static bool AddJob(Ucs_Xrm_ResObject_t **joblist, Ucs_Xrm_ResObject_t *job);
194 static void AddRoute(struct UcsXmlRouteInfo **pRtLst, struct UcsXmlRouteInfo *route);
195 static void AddScript(struct UcsXmlScriptInfo **pScrLst, struct UcsXmlScriptInfo *script);
196 static ParseResult_t ParseAll(mxml_node_t *tree, UcsXmlVal_t *v, PrivateData_t *vp);
197 static ParseResult_t ParseDevice(mxml_node_t * dev, PrivateData_t *vp);
198 static ParseResult_t ParseChannel(mxml_node_t * ch, PrivateData_t *vp);
199 static ParseResult_t ParseSocket(mxml_node_t *soc, PrivateData_t *vp);
200 static ParseResult_t ParseMostSoc(Ucs_Xrm_MostSocket_t *mostSoc, mxml_node_t *soc, PrivateData_t *vp);
201 static ParseResult_t ParseUsbSoc(Ucs_Xrm_UsbSocket_t *usbSoc, mxml_node_t *soc, PrivateData_t *vp);
202 static ParseResult_t ParseMlbSoc(Ucs_Xrm_MlbSocket_t *mlbSoc, mxml_node_t *soc, PrivateData_t *vp);
203 static ParseResult_t ParseStreamSoc(Ucs_Xrm_StrmSocket_t *strmSoc, mxml_node_t *soc, PrivateData_t *vp);
204 static ParseResult_t ParseScript(mxml_node_t *scr, PrivateData_t *vp);
205 static ParseResult_t ParseScriptAction(mxml_node_t *act, Ucs_Rm_Node_t *n, uint32_t index, PrivateData_t *vp);
206 static ParseResult_t ParseRoutes(UcsXmlVal_t *v, PrivateData_t *vp);
208 /************************************************************************/
209 /* Public Functions */
210 /************************************************************************/
212 UcsXmlVal_t *UcsXml_Parse(const char *xmlString)
214 UcsXmlVal_t *v = NULL;
215 ParseResult_t result = Parse_Success;
216 mxml_node_t *tree = mxmlLoadString(NULL, xmlString, MXML_NO_CALLBACK);
219 result = Parse_XmlError;
221 if (Parse_Success == result)
223 if (!GetElement(tree, UNICENS, true, &tree, true))
224 result = Parse_XmlError;
226 if (Parse_Success == result)
228 //Do not use MCalloc for the root element
229 v = calloc(1, sizeof(UcsXmlVal_t));
230 if (NULL == v) result = Parse_MemoryError;
232 if (Parse_Success == result)
234 //Do not use MCalloc for the private data
235 v->pInternal = calloc(1, sizeof(PrivateData_t));
236 if (NULL == v->pInternal) result = Parse_MemoryError;
238 if (Parse_Success == result)
240 result = ParseAll(tree, v, v->pInternal);
246 if (Parse_Success == result)
250 if (Parse_MemoryError == result)
252 UcsXml_CB_OnError("XML error, aborting..", 0);
256 UcsXml_CB_OnError("Alloc error, aborting..", 0);
263 void UcsXml_FreeVal(UcsXmlVal_t *val)
268 /************************************************************************/
269 /* Private Function Implementations */
270 /************************************************************************/
272 static void *MCalloc(struct UcsXmlObjectList *list, uint32_t nElem, uint32_t elemSize)
275 struct UcsXmlObjectList *tail = list;
276 if (NULL == list || 0 == nElem || 0 == elemSize) return NULL;
278 obj = calloc(nElem, elemSize);
284 if (NULL == list->obj)
289 while(tail->next) tail = tail->next;
290 tail->next = calloc(1, sizeof(struct UcsXmlObjectList));
291 if (NULL == tail->next)
297 tail->next->obj = obj;
301 static void FreeObjList(struct UcsXmlObjectList *cur)
303 struct UcsXmlObjectList *root = cur;
306 struct UcsXmlObjectList *next = cur->next;
307 assert(NULL != cur->obj);
316 static void FreeVal(UcsXmlVal_t *v)
319 if (NULL == v || NULL == v->pInternal)
322 FreeObjList(&vp->objList);
327 static bool GetElement(mxml_node_t *element, const char *name, bool goDeep, mxml_node_t **out, bool mandatory)
329 mxml_node_t *n = element;
330 if (NULL == n || NULL == name || NULL == out) return false;
333 *out = mxmlFindElement(n, n, name, NULL, NULL, MXML_DESCEND);
334 return (NULL != *out);
336 while ((n = n->next))
338 if (MXML_ELEMENT != n->type)
340 if (0 == strcmp(name, n->value.opaque))
347 UcsXml_CB_OnError("Can not find tag <%s>", 1, name);
351 static bool GetCount(mxml_node_t *element, const char *name, uint32_t *out, bool mandatory)
355 if (NULL == element || NULL == name) return false;
356 if(!GetElement(element, name, true, &n, false))
361 if(!GetElement(n, name, false, &n, false))
364 if (mandatory && 0 == cnt)
366 UcsXml_CB_OnError("element count of <%s> is zero", 1, name);
373 static bool GetString(mxml_node_t *element, const char *key, const char **out, bool mandatory)
376 if (NULL == element || NULL == key) return false;
377 for (i = 0; i < element->value.element.num_attrs; i++)
379 mxml_attr_t *attr = &element->value.element.attrs[i];
380 if (0 == strcmp(key, attr->name))
387 UcsXml_CB_OnError("Can not find attribute='%s' from element <%s>",
388 2, key, element->value.element.name);
392 static bool GetUInt16(mxml_node_t *element, const char *key, uint16_t *out, bool mandatory)
395 if (!GetString(element, key, &txt, mandatory)) return false;
396 *out = strtol( txt, NULL, 0 );
400 static bool GetUInt8(mxml_node_t *element, const char *key, uint8_t *out, bool mandatory)
403 if (!GetString(element, key, &txt, mandatory)) return false;
404 *out = strtol( txt, NULL, 0 );
408 static bool GetMlbSpeed(mxml_node_t *element, const char *key, Ucs_Mlb_ClockConfig_t *clock, bool mandatory)
411 if (!GetUInt16(element, DEVICE_MLB_SPEED, &speed, false))
415 case 256: *clock = UCS_MLB_CLK_CFG_256_FS; break;
416 case 512: *clock = UCS_MLB_CLK_CFG_512_FS; break;
417 case 1024: *clock = UCS_MLB_CLK_CFG_1024_FS; break;
418 case 2048: *clock = UCS_MLB_CLK_CFG_2048_FS; break;
419 case 3072: *clock = UCS_MLB_CLK_CFG_3072_FS; break;
420 case 4096: *clock = UCS_MLB_CLK_CFG_4096_FS; break;
421 case 6144: *clock = UCS_MLB_CLK_CFG_6144_FS; break;
422 case 8192: *clock = UCS_MLB_CLK_CFG_8192_FS; break;
423 case 0: *clock = UCS_MLB_CLK_CFG_WILDCARD; break;
425 UcsXml_CB_OnError("Invalid MLB clock val:'%d'", 1, clock);
431 static bool GetI2SSpeed(mxml_node_t *element, const char *key, Ucs_Stream_PortClockConfig_t *clock, bool mandatory)
434 if (!GetUInt16(element, I2S_FS_SPEED, &speed, false))
438 case 8: *clock = UCS_STREAM_PORT_CLK_CFG_8FS; break;
439 case 16: *clock = UCS_STREAM_PORT_CLK_CFG_16FS; break;
440 case 32: *clock = UCS_STREAM_PORT_CLK_CFG_32FS; break;
441 case 64: *clock = UCS_STREAM_PORT_CLK_CFG_64FS; break;
442 case 128: *clock = UCS_STREAM_PORT_CLK_CFG_128FS; break;
443 case 256: *clock = UCS_STREAM_PORT_CLK_CFG_256FS; break;
444 case 512: *clock = UCS_STREAM_PORT_CLK_CFG_512FS; break;
445 case 0: *clock = UCS_MLB_CLK_CFG_WILDCARD; break;
447 UcsXml_CB_OnError("Invalid I2S clock val:'%d'", 1, clock);
453 static bool GetI2SPin(mxml_node_t *element, Ucs_Stream_PortPinId_t *pin, uint8_t *portIndex, bool mandatory)
456 if (!GetString(element, I2S_PIN, &txt, true))
458 if (0 == strcmp(I2S_PIN_SRXA0, txt))
460 *pin = UCS_STREAM_PORT_PIN_ID_SRXA0;
464 else if (0 == strcmp(I2S_PIN_SRXA1, txt))
466 *pin = UCS_STREAM_PORT_PIN_ID_SRXA1;
470 else if (0 == strcmp(I2S_PIN_SRXB0, txt))
472 *pin = UCS_STREAM_PORT_PIN_ID_SRXB0;
476 else if (0 == strcmp(I2S_PIN_SRXB1, txt))
478 *pin = UCS_STREAM_PORT_PIN_ID_SRXB1;
482 UcsXml_CB_OnError("Invalid I2S pin val:'%s'", 1, txt);
486 static bool GetI2SAlignment(mxml_node_t *element, Ucs_Stream_PortDataAlign_t *align, bool mandatory)
489 if (!GetString(element, I2S_ALIGN, &txt, true))
491 if (0 == strcmp(I2S_ALIGN_L16, txt))
492 *align = UCS_STREAM_PORT_ALGN_LEFT16BIT;
493 else if (0 == strcmp(I2S_ALIGN_L24, txt))
494 *align = UCS_STREAM_PORT_ALGN_LEFT24BIT;
495 else if (0 == strcmp(I2S_ALIGN_R16, txt))
496 *align = UCS_STREAM_PORT_ALGN_RIGHT16BIT;
497 else if (0 == strcmp(I2S_ALIGN_R24, txt))
498 *align = UCS_STREAM_PORT_ALGN_RIGHT24BIT;
499 else if (0 == strcmp(I2S_ALIGN_SEQUENTIAL, txt))
500 *align = UCS_STREAM_PORT_ALGN_SEQ;
503 UcsXml_CB_OnError("Invalid I2S alignment:'%s'", 1, txt);
509 static bool GetDirection(mxml_node_t *element, Ucs_SocketDirection_t *out)
512 if (!GetString(element, DIR, &txt, true)) return false;
513 if (0 == strcmp(DIR_IN, txt))
514 *out = UCS_SOCKET_DIR_INPUT;
515 else if (0 == strcmp(DIR_OUT, txt))
516 *out = UCS_SOCKET_DIR_OUTPUT;
522 static bool GetDataType(mxml_node_t *element, MData_t *out)
525 if (!GetString(element, DATA_TYPE, &txt, true)) return false;
526 if (0 == strcmp(DATATYPE_SYNC, txt)) {
528 } else if (0 == strcmp(DATATYPE_CTRL, txt)) {
530 } else if (0 == strcmp(DATATYPE_AVP, txt)) {
531 *out = AV_PACKETIZED;
532 } else if (0 == strcmp(DATATYPE_QOS, txt)) {
534 } else if (0 == strcmp(DATATYPE_DFP, txt)) {
535 *out = DISC_FRAME_PHASE;
536 } else if (0 == strcmp(DATATYPE_IPC, txt)) {
539 UcsXml_CB_OnError("Unknown data type : '%s'", 1, txt);
545 static bool GetPort(mxml_node_t *element, MPort_t *out)
548 if (!GetString(element, PORT, &txt, true)) return false;
549 if (0 == strcmp(txt, PORT_MOST)) {
551 } else if (0 == strcmp(txt, PORT_USB)) {
553 } else if (0 == strcmp(txt, PORT_MLB)) {
555 } else if (0 == strcmp(txt, PORT_I2S)) {
558 UcsXml_CB_OnError("Unknown port : '%s'", 1, txt);
564 static bool GetPayload(mxml_node_t *element, const char *name, uint8_t **pPayload, uint8_t *outLen, struct UcsXmlObjectList *obj, bool mandatory)
566 uint32_t tempLen, len = 0;
572 if (!GetString(element, name, &txt, mandatory))
574 tempLen = strlen(txt) + 1;
575 txtCopy = malloc(tempLen);
578 strncpy(txtCopy, txt, tempLen);
579 tempLen = tempLen / 3; /* 2 chars hex value plus space (AA ) */
580 p = MCalloc(obj, tempLen, 1);
587 token = strtok_r( txtCopy, " ,.-", &tkPtr );
588 while( NULL != token )
592 UcsXml_CB_OnError("Script payload values must be stuffed to two characters", 0);
597 p[len++] = strtol( token, NULL, 16 );
598 token = strtok_r( NULL, " ,.-", &tkPtr );
604 static bool AddJob(Ucs_Xrm_ResObject_t **joblist, Ucs_Xrm_ResObject_t *job)
607 if (NULL == joblist || NULL == job)
612 for (i = 0; i < MAX_JOB_LIST_LEN; i++)
614 if (NULL == joblist[i])
624 static void AddRoute(struct UcsXmlRouteInfo **pRtLst, struct UcsXmlRouteInfo *route)
626 struct UcsXmlRouteInfo *tail;
627 if (NULL == pRtLst || NULL == route) return;
628 if (NULL == pRtLst[0])
634 while(tail->next) tail = tail->next;
638 static void AddScript(struct UcsXmlScriptInfo **pScrLst, struct UcsXmlScriptInfo *script)
640 struct UcsXmlScriptInfo *tail;
641 if (NULL == pScrLst || NULL == script) return;
642 if (NULL == pScrLst[0])
648 while(tail->next) tail = tail->next;
652 static ParseResult_t ParseAll(mxml_node_t *tree, UcsXmlVal_t *v, PrivateData_t *vp)
656 ParseResult_t result;
657 if (!GetCount(tree, DEVICE, &devCount, true))
658 return Parse_XmlError;
660 v->pNod = MCalloc(&vp->objList, devCount, sizeof(Ucs_Rm_Node_t));
661 if (NULL == v->pNod) return Parse_MemoryError;
663 if (!GetUInt16(tree, ASYNC_BANDWIDTH, &v->packetBw, true))
664 return Parse_XmlError;
666 ///Iterate all devices
667 if (!GetElement(tree, DEVICE, true, &sub, true))
668 return Parse_XmlError;
672 vp->nod = &v->pNod[v->nodSize];
673 if (Parse_Success != (result = ParseDevice(sub, vp)))
675 ///Iterate all channels. Device without any channel is also valid.
676 if (GetElement(sub->child, CHANNEL, false, &ch, false))
682 if (Parse_Success != (result = ParseChannel(ch, vp)))
684 ///Iterate all sockets
685 if(!GetElement(ch->child, SOCKET, false, &soc, true))
686 return Parse_XmlError;
689 ParseResult_t result;
690 if (Parse_Success != (result = ParseSocket(soc, vp)))
693 if (!GetElement(soc, SOCKET, false, &soc, false))
698 UcsXml_CB_OnError("%d sockets per channel found, must be 2", 1, sockCnt);
699 return Parse_XmlError;
701 if (!GetElement(ch, CHANNEL, false, &ch, false))
706 if (!GetElement(sub, DEVICE, false, &sub, false))
710 ///Fill route structures
711 result = ParseRoutes(v, vp);
712 if (Parse_MemoryError == result) return Parse_MemoryError;
713 else if (Parse_XmlError == result) return Parse_XmlError;
715 ///Iterate all scripts. No scripts at all is allowed
716 if(GetElement(tree, SCRIPT, true, &sub, false))
720 ParseResult_t result = ParseScript(sub, vp);
721 if (Parse_MemoryError == result) return Parse_MemoryError;
722 else if (Parse_XmlError == result) return Parse_XmlError;
723 if(!GetElement(sub, SCRIPT, false, &sub, false))
730 static ParseResult_t ParseDevice(mxml_node_t * dev, PrivateData_t *vp)
733 assert(NULL != dev && NULL != vp);
734 vp->nod->signature_ptr = MCalloc(&vp->objList, 1, sizeof(Ucs_Signature_t));
735 if(NULL == vp->nod->signature_ptr) return Parse_MemoryError;
736 if (!GetUInt16(dev, NODE_ADDR, &vp->nod->signature_ptr->node_address, true))
737 return Parse_XmlError;
738 if (GetString(dev, SCRIPT, &txt, false))
740 struct UcsXmlScriptInfo *scr = MCalloc(&vp->objList, 1, sizeof(struct UcsXmlScriptInfo));
741 if (NULL == scr) return Parse_MemoryError;
743 strncpy(scr->scriptName, txt, sizeof(scr->scriptName));
744 AddScript(&vp->pScrLst, scr);
746 return Parse_Success;;
749 static ParseResult_t ParseChannel(mxml_node_t *ch, PrivateData_t *vp)
752 vp->outSocket = NULL;
757 assert(NULL != ch && NULL != vp);
758 if (!GetString(ch, CHANNEL_NAME, &vp->chName, true))
759 return Parse_XmlError;
760 if (!GetDataType(ch, &vp->dataType))
761 return Parse_XmlError;
762 if (!GetUInt16(ch, BANDWIDTH, &vp->blockWidth, true))
763 return Parse_XmlError;
764 vp->jobList = MCalloc(&vp->objList, MAX_JOB_LIST_LEN, sizeof(Ucs_Xrm_ResObject_t *));
765 if (NULL == vp->jobList) return Parse_MemoryError;
766 return Parse_Success;
769 static ParseResult_t ParseSocket(mxml_node_t *soc, PrivateData_t *vp)
773 bool isSource = false;
775 assert(NULL != soc && NULL != vp);
776 Ucs_SocketDirection_t direction;
777 if (!GetDirection(soc, &direction))
778 return Parse_XmlError;
779 isIn = (UCS_SOCKET_DIR_INPUT == direction);
780 if (!GetPort(soc, &port))
781 return Parse_XmlError;
786 Ucs_Xrm_MostSocket_t *sock = MCalloc(&vp->objList, 1, sizeof(Ucs_Xrm_MostSocket_t));
787 if (NULL == sock) return Parse_MemoryError;
788 if (!AddJob(vp->jobList, sock)) return Parse_XmlError;
789 sock->data_type = vp->dataType;
790 sock->bandwidth = vp->blockWidth;
791 if (Parse_Success != ParseMostSoc(sock, soc, vp))
792 return Parse_XmlError;
793 isSource = (UCS_SOCKET_DIR_OUTPUT == direction);
794 if (isIn) vp->inSocket = sock; else vp->outSocket = sock;
799 Ucs_Xrm_UsbSocket_t *sock = MCalloc(&vp->objList, 1, sizeof(Ucs_Xrm_UsbSocket_t));
800 if (NULL == sock) return Parse_MemoryError;
801 if (!AddJob(vp->jobList, sock)) return Parse_XmlError;
802 sock->data_type = vp->dataType;
803 if (Parse_Success != ParseUsbSoc(sock, soc, vp))
804 return Parse_XmlError;
805 if (isIn) vp->inSocket = sock; else vp->outSocket = sock;
810 Ucs_Xrm_MlbSocket_t *sock = MCalloc(&vp->objList, 1, sizeof(Ucs_Xrm_MlbSocket_t));
811 if (NULL == sock) return Parse_MemoryError;
812 if (!AddJob(vp->jobList, sock)) return Parse_XmlError;
813 sock->data_type = vp->dataType;
814 sock->bandwidth = vp->blockWidth;
815 if (Parse_Success != ParseMlbSoc(sock, soc, vp))
816 return Parse_XmlError;
817 if (isIn) vp->inSocket = sock; else vp->outSocket = sock;
822 Ucs_Xrm_StrmSocket_t *sock = MCalloc(&vp->objList, 1, sizeof(Ucs_Xrm_StrmSocket_t));
823 if (NULL == sock) return Parse_MemoryError;
824 sock->data_type = vp->dataType;
825 sock->bandwidth = vp->blockWidth;
826 if (Parse_Success != ParseStreamSoc(sock, soc, vp))
827 return Parse_XmlError;
828 if (isIn) vp->inSocket = sock; else vp->outSocket = sock;
833 return Parse_XmlError;
835 if (GetUInt16(soc, OFFSET, &offset, false))
837 //TODO: If offset is non zero allocate Splitter / Combiner
839 //Connect in and out socket once they are created
840 if (vp->inSocket && vp->outSocket)
846 Ucs_Xrm_AvpCon_t *con = MCalloc(&vp->objList, 1, sizeof(Ucs_Xrm_AvpCon_t));
847 if (NULL == con) return Parse_MemoryError;
848 if (!AddJob(vp->jobList, con))
849 return Parse_XmlError;
850 con->resource_type = UCS_XRM_RC_TYPE_AVP_CON;
851 con->socket_in_obj_ptr = vp->inSocket;
852 con->socket_out_obj_ptr = vp->outSocket;
853 con->isoc_packet_size = UCS_ISOC_PCKT_SIZE_188; //TODO:Read from XML
858 Ucs_Xrm_SyncCon_t *con = MCalloc(&vp->objList, 1, sizeof(Ucs_Xrm_SyncCon_t));
859 if (NULL == con) return Parse_MemoryError;
860 if (!AddJob(vp->jobList, con))
861 return Parse_XmlError;
862 con->resource_type = UCS_XRM_RC_TYPE_SYNC_CON;
863 con->socket_in_obj_ptr = vp->inSocket;
864 con->socket_out_obj_ptr = vp->outSocket;
865 con->mute_mode = UCS_SYNC_MUTE_MODE_NO_MUTING; //TODO:Read from XML
866 con->offset = offset;
870 UcsXml_CB_OnError("Could not connect sockets, data type not implemented: %d", 1, vp->dataType);
871 return Parse_XmlError;
874 Ucs_Rm_EndPoint_t *ep = MCalloc(&vp->objList, 1, sizeof(Ucs_Rm_EndPoint_t));
875 if (NULL == ep) return Parse_MemoryError;
876 ep->endpoint_type = isSource ? UCS_RM_EP_SOURCE : UCS_RM_EP_SINK;
877 ep->jobs_list_ptr = vp->jobList;
878 ep->node_obj_ptr = vp->nod;
880 struct UcsXmlRouteInfo *route = MCalloc(&vp->objList, 1, sizeof(struct UcsXmlRouteInfo));
881 if (NULL == route) return Parse_MemoryError;
882 route->isSource = isSource;
884 strncpy(route->routeName, vp->chName, sizeof(route->routeName));
885 AddRoute(&vp->pRtLst, route);
887 return Parse_Success;
890 static ParseResult_t ParseMostSoc(Ucs_Xrm_MostSocket_t *mostSoc, mxml_node_t *soc, PrivateData_t *vp)
892 assert(NULL != mostSoc && NULL != soc && NULL != vp);
893 COMPILETIME_CHECK(SYNC_DATA == (MData_t)UCS_MOST_SCKT_SYNC_DATA);
894 COMPILETIME_CHECK(AV_PACKETIZED == (MData_t)UCS_MOST_SCKT_AV_PACKETIZED);
895 COMPILETIME_CHECK(QOS_IP == (MData_t)UCS_MOST_SCKT_QOS_IP);
896 COMPILETIME_CHECK(DISC_FRAME_PHASE == (MData_t)UCS_MOST_SCKT_DISC_FRAME_PHASE);
897 switch((MData_t)mostSoc->data_type)
902 case DISC_FRAME_PHASE:
903 break; //Nothing to do, valid values.
905 UcsXml_CB_OnError("Invalid DataType=%d for MOST socket", 1, mostSoc->data_type);
906 return Parse_XmlError;
908 mostSoc->resource_type = UCS_XRM_RC_TYPE_MOST_SOCKET;
909 mostSoc->most_port_handle = 0x0D00;
910 if (!GetDirection(soc, &mostSoc->direction))
911 return Parse_XmlError;
912 return Parse_Success;
915 static ParseResult_t ParseUsbSoc(Ucs_Xrm_UsbSocket_t *usbSoc, mxml_node_t *soc, PrivateData_t *vp)
917 Ucs_Xrm_DefaultCreatedPort_t *p;
918 assert(NULL != usbSoc && NULL != soc && NULL != vp);
919 COMPILETIME_CHECK(SYNC_DATA == (MData_t)UCS_USB_SCKT_SYNC_DATA);
920 COMPILETIME_CHECK(CONTROL_DATA == (MData_t)UCS_USB_SCKT_CONTROL_DATA);
921 COMPILETIME_CHECK(AV_PACKETIZED == (MData_t)UCS_USB_SCKT_AV_PACKETIZED);
922 switch((MData_t)usbSoc->data_type)
927 break; //Nothing to do, valid values.
929 UcsXml_CB_OnError("Invalid DataType=%d for USB socket", 1, usbSoc->data_type);
930 return Parse_XmlError;
932 usbSoc->resource_type = UCS_XRM_RC_TYPE_USB_SOCKET;
933 if (!GetDirection(soc, &usbSoc->direction))
934 return Parse_XmlError;
935 if (!GetUInt8(soc, ADDRESS, &usbSoc->end_point_addr, true))
936 return Parse_XmlError;
938 if (!GetUInt16(soc, PACKETS_XACT, &usbSoc->frames_per_transfer, true))
939 return Parse_XmlError;
941 //XML provides currently no way to open USB port, so use ConfigString default
942 p = MCalloc(&vp->objList, 1, sizeof(Ucs_Xrm_DefaultCreatedPort_t));
943 if (NULL == p) return Parse_MemoryError;
944 if (!AddJob(vp->jobList, p)) return Parse_MemoryError;
945 p->resource_type = UCS_XRM_RC_TYPE_DC_PORT;
946 p->port_type = UCS_XRM_PORT_TYPE_USB;
948 usbSoc->usb_port_obj_ptr = p;
949 return Parse_Success;
952 static ParseResult_t ParseMlbSoc(Ucs_Xrm_MlbSocket_t *mlbSoc, mxml_node_t *soc, PrivateData_t *vp)
954 Ucs_Mlb_ClockConfig_t clock;
955 assert(NULL != mlbSoc && NULL != soc && NULL != vp);
956 COMPILETIME_CHECK(SYNC_DATA == (MData_t)UCS_MLB_SCKT_SYNC_DATA);
957 COMPILETIME_CHECK(CONTROL_DATA == (MData_t)UCS_MLB_SCKT_CONTROL_DATA);
958 COMPILETIME_CHECK(AV_PACKETIZED == (MData_t)UCS_USB_SCKT_AV_PACKETIZED);
959 COMPILETIME_CHECK(QOS_IP == (MData_t)UCS_MLB_SCKT_QOS_IP);
960 COMPILETIME_CHECK(DISC_FRAME_PHASE == (MData_t)UCS_MLB_SCKT_DISC_FRAME_PHASE);
961 COMPILETIME_CHECK(IPC_PACKET == (MData_t)UCS_MLB_SCKT_IPC_PACKET);
962 switch((MData_t)mlbSoc->data_type)
968 case DISC_FRAME_PHASE:
970 break; //Nothing to do, valid values.
972 UcsXml_CB_OnError("Invalid DataType=%d for MLB socket", 1, mlbSoc->data_type);
973 return Parse_XmlError;
975 mlbSoc->resource_type = UCS_XRM_RC_TYPE_MLB_SOCKET;
976 if (!GetDirection(soc, &mlbSoc->direction))
977 return Parse_XmlError;
978 if (!GetUInt16(soc, ADDRESS, &mlbSoc->channel_address, true))
979 return Parse_XmlError;
981 //Create MLB port when DEVICE_MLB_SPEED is defined, otherwise use ConfigString default
982 if (GetMlbSpeed(soc, DEVICE_MLB_SPEED, &clock, false))
984 Ucs_Xrm_MlbPort_t *p = MCalloc(&vp->objList, 1, sizeof(Ucs_Xrm_MlbPort_t));
985 if (NULL == p) return Parse_MemoryError;
986 if (!AddJob(vp->jobList, p)) return Parse_MemoryError;
987 p->resource_type = UCS_XRM_RC_TYPE_MLB_PORT;
989 p->clock_config = clock;
990 mlbSoc->mlb_port_obj_ptr = p;
992 Ucs_Xrm_DefaultCreatedPort_t *p = MCalloc(&vp->objList, 1, sizeof(Ucs_Xrm_DefaultCreatedPort_t));
993 if (NULL == p) return Parse_MemoryError;
994 if (!AddJob(vp->jobList, p)) return Parse_MemoryError;
995 p->resource_type = UCS_XRM_RC_TYPE_DC_PORT;
996 p->port_type = UCS_XRM_PORT_TYPE_MLB;
998 mlbSoc->mlb_port_obj_ptr = p;
1000 return Parse_Success;
1003 static ParseResult_t ParseStreamSoc(Ucs_Xrm_StrmSocket_t *strmSoc, mxml_node_t *soc, PrivateData_t *vp)
1006 Ucs_Xrm_StrmPort_t *strPort;
1007 assert(NULL != strmSoc && NULL != soc && NULL != vp);
1008 COMPILETIME_CHECK(SYNC_DATA == (MData_t)UCS_STREAM_PORT_SCKT_SYNC_DATA);
1009 if (SYNC_DATA != (MData_t)strmSoc->data_type)
1011 UcsXml_CB_OnError("Invalid DataType=%d for I2S socket", 1, strmSoc->data_type);
1012 return Parse_XmlError;
1014 strPort = MCalloc(&vp->objList, 1, sizeof(Ucs_Xrm_StrmPort_t));
1015 if (NULL == strPort) return Parse_MemoryError;
1016 if (!AddJob(vp->jobList, strPort)) return Parse_MemoryError;
1017 if (!AddJob(vp->jobList, strmSoc)) return Parse_MemoryError;
1018 strmSoc->resource_type = UCS_XRM_RC_TYPE_STRM_SOCKET;
1019 strmSoc->stream_port_obj_ptr = strPort;
1021 strPort->resource_type = UCS_XRM_RC_TYPE_STRM_PORT;
1022 if (!GetDirection(soc, &strmSoc->direction))
1023 return Parse_XmlError;
1024 if (!GetI2SPin(soc, &strmSoc->stream_pin_id, &strPort->index, true))
1025 return Parse_XmlError;
1026 if (!GetI2SSpeed(soc, I2S_FS_SPEED, &strPort->clock_config, true))
1027 return Parse_XmlError;
1028 if (!GetString(soc, I2S_ALIGN, &txt, true))
1029 return Parse_XmlError;
1030 if (!GetI2SAlignment(soc, &strPort->data_alignment, true))
1031 return Parse_XmlError;
1032 return Parse_Success;
1035 static ParseResult_t ParseScript(mxml_node_t *scr, PrivateData_t *vp)
1041 assert(NULL != scr && NULL != vp);
1043 if (!GetString(scr, NAME, &txt, true))
1044 return Parse_XmlError;
1045 Ucs_Rm_Node_t *n = NULL;
1046 struct UcsXmlScriptInfo *scrlist = vp->pScrLst;
1047 while(NULL != scrlist)
1049 if (0 == strcmp(txt, scrlist->scriptName))
1054 scrlist = scrlist->next;
1058 UcsXml_CB_OnError("Script defined:'%s', which was never referenced", 1, txt);
1059 return Parse_XmlError;
1061 if (!GetCount(scr, ACTION, &actCnt, true)) return Parse_XmlError;
1062 if (NULL == (n->script_list_ptr = MCalloc(&vp->objList, actCnt, sizeof(Ucs_Ns_Script_t))))
1063 return Parse_MemoryError;
1064 n->script_list_size = actCnt;
1065 ///Iterate all actions
1066 if (!GetElement(scr, ACTION, true, &act, true)) return false;
1069 ParseResult_t result = ParseScriptAction(act, n, i, vp);
1070 if (Parse_Success != result) return result;
1071 if (!GetElement(act, ACTION, false, &act, false))
1075 return Parse_Success;
1078 static ParseResult_t ParseScriptAction(mxml_node_t *act, Ucs_Rm_Node_t *n, uint32_t index, PrivateData_t *vp)
1082 assert(NULL != act && NULL != vp);
1083 Ucs_Ns_Script_t *scr = &n->script_list_ptr[index];
1084 if (!GetString(act, TYPE, &txt, true))
1085 return Parse_XmlError;
1086 if (0 == strcmp(txt, SEND_MSG))
1088 Ucs_Ns_ConfigMsg_t *req;
1089 scr->send_cmd = MCalloc(&vp->objList, 1, sizeof(Ucs_Ns_ConfigMsg_t));
1090 req = scr->send_cmd;
1091 if (NULL == req) return Parse_MemoryError;
1092 scr->pause = vp->pause;
1093 if (vp->pause) vp->pause = 0;
1095 if (!GetUInt8(act, FBLOCK_ID, &req->FBlockId, true))
1096 return Parse_XmlError;
1098 if (!GetUInt16(act, FUNCTION_ID, &req->FunktId, true))
1099 return Parse_XmlError;
1101 if (!GetUInt8(act, OP_TYPE_REQUEST, &req->OpCode, true))
1102 return Parse_XmlError;
1104 if (GetUInt8(act, OP_TYPE_RESPONSE, &opResult, false))
1106 //Waiting for response is optional
1107 Ucs_Ns_ConfigMsg_t *res;
1108 scr->exp_result = MCalloc(&vp->objList, 1, sizeof(Ucs_Ns_ConfigMsg_t));
1109 res = scr->exp_result;
1110 res->FBlockId = req->FBlockId;
1111 res->InstId = req->InstId;
1112 res->FunktId = req->FunktId;
1113 res->OpCode = opResult;
1114 //Not interested in result:
1115 GetPayload(act, PAYLOAD_RES_HEX, &res->DataPtr, &res->DataLen, &vp->objList, false);
1117 if (!GetPayload(act, PAYLOAD_REQ_HEX, &req->DataPtr, &req->DataLen, &vp->objList, true))
1118 return Parse_XmlError;
1119 if (0 == req->DataLen || NULL == req->DataPtr)
1120 return Parse_XmlError;
1122 else if (0 == strcmp(txt, PAUSE))
1124 if (!GetUInt16(act, PAUSE_MS, &vp->pause, true))
1125 return Parse_XmlError;
1127 return Parse_Success;
1130 static ParseResult_t ParseRoutes(UcsXmlVal_t *v, PrivateData_t *vp)
1132 uint16_t routeAmount = 0;
1133 struct UcsXmlRouteInfo *sourceRoute;
1134 assert(NULL != v && NULL != vp);
1135 //First: Count the amount of routes and allocate the correct amount
1136 sourceRoute = vp->pRtLst;
1137 while (NULL != sourceRoute)
1139 if (!sourceRoute->isSource) //There can be more sinks than sources, so count them
1143 sourceRoute = sourceRoute->next;
1145 if (0 == routeAmount)
1146 return Parse_Success; //Its okay to have no routes at all (e.g. MEP traffic only)
1147 v->pRoutes = MCalloc(&vp->objList, routeAmount, sizeof(Ucs_Rm_Route_t));
1148 if (NULL == v->pRoutes) return Parse_MemoryError;
1150 //Second: Fill allocated structure now
1151 sourceRoute = vp->pRtLst;
1152 while (NULL != sourceRoute)
1154 if (sourceRoute->isSource)
1156 struct UcsXmlRouteInfo *sinkRoute = vp->pRtLst;
1157 while (NULL != sinkRoute)
1159 if (sourceRoute != sinkRoute
1160 && !sinkRoute->isSource
1161 && (0 == strncmp(sourceRoute->routeName, sinkRoute->routeName, sizeof(sourceRoute->routeName))))
1163 Ucs_Rm_Route_t *route = &v->pRoutes[v->routesSize++];
1164 route->source_endpoint_ptr = sourceRoute->ep;
1165 route->sink_endpoint_ptr = sinkRoute->ep;
1168 sinkRoute = sinkRoute->next;
1171 sourceRoute = sourceRoute->next;
1173 return Parse_Success;