blob: f39321c55f5319fa731e2eeedefd0eae9526fc37 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/******************************************************************************
2*(C) Copyright 2016 notion International Ltd.
3* All Rights Reserved
4******************************************************************************/
5/* -------------------------------------------------------------------------------------------------------------------
6 *
7 * Filename: mgui_version.c
8 *
9 * Authors: yueguangkai
10 *
11 * Description: MGUI version interface
12 *
13 * HISTORY:
14 *
15 * Feb 23, 2016 - Initial Version
16 *
17 * Notes:
18 *
19 ******************************************************************************/
20
21/******************************************************************************
22 * Include files
23 ******************************************************************************/
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <inttypes.h>
28#include "mgui_utils.h"
29#include "mgui_ubus.h"
30#include "mgui_icons.h"
31#include "mgui_version.h"
32#include "mgui.h"
33
34/******************************************************************************
35 * Structures
36 ******************************************************************************/
37
38/******************************************************************************
39 * Definitions
40 ******************************************************************************/
41//#define VERSION_DEBUG
42
43#define VERSION_UBUS_ID "version"
44#define VERSION_UBUS_REQUEST "get_version"
45
46/******************************************************************************
47 * Globals
48 ******************************************************************************/
49
50/* version get_version */
51enum {
52 ATTR_VERSION_INFO = 0,
53 ATTR_SW_VERSION,
54 ATTR_HDWARE_VER,
55 ATTR_BUILD_TIME,
56 ATTR_CP_LTG_VER,
57 ATTR_CP_LWG_VER,
58 ATTR_MAC_ADDR,
59};
60
61static const struct blobmsg_policy version_info_attr_policy[] = {
62 [ATTR_VERSION_INFO] = {.name = "version_info", .type = BLOBMSG_TYPE_TABLE},
63 [ATTR_SW_VERSION] = {.name = "sw_version", .type = BLOBMSG_TYPE_STRING},
64 [ATTR_HDWARE_VER] = {.name = "hdware_ver", .type = BLOBMSG_TYPE_STRING},
65 [ATTR_BUILD_TIME] = {.name = "build_time", .type = BLOBMSG_TYPE_STRING},
66 [ATTR_CP_LTG_VER] = {.name = "CP_LTG_VER", .type = BLOBMSG_TYPE_STRING},
67 [ATTR_CP_LWG_VER] = {.name = "CP_LWG_VER", .type = BLOBMSG_TYPE_STRING},
68 [ATTR_MAC_ADDR] = {.name = "mac_addr", .type = BLOBMSG_TYPE_STRING},
69};
70
71static struct blob_buf b;
72
73/******************************************************************************
74 * Code
75 ******************************************************************************/
76
77#ifdef VERSION_DEBUG
78static const char *indent_str = "\t\t\t\t\t\t\t\t\t\t\t\t\t";
79
80#define indent_printf(indent, ...) do { \
81 if (indent > 0) \
82 fwrite(indent_str, indent, 1, stderr); \
83 fprintf(stderr, __VA_ARGS__); \
84} while(0)
85
86static void dump_attr_data(struct blob_attr *data, int indent, int next_indent);
87
88static void
89dump_table(struct blob_attr *head, int len, int indent, bool array)
90{
91 struct blob_attr *attr;
92 struct blobmsg_hdr *hdr;
93
94 indent_printf(indent, "{\n");
95 __blob_for_each_attr(attr, head, len) {
96 hdr = blob_data(attr);
97 if (!array)
98 indent_printf(indent + 1, "%s : ", hdr->name);
99 dump_attr_data(attr, 0, indent + 1);
100 }
101 indent_printf(indent, "}\n");
102}
103
104static void dump_attr_data(struct blob_attr *data, int indent, int next_indent)
105{
106 int type = blobmsg_type(data);
107 switch(type) {
108 case BLOBMSG_TYPE_STRING:
109 indent_printf(indent, "%s\n", blobmsg_get_string(data));
110 break;
111 case BLOBMSG_TYPE_INT8:
112 indent_printf(indent, "%d\n", blobmsg_get_u8(data));
113 break;
114 case BLOBMSG_TYPE_INT16:
115 indent_printf(indent, "%d\n", blobmsg_get_u16(data));
116 break;
117 case BLOBMSG_TYPE_INT32:
118 indent_printf(indent, "%d\n", blobmsg_get_u32(data));
119 break;
120 case BLOBMSG_TYPE_INT64:
121 indent_printf(indent, "%"PRIu64"\n", blobmsg_get_u64(data));
122 break;
123 case BLOBMSG_TYPE_TABLE:
124 case BLOBMSG_TYPE_ARRAY:
125 if (!indent)
126 indent_printf(indent, "\n");
127 dump_table(blobmsg_data(data), blobmsg_data_len(data),
128 next_indent, type == BLOBMSG_TYPE_ARRAY);
129 break;
130 }
131}
132#endif /* VERSION_DEBUG */
133
134static int version_info_parse_blobmsg(struct mgui_version_context *ctx, struct blob_attr *msg)
135{
136 struct blob_attr *tb[ARRAY_SIZE(version_info_attr_policy)];
137 int ret;
138
139 MASSERT(ctx);
140
141 ret = blobmsg_parse(version_info_attr_policy, ARRAY_SIZE(version_info_attr_policy),
142 tb, blob_data(msg), blob_len(msg));
143 if (ret){
144 MGUI_EMSG("parsing version blobmsg failed %d\n", ret);
145 return -1;
146 }
147
148 if (!tb[ATTR_VERSION_INFO])
149 return -1;
150 ret = blobmsg_parse(version_info_attr_policy, ARRAY_SIZE(version_info_attr_policy), tb,
151 blobmsg_data(tb[ATTR_VERSION_INFO]),
152 blobmsg_data_len(tb[ATTR_VERSION_INFO]));
153 if (ret){
154 MGUI_EMSG("parsing version blobmsg failed %d\n", ret);
155 return -1;
156 }
157
158 ctx->info.sw_version= blobmsg_get_string(tb[ATTR_SW_VERSION]);
159 ctx->info.hdware_ver= blobmsg_get_string(tb[ATTR_HDWARE_VER]);
160 ctx->info.build_time= blobmsg_get_string(tb[ATTR_BUILD_TIME]);
161 ctx->info.CP_LTG_VER= blobmsg_get_string(tb[ATTR_CP_LTG_VER]);
162 ctx->info.CP_LWG_VER= blobmsg_get_string(tb[ATTR_CP_LWG_VER]);
163 ctx->info.mac_addr= blobmsg_get_string(tb[ATTR_MAC_ADDR]);
164
165 MGUI_IMSG("parsing version blobmsg sw_version = %s, hdware_ver = %s, build_time = %s, CP_LTG_VER = %s,CP_LWG_VER = %s,mac_addr = %s\n",
166 ctx->info.sw_version,
167 ctx->info.hdware_ver,
168 ctx->info.build_time,
169 ctx->info.CP_LTG_VER,
170 ctx->info.CP_LWG_VER,
171 ctx->info.mac_addr);
172
173 return 0;
174}
175
176static void version_info_data_cb(struct ubus_request *req, int type, struct blob_attr *msg)
177{
178 struct mgui_version_context *version = (struct mgui_version_context *)req->priv;
179 int ret;
180
181 MASSERT(version);
182
183 MGUI_DMSG("version data received\n");
184
185 ret = version_info_parse_blobmsg(version, msg);
186 if (ret){
187 MGUI_EMSG("parsing blobmsg failed %d\n", ret);
188 return;
189 }
190
191 mgui_update_icon(version->mgui, MGUI_VERSION_ICON, version);
192}
193
194static void version_complete_cb(struct ubus_request *req, int ret)
195{
196 struct mgui_version_context *version = (struct mgui_version_context *)req->priv;
197
198 MGUI_DMSG("version complete received\n");
199 /* trigger screen refresh since this is a result of an async request */
200 mgui_screen_refresh(version->mgui);
201}
202
203
204static inline int mgui_version_info_request(struct mgui_version_context *ctx)
205{
206 return mgui_ubus_invoke_async(ctx->mgui->ubus, &b, ctx->version_ubus_id,
207 VERSION_UBUS_REQUEST, version_info_data_cb, version_complete_cb, ctx);
208}
209
210/**
211 * mgui_version_exit
212 * De-initialize version interface
213 *
214 * @param version pointer to previously allocated version context
215 *
216 * @return 0 for success, error code otherwise
217 */
218int mgui_version_exit(struct mgui_version_context *version)
219{
220 if(!version) {
221 MGUI_IMSG("version module not running\n");
222 return 0;
223 }
224
225 if (version->info.build_time)
226 free(version->info.build_time);
227 if (version->info.CP_LTG_VER)
228 free(version->info.CP_LTG_VER);
229 if (version->info.CP_LWG_VER)
230 free(version->info.CP_LWG_VER);
231 if (version->info.hdware_ver)
232 free(version->info.hdware_ver);
233 if (version->info.mac_addr)
234 free(version->info.mac_addr);
235 if (version->info.sw_version)
236 free(version->info.sw_version);
237 free(version);
238
239 MGUI_IMSG("version exit done\n");
240
241 return 0;
242}
243
244/**
245 * mgui_version_init
246 * Initialize mgui version interface
247 *
248 * NOTE - must be called BEFORE uloop_run()!
249 *
250 * @param mgui mgui context
251 *
252 * @return pointer to mgui_version_context
253 */
254struct mgui_version_context *mgui_version_init(struct mgui_context *mgui)
255{
256 struct mgui_version_context *ver;
257 int ret;
258
259 MASSERT(mgui);
260 MASSERT(mgui->ubus);
261
262 ver = malloc(sizeof(struct mgui_version_context));
263 if (!ver) {
264 MGUI_EMSG("memory allocation failed\n");
265 return NULL;
266 }
267
268 memset(ver, 0, sizeof(*ver));
269
270 ver->mgui = mgui;
271
272 ret = mgui_ubus_lookup_id(ver->mgui->ubus, VERSION_UBUS_ID,
273 &ver->version_ubus_id);
274 if (ret) {
275 MGUI_EMSG("mubus_lookup_id failed (ret=%d)\n", ret);
276 goto out_error;
277 }
278
279 ret = mgui_version_info_request(ver);
280 if (ret) {
281 MGUI_EMSG("initial request failed\n");
282 goto out_error;
283 }
284
285 MGUI_IMSG("version init done\n");
286
287 return ver;
288
289out_error:
290 free(ver);
291 return NULL;
292}