]> rtime.felk.cvut.cz Git - linux-lin.git/blob - lin_config/src/linc_parse_xml.c
linconf: Modular architecture.
[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 Entry = %d\n", interval, linid);
51                 }
52                 cur = cur->next;
53         }
54 }
55
56 void linc_parse_frame_configuration(struct linc_lin_state *linc_lin_state, xmlDocPtr doc, xmlNodePtr cur)
57 {
58         xmlNodePtr tmp_node;
59         int val;
60
61         cur = cur->children;
62         while (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;
69                         int linid = -1;
70
71                         while (tmp_node) {
72                                 if (!xmlStrcmp(tmp_node->name, (const xmlChar *)"ID")) {
73                                         val = linc_xml_get_element_int(doc, tmp_node);
74                                         linid = val;
75                                         //printf("ID = %d\n", val);
76                                 }
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);
81                                 }
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);
86                                 }
87                                 if (!xmlStrcmp(tmp_node->name, (const xmlChar *)"Data")) {
88                                         int indx = 0;
89                                         xmlNodePtr tmp_node2;
90                                         tmp_node2 = tmp_node->children;
91                                         while (tmp_node2) {
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);
99                                                         indx++;
100                                                 }
101                                                 tmp_node2 = tmp_node2->next;
102                                         }
103                                 }
104                                 tmp_node = tmp_node->next;
105                         }
106
107                         if (linid >= 0) {
108                                 memcpy(&linc_lin_state->frame_entry[linid], &tmp_fr_entry,
109                                         sizeof(struct linc_frame_entry));
110                         }
111                 }
112                 cur = cur->next;
113         }
114 }
115
116 int linc_parse_configuration(char *filename, struct linc_lin_state *linc_lin_state)
117 {
118         xmlDocPtr doc;
119         xmlNodePtr cur_node;
120
121         if (!filename)
122                 filename = PCL_DEFAULT_CONFIG;
123
124         xmlKeepBlanksDefault(1);
125         doc = xmlParseFile(filename);
126         if (doc == NULL)
127                 return -1;
128
129         cur_node = xmlDocGetRootElement(doc);
130         if (cur_node == NULL) {
131                 fprintf(stderr, "Configuration file %s is empty\n", filename);
132                 xmlFreeDoc(doc);
133                 return -1;
134         }
135
136         /* Check for Root element */
137         if (xmlStrcmp(cur_node->name, (const xmlChar *)"PCLIN_PROFILE"))
138                 goto exit_failure;
139
140         /* Check for LIN element */
141         cur_node = cur_node->children;
142         while (cur_node) {
143                 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"LIN"))
144                         break;
145
146                 cur_node = cur_node->next;
147         }
148
149         if (!cur_node)
150                 goto exit_failure;
151
152         /* Process LIN configuration */
153         cur_node = cur_node->children;
154         while (cur_node) {
155                 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Active")) {
156                         linc_lin_state->is_active = linc_xml_get_element_int(doc, cur_node);
157                 }
158                 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Baudrate")) {
159                         linc_lin_state->baudrate = linc_xml_get_element_int(doc, cur_node);
160                 }
161                 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Master_Status")) {
162                         linc_lin_state->master_status = linc_xml_get_element_int(doc, cur_node);
163                 }
164                 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Bus_Termination")) {
165                         linc_lin_state->bus_termination = linc_xml_get_element_int(doc, cur_node);
166                 }
167                 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Scheduler_Entries")) {
168                         linc_parse_scheduler_entries(linc_lin_state, doc, cur_node);
169                 }
170                 if (!xmlStrcmp(cur_node->name, (const xmlChar *)"Frame_Configuration")) {
171                         linc_parse_frame_configuration(linc_lin_state, doc, cur_node);
172                 }
173
174                 cur_node = cur_node->next;
175         }
176
177         xmlFreeDoc(doc);
178         return 0;
179
180 exit_failure:
181         fprintf(stderr, "Invalid configuration file\n");
182         xmlFreeDoc(doc);
183         return -1;
184 }
185