-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.c
154 lines (123 loc) · 3.17 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include <stdlib.h>
#include <stdio.h>
#include "meter.h"
#include "conf-parser.h"
#include "db_sqlite.h"
#define GLB_DBFILE "./ele_meter.db"
static pa_config_item items[] = {
/* [meter] */
{"slave-addr", pa_config_parse_unsigned, NULL, NULL},
{"name", pa_config_parse_string, NULL, NULL},
/* [meter registers] */
{"register-addr", pa_config_parse_unsigned, NULL, NULL},
{"repeat-num", pa_config_parse_unsigned, NULL, NULL},
{"scale-addr", pa_config_parse_unsigned, NULL, NULL},
{"unit", pa_config_parse_string, NULL, NULL},
{"data_type", pa_config_parse_string, NULL, NULL},
{NULL, NULL, NULL, NULL}
};
struct ele_meter *glb_meter;
static pa_config_parser_state state;
static void fill_parser_state_meter(struct pa_config_item *items,
struct ele_meter *pmeter)
{
items[0].data = &pmeter->addr;
items[1].data = &pmeter->name;
}
static void fill_parser_state_register(struct pa_config_item *items,
struct meter_register *reg)
{
items[2].data = ®->reg_addr;
items[3].data = ®->repeat_num;
items[4].data = ®->scale_addr;
items[5].data = ®->unit;
items[6].data = ®->dtype;
}
void print_register_info(struct meter_register *preg)
{
printf("reg_addr = %d, repeat_num = %d, unit = %s, scale_addr = %d\n", preg->reg_addr,
preg->repeat_num, preg->unit, preg->scale_addr);
printf("\n");
}
void print_meter_registers(struct ele_meter *pmeter)
{
struct meter_register *preg;
preg = pmeter->registers;
while (preg) {
print_register_info(preg);
preg = preg->next;
}
}
void print_meter_info(struct ele_meter *pmeter)
{
printf("\n\n\n");
printf("name = %s\n", pmeter->name);
printf("addr = %d\n", pmeter->addr);
}
void print_all_meters()
{
struct ele_meter *pmeter;
pmeter = glb_meter;
while (pmeter) {
print_meter_info(pmeter);
print_meter_registers(pmeter);
pmeter = pmeter->next;
}
}
int build_glb_meter_list(FILE *f, pa_config_parser_state *pstate)
{
int r;
struct ele_meter **next_meter;
struct meter_register **next_reg;
next_meter = &glb_meter;
parse_again:
r = pa_config_parse(f, pstate);
/* r = 1 means a new register is found */
if (r == 1) {
struct meter_register *reg;
reg = malloc(sizeof(struct meter_register));
fill_parser_state_register(items, reg);
*next_reg = reg;
next_reg = ®->next;
goto parse_again;
}
/* r = 2 means a new meter is found */
if (r == 2) {
struct ele_meter *pmeter;
pmeter = malloc(sizeof(struct ele_meter));
fill_parser_state_meter(items, pmeter);
*next_meter = pmeter;
next_meter = &pmeter->next;
next_reg = &pmeter->registers;
goto parse_again;
}
printf("r = %d\n", r);
return r;
}
int main ()
{
FILE *f;
int r;
sqlite3 *db;
const char *filename = "./elec_meters.conf";
if (!(f = pa_fopen_cloexec(filename, "r"))) {
printf("open meter config failed.\n");
goto error_exit;
}
state.filename = filename;
state.item_table = items;
r = build_glb_meter_list(f, &state);
if (r != 0)
goto error_exit;
mb_read_all_meters(glb_meter);
print_all_meters();
db = db_glb_init(GLB_DBFILE);
if (db == NULL) {
printf("openning database failed\n");
goto error_exit;
}
db_insert_meters(db, glb_meter);
db_glb_close(db);
error_exit:
return -1;
}