1 #include <libxml/parser.h>
5 #include "lin_config.h"
8 * @val -- ptr to int where the int value will be saved
10 * @str -- Property name (string)
12 static inline int linc_xml_get_prop_int(int *val, xmlNodePtr cur, const xmlChar* str)
17 attr = xmlGetProp(cur, str);
22 *val = strtol((const char *)attr, &endptr, 10);
23 if ((char *)attr == endptr)
35 * @val -- ptr to int where the int value will be saved
39 static inline int linc_xml_get_element_int(int *val, xmlDocPtr doc, xmlNodePtr cur)
44 key = xmlNodeListGetString(doc, cur->children, 1);
49 *val = strtol((const char *)key, &endptr, 10);
50 if ((char *)key == endptr)
61 int linc_parse_scheduler_entries(struct linc_lin_state *linc_lin_state, xmlDocPtr doc, xmlNodePtr cur)
65 if (!xmlStrcmp(cur->name, (const xmlChar *)"Entry")) {
70 ret = linc_xml_get_element_int(&linid, doc, cur);
74 ret = linc_xml_get_prop_int(&interval, cur, (const xmlChar *)"Time");
78 linc_lin_state->scheduler_entry[linc_lin_state->scheduler_entries_cnt].lin_id = linid;
79 linc_lin_state->scheduler_entry[linc_lin_state->scheduler_entries_cnt].interval_ms = interval;
80 linc_lin_state->scheduler_entries_cnt++;
82 //printf("Time = %d Lin ID = %d Entry no. = %d\n",
83 // interval, linid, linc_lin_state->scheduler_entries_cnt-1);
90 int linc_parse_frame_configuration(struct linc_lin_state *linc_lin_state, xmlDocPtr doc, xmlNodePtr cur)
97 if (!xmlStrcmp(cur->name, (const xmlChar *)"Frame")) {
98 tmp_node = cur->children;
99 /* We are able to write into the main Configuration array after
100 parsing of all necessary elements (especially LIN ID) -- store
101 parsed elements in this temporary entry -- copy the entry afterwards */
102 struct linc_frame_entry tmp_fr_entry;
107 if (!xmlStrcmp(tmp_node->name, (const xmlChar *)"ID")) {
108 ret = linc_xml_get_element_int(&linid, doc, tmp_node);
109 //printf("ID = %d\n", linid);
113 if (!xmlStrcmp(tmp_node->name, (const xmlChar *)"Length")) {
114 ret = linc_xml_get_element_int(&val, doc, tmp_node);
118 tmp_fr_entry.data_len = val;
119 //printf("Length = %d\n", val);
121 if (!xmlStrcmp(tmp_node->name, (const xmlChar *)"Active")) {
122 ret = linc_xml_get_element_int(&val, doc, tmp_node);
126 tmp_fr_entry.status = val;
127 //printf("Active = %d\n", val);
129 if (!xmlStrcmp(tmp_node->name, (const xmlChar *)"Data")) {
131 xmlNodePtr tmp_node2;
132 tmp_node2 = tmp_node->children;
134 if (!xmlStrcmp(tmp_node2->name, (const xmlChar *)"Byte")) {
135 // Byte indexing in XML file is wrong
136 //ret = linc_xml_get_prop_int(&index, tmp_node2,
137 // (const xmlChar *)"Index");
138 ret = linc_xml_get_element_int(&val, doc, tmp_node2);
142 //printf("Data = %d\n", val);
143 snprintf((char *)&tmp_fr_entry.data[indx], 1, "%i", val);
146 tmp_node2 = tmp_node2->next;
149 tmp_node = tmp_node->next;
152 if (linid >= 0 && linid <= MAX_LIN_ID) {
153 memcpy(&linc_lin_state->frame_entry[linid], &tmp_fr_entry,
154 sizeof(struct linc_frame_entry));
163 int linc_parse_configuration(char *filename, struct linc_lin_state *linc_lin_state)
171 filename = PCL_DEFAULT_CONFIG;
173 xmlKeepBlanksDefault(1);
174 doc = xmlParseFile(filename);
178 cur_node = xmlDocGetRootElement(doc);
179 if (cur_node == NULL) {
180 fprintf(stderr, "Configuration file %s is empty\n", filename);
185 /* Check for Root element */
186 if (xmlStrcmp(cur_node->name, (const xmlChar *)"PCLIN_PROFILE"))
189 /* Check for LIN element */
190 cur_node = cur_node->children;
192 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"LIN"))
195 cur_node = cur_node->next;
201 /* Process LIN configuration */
202 cur_node = cur_node->children;
204 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Active")) {
205 ret = linc_xml_get_element_int(&val, doc, cur_node);
209 linc_lin_state->is_active = val;
211 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Baudrate")) {
212 ret = linc_xml_get_element_int(&val, doc, cur_node);
216 linc_lin_state->baudrate = val;
218 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Master_Status")) {
219 ret = linc_xml_get_element_int(&val, doc, cur_node);
223 linc_lin_state->master_status = val;
225 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Bus_Termination")) {
226 ret = linc_xml_get_element_int(&val, doc, cur_node);
230 linc_lin_state->bus_termination = val;
232 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Scheduler_Entries")) {
233 ret = linc_parse_scheduler_entries(linc_lin_state, doc, cur_node);
237 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Frame_Configuration")) {
238 ret = linc_parse_frame_configuration(linc_lin_state, doc, cur_node);
243 cur_node = cur_node->next;
250 fprintf(stderr, "Invalid configuration file\n");