]> rtime.felk.cvut.cz Git - linux-lin.git/blob - lin_config/src/linc_parse_xml.c
160ef845846e8a090c68fa9163c93435fcb24689
[linux-lin.git] / lin_config / src / linc_parse_xml.c
1 #include <libxml/parser.h>
2 #include <assert.h>
3 #include <string.h>
4 #include "lin_config.h"
5
6 static inline int linc_xml_get_prop_int(xmlNodePtr cur, const xmlChar* str)
7 {
8         int val;
9         xmlChar *attr;
10
11         attr = xmlGetProp(cur, str);
12         if (!attr)
13                 assert(0);
14
15         val = atoi((const char *)attr); // FIXME error handling
16         xmlFree(attr);
17
18         return val;
19 }
20
21 static inline int linc_xml_get_element_int(xmlDocPtr doc, xmlNodePtr cur)
22 {
23         xmlChar *key;
24         int val;
25
26         key = xmlNodeListGetString(doc, cur->children, 1);
27         if (!key)
28                 assert(0);
29
30         val = atoi((const char *)key); // FIXME error handling etc.
31         xmlFree(key);
32
33         return val;
34 }
35
36 void linc_parse_scheduler_entries(struct linc_lin_state *linc_lin_state, xmlDocPtr doc, xmlNodePtr cur)
37 {
38         cur = cur->children;
39         while (cur) {
40                 if (!xmlStrcmp(cur->name, (const xmlChar *)"Entry")) {
41                         int linid;
42                         int interval;
43                         linid = linc_xml_get_element_int(doc, cur);
44                         interval = linc_xml_get_prop_int(cur, (const xmlChar *)"Time");
45
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++;
49
50                         //printf("Time = %d Lin ID = %d Entry no. = %d\n",
51                         //      interval, linid, linc_lin_state->scheduler_entries_cnt-1);
52                 }
53                 cur = cur->next;
54         }
55 }
56
57 void linc_parse_frame_configuration(struct linc_lin_state *linc_lin_state, xmlDocPtr doc, xmlNodePtr cur)
58 {
59         xmlNodePtr tmp_node;
60         int val;
61
62         cur = cur->children;
63         while (cur) {
64                 if (!xmlStrcmp(cur->name, (const xmlChar *)"Frame")) {
65                         tmp_node = cur->children;
66                         /* We are able to write into the main Configuration array after
67                         parsing of all necessary elements (especially LIN ID) -- store
68                         parsed elements in this temporary entry -- copy the entry afterwards */
69                         struct linc_frame_entry tmp_fr_entry;
70                         int linid = -1;
71
72                         while (tmp_node) {
73                                 if (!xmlStrcmp(tmp_node->name, (const xmlChar *)"ID")) {
74                                         val = linc_xml_get_element_int(doc, tmp_node);
75                                         linid = val;
76                                         //printf("ID = %d\n", val);
77                                 }
78                                 if (!xmlStrcmp(tmp_node->name, (const xmlChar *)"Length")) {
79                                         val = linc_xml_get_element_int(doc, tmp_node);
80                                         tmp_fr_entry.data_len = val;
81                                         //printf("Length = %d\n", val);
82                                 }
83                                 if (!xmlStrcmp(tmp_node->name, (const xmlChar *)"Active")) {
84                                         val = linc_xml_get_element_int(doc, tmp_node);
85                                         tmp_fr_entry.status = val;
86                                         //printf("Active = %d\n", val);
87                                 }
88                                 if (!xmlStrcmp(tmp_node->name, (const xmlChar *)"Data")) {
89                                         int indx = 0;
90                                         xmlNodePtr tmp_node2;
91                                         tmp_node2 = tmp_node->children;
92                                         while (tmp_node2) {
93                                                 if (!xmlStrcmp(tmp_node2->name, (const xmlChar *)"Byte")) {
94                                                         // Byte indexing in XML file is wrong
95                                                         //indx = linc_xml_get_prop_int(tmp_node2,
96                                                         //      (const xmlChar *)"Index");
97                                                         val = linc_xml_get_element_int(doc, tmp_node2);
98                                                         //printf("Data = %d\n", val);
99                                                         snprintf((char *)&tmp_fr_entry.data[indx], 1, "%i", val);
100                                                         indx++;
101                                                 }
102                                                 tmp_node2 = tmp_node2->next;
103                                         }
104                                 }
105                                 tmp_node = tmp_node->next;
106                         }
107
108                         if (linid >= 0 && linid <= MAX_LIN_ID) {
109                                 memcpy(&linc_lin_state->frame_entry[linid], &tmp_fr_entry,
110                                         sizeof(struct linc_frame_entry));
111                         }
112                 }
113                 cur = cur->next;
114         }
115 }
116
117 int linc_parse_configuration(char *filename, struct linc_lin_state *linc_lin_state)
118 {
119         xmlDocPtr doc;
120         xmlNodePtr cur_node;
121
122         if (!filename)
123                 filename = PCL_DEFAULT_CONFIG;
124
125         xmlKeepBlanksDefault(1);
126         doc = xmlParseFile(filename);
127         if (doc == NULL)
128                 return -1;
129
130         cur_node = xmlDocGetRootElement(doc);
131         if (cur_node == NULL) {
132                 fprintf(stderr, "Configuration file %s is empty\n", filename);
133                 xmlFreeDoc(doc);
134                 return -1;
135         }
136
137         /* Check for Root element */
138         if (xmlStrcmp(cur_node->name, (const xmlChar *)"PCLIN_PROFILE"))
139                 goto exit_failure;
140
141         /* Check for LIN element */
142         cur_node = cur_node->children;
143         while (cur_node) {
144                 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"LIN"))
145                         break;
146
147                 cur_node = cur_node->next;
148         }
149
150         if (!cur_node)
151                 goto exit_failure;
152
153         /* Process LIN configuration */
154         cur_node = cur_node->children;
155         while (cur_node) {
156                 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Active")) {
157                         linc_lin_state->is_active = linc_xml_get_element_int(doc, cur_node);
158                 }
159                 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Baudrate")) {
160                         linc_lin_state->baudrate = linc_xml_get_element_int(doc, cur_node);
161                 }
162                 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Master_Status")) {
163                         linc_lin_state->master_status = linc_xml_get_element_int(doc, cur_node);
164                 }
165                 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Bus_Termination")) {
166                         linc_lin_state->bus_termination = linc_xml_get_element_int(doc, cur_node);
167                 }
168                 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Scheduler_Entries")) {
169                         linc_parse_scheduler_entries(linc_lin_state, doc, cur_node);
170                 }
171                 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Frame_Configuration")) {
172                         linc_parse_frame_configuration(linc_lin_state, doc, cur_node);
173                 }
174
175                 cur_node = cur_node->next;
176         }
177
178         xmlFreeDoc(doc);
179         return 0;
180
181 exit_failure:
182         fprintf(stderr, "Invalid configuration file\n");
183         xmlFreeDoc(doc);
184         return -1;
185 }
186