1 #include <libxml/parser.h>
4 #include "lin_config.h"
6 static inline int linc_xml_get_prop_int(xmlNodePtr cur, const xmlChar* str)
11 attr = xmlGetProp(cur, str);
15 val = atoi((const char *)attr); // FIXME error handling
21 static inline int linc_xml_get_element_int(xmlDocPtr doc, xmlNodePtr cur)
26 key = xmlNodeListGetString(doc, cur->children, 1);
30 val = atoi((const char *)key); // FIXME error handling etc.
36 void linc_parse_scheduler_entries(struct linc_lin_state *linc_lin_state, xmlDocPtr doc, xmlNodePtr cur)
40 if (!xmlStrcmp(cur->name, (const xmlChar *)"Entry")) {
43 linid = linc_xml_get_element_int(doc, cur);
44 interval = linc_xml_get_prop_int(cur, (const xmlChar *)"Time");
46 linc_lin_state->scheduler_entry[linc_lin_state->scheduler_entries_cnt].lin_id = linid;
47 linc_lin_state->scheduler_entry[linc_lin_state->scheduler_entries_cnt].interval_ms = interval;
48 linc_lin_state->scheduler_entries_cnt++;
50 //printf("Time = %d Entry = %d\n", interval, linid);
56 void linc_parse_frame_configuration(struct linc_lin_state *linc_lin_state, xmlDocPtr doc, xmlNodePtr cur)
63 if (!xmlStrcmp(cur->name, (const xmlChar *)"Frame")) {
64 tmp_node = cur->children;
65 /* We are able to write into the main Configuration array after
66 parsing of all necessary elements (especially LIN ID) -- store
67 parsed elements in this temporary entry -- copy the entry afterwards */
68 struct linc_frame_entry tmp_fr_entry;
72 if (!xmlStrcmp(tmp_node->name, (const xmlChar *)"ID")) {
73 val = linc_xml_get_element_int(doc, tmp_node);
75 //printf("ID = %d\n", val);
77 if (!xmlStrcmp(tmp_node->name, (const xmlChar *)"Length")) {
78 val = linc_xml_get_element_int(doc, tmp_node);
79 tmp_fr_entry.data_len = val;
80 //printf("Length = %d\n", val);
82 if (!xmlStrcmp(tmp_node->name, (const xmlChar *)"Active")) {
83 val = linc_xml_get_element_int(doc, tmp_node);
84 tmp_fr_entry.status = val;
85 //printf("Active = %d\n", val);
87 if (!xmlStrcmp(tmp_node->name, (const xmlChar *)"Data")) {
90 tmp_node2 = tmp_node->children;
92 if (!xmlStrcmp(tmp_node2->name, (const xmlChar *)"Byte")) {
93 // Byte indexing in XML file is wrong
94 //indx = linc_xml_get_prop_int(tmp_node2,
95 // (const xmlChar *)"Index");
96 val = linc_xml_get_element_int(doc, tmp_node2);
97 //printf("Data = %d\n", val);
98 snprintf((char *)&tmp_fr_entry.data[indx], 1, "%i", val);
101 tmp_node2 = tmp_node2->next;
104 tmp_node = tmp_node->next;
108 memcpy(&linc_lin_state->frame_entry[linid], &tmp_fr_entry,
109 sizeof(struct linc_frame_entry));
116 int linc_parse_configuration(char *filename, struct linc_lin_state *linc_lin_state)
122 filename = PCL_DEFAULT_CONFIG;
124 xmlKeepBlanksDefault(1);
125 doc = xmlParseFile(filename);
129 cur_node = xmlDocGetRootElement(doc);
130 if (cur_node == NULL) {
131 fprintf(stderr, "Configuration file %s is empty\n", filename);
136 /* Check for Root element */
137 if (xmlStrcmp(cur_node->name, (const xmlChar *)"PCLIN_PROFILE"))
140 /* Check for LIN element */
141 cur_node = cur_node->children;
143 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"LIN"))
146 cur_node = cur_node->next;
152 /* Process LIN configuration */
153 cur_node = cur_node->children;
155 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Active")) {
156 linc_lin_state->is_active = linc_xml_get_element_int(doc, cur_node);
158 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Baudrate")) {
159 linc_lin_state->baudrate = linc_xml_get_element_int(doc, cur_node);
161 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Master_Status")) {
162 linc_lin_state->master_status = linc_xml_get_element_int(doc, cur_node);
164 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Bus_Termination")) {
165 linc_lin_state->bus_termination = linc_xml_get_element_int(doc, cur_node);
167 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Scheduler_Entries")) {
168 linc_parse_scheduler_entries(linc_lin_state, doc, cur_node);
170 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Frame_Configuration")) {
171 linc_parse_frame_configuration(linc_lin_state, doc, cur_node);
174 cur_node = cur_node->next;
181 fprintf(stderr, "Invalid configuration file\n");