xref: /aosp_15_r20/external/libwebsockets/minimal-examples/api-tests/api-test-lws_struct-json/main.c (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker  * lws-api-test-lws_struct-json
3*1c60b9acSAndroid Build Coastguard Worker  *
4*1c60b9acSAndroid Build Coastguard Worker  * Written in 2010-2020 by Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker  *
6*1c60b9acSAndroid Build Coastguard Worker  * This file is made available under the Creative Commons CC0 1.0
7*1c60b9acSAndroid Build Coastguard Worker  * Universal Public Domain Dedication.
8*1c60b9acSAndroid Build Coastguard Worker  *
9*1c60b9acSAndroid Build Coastguard Worker  * lws_struct apis are used to serialize and deserialize your C structs and
10*1c60b9acSAndroid Build Coastguard Worker  * linked-lists in a standardized way that's very modest on memory but
11*1c60b9acSAndroid Build Coastguard Worker  * convenient and easy to maintain.
12*1c60b9acSAndroid Build Coastguard Worker  *
13*1c60b9acSAndroid Build Coastguard Worker  * The API test shows how to serialize and deserialize a struct with a linked-
14*1c60b9acSAndroid Build Coastguard Worker  * list of child structs in JSON using lws_struct APIs.
15*1c60b9acSAndroid Build Coastguard Worker  */
16*1c60b9acSAndroid Build Coastguard Worker 
17*1c60b9acSAndroid Build Coastguard Worker #include <libwebsockets.h>
18*1c60b9acSAndroid Build Coastguard Worker 
19*1c60b9acSAndroid Build Coastguard Worker typedef struct {
20*1c60b9acSAndroid Build Coastguard Worker 	lws_dll2_t		list;
21*1c60b9acSAndroid Build Coastguard Worker 
22*1c60b9acSAndroid Build Coastguard Worker 	struct gpiod_line	*line;
23*1c60b9acSAndroid Build Coastguard Worker 
24*1c60b9acSAndroid Build Coastguard Worker 	const char		*name;
25*1c60b9acSAndroid Build Coastguard Worker 	const char		*wire;
26*1c60b9acSAndroid Build Coastguard Worker 
27*1c60b9acSAndroid Build Coastguard Worker 	int			chip_idx;
28*1c60b9acSAndroid Build Coastguard Worker 	int			offset;
29*1c60b9acSAndroid Build Coastguard Worker 	int			safe;
30*1c60b9acSAndroid Build Coastguard Worker } sai_jig_gpio_t;
31*1c60b9acSAndroid Build Coastguard Worker 
32*1c60b9acSAndroid Build Coastguard Worker typedef struct {
33*1c60b9acSAndroid Build Coastguard Worker 	lws_dll2_t		list;
34*1c60b9acSAndroid Build Coastguard Worker 	sai_jig_gpio_t		*gpio; /* null = wait ms */
35*1c60b9acSAndroid Build Coastguard Worker 	const char		*gpio_name;
36*1c60b9acSAndroid Build Coastguard Worker 	int			value;
37*1c60b9acSAndroid Build Coastguard Worker } sai_jig_seq_item_t;
38*1c60b9acSAndroid Build Coastguard Worker 
39*1c60b9acSAndroid Build Coastguard Worker typedef struct {
40*1c60b9acSAndroid Build Coastguard Worker 	lws_dll2_t		list;
41*1c60b9acSAndroid Build Coastguard Worker 	lws_dll2_owner_t	seq_owner;
42*1c60b9acSAndroid Build Coastguard Worker 	const char		*name;
43*1c60b9acSAndroid Build Coastguard Worker } sai_jig_sequence_t;
44*1c60b9acSAndroid Build Coastguard Worker 
45*1c60b9acSAndroid Build Coastguard Worker typedef struct {
46*1c60b9acSAndroid Build Coastguard Worker 	lws_dll2_t		list;
47*1c60b9acSAndroid Build Coastguard Worker 	lws_dll2_owner_t	gpio_owner;
48*1c60b9acSAndroid Build Coastguard Worker 	lws_dll2_owner_t	seq_owner;
49*1c60b9acSAndroid Build Coastguard Worker 
50*1c60b9acSAndroid Build Coastguard Worker 	lws_sorted_usec_list_t	sul;		/* next step in ongoing seq */
51*1c60b9acSAndroid Build Coastguard Worker 	sai_jig_seq_item_t	*current;	/* next seq step */
52*1c60b9acSAndroid Build Coastguard Worker 
53*1c60b9acSAndroid Build Coastguard Worker 	const char		*name;
54*1c60b9acSAndroid Build Coastguard Worker 
55*1c60b9acSAndroid Build Coastguard Worker 	struct lws		*wsi;
56*1c60b9acSAndroid Build Coastguard Worker } sai_jig_target_t;
57*1c60b9acSAndroid Build Coastguard Worker 
58*1c60b9acSAndroid Build Coastguard Worker typedef struct {
59*1c60b9acSAndroid Build Coastguard Worker 	lws_dll2_owner_t	target_owner;
60*1c60b9acSAndroid Build Coastguard Worker 	struct gpiod_chip	*chip[16];
61*1c60b9acSAndroid Build Coastguard Worker 	struct lwsac		*ac_conf;
62*1c60b9acSAndroid Build Coastguard Worker 	int			port;
63*1c60b9acSAndroid Build Coastguard Worker 	const char		*iface;
64*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context	*ctx;
65*1c60b9acSAndroid Build Coastguard Worker } sai_jig_t;
66*1c60b9acSAndroid Build Coastguard Worker 
67*1c60b9acSAndroid Build Coastguard Worker /*
68*1c60b9acSAndroid Build Coastguard Worker  * We read the JSON config using lws_struct... instrument the related structures
69*1c60b9acSAndroid Build Coastguard Worker  */
70*1c60b9acSAndroid Build Coastguard Worker 
71*1c60b9acSAndroid Build Coastguard Worker static const lws_struct_map_t lsm_sai_jig_gpio[] = {
72*1c60b9acSAndroid Build Coastguard Worker 	LSM_UNSIGNED	(sai_jig_gpio_t, chip_idx,		"chip_idx"),
73*1c60b9acSAndroid Build Coastguard Worker 	LSM_UNSIGNED	(sai_jig_gpio_t, offset,		"offset"),
74*1c60b9acSAndroid Build Coastguard Worker 	LSM_UNSIGNED	(sai_jig_gpio_t, safe,			"safe"),
75*1c60b9acSAndroid Build Coastguard Worker 	LSM_STRING_PTR	(sai_jig_gpio_t, name,			"name"),
76*1c60b9acSAndroid Build Coastguard Worker 	LSM_STRING_PTR	(sai_jig_gpio_t, wire,			"wire"),
77*1c60b9acSAndroid Build Coastguard Worker };
78*1c60b9acSAndroid Build Coastguard Worker 
79*1c60b9acSAndroid Build Coastguard Worker static const lws_struct_map_t lsm_sai_jig_seq_item[] = {
80*1c60b9acSAndroid Build Coastguard Worker 	LSM_STRING_PTR	(sai_jig_seq_item_t, gpio_name,		"gpio_name"),
81*1c60b9acSAndroid Build Coastguard Worker 	LSM_UNSIGNED	(sai_jig_seq_item_t, value,		"value"),
82*1c60b9acSAndroid Build Coastguard Worker };
83*1c60b9acSAndroid Build Coastguard Worker 
84*1c60b9acSAndroid Build Coastguard Worker static const lws_struct_map_t lsm_sai_jig_sequence[] = {
85*1c60b9acSAndroid Build Coastguard Worker 	LSM_STRING_PTR	(sai_jig_sequence_t, name,		"name"),
86*1c60b9acSAndroid Build Coastguard Worker 	LSM_LIST	(sai_jig_sequence_t, seq_owner,
87*1c60b9acSAndroid Build Coastguard Worker 			 sai_jig_seq_item_t, list,
88*1c60b9acSAndroid Build Coastguard Worker 			 NULL, lsm_sai_jig_seq_item,		"seq"),
89*1c60b9acSAndroid Build Coastguard Worker };
90*1c60b9acSAndroid Build Coastguard Worker 
91*1c60b9acSAndroid Build Coastguard Worker static const lws_struct_map_t lsm_sai_jig_target[] = {
92*1c60b9acSAndroid Build Coastguard Worker 	LSM_STRING_PTR	(sai_jig_target_t, name,		"name"),
93*1c60b9acSAndroid Build Coastguard Worker 	LSM_LIST	(sai_jig_target_t, gpio_owner, sai_jig_gpio_t, list,
94*1c60b9acSAndroid Build Coastguard Worker 			 NULL, lsm_sai_jig_gpio,		"gpios"),
95*1c60b9acSAndroid Build Coastguard Worker 	LSM_LIST	(sai_jig_target_t, seq_owner, sai_jig_sequence_t, list,
96*1c60b9acSAndroid Build Coastguard Worker 			 NULL, lsm_sai_jig_sequence,		"sequences"),
97*1c60b9acSAndroid Build Coastguard Worker };
98*1c60b9acSAndroid Build Coastguard Worker 
99*1c60b9acSAndroid Build Coastguard Worker static const lws_struct_map_t lsm_sai_jig[] = {
100*1c60b9acSAndroid Build Coastguard Worker 	LSM_STRING_PTR	(sai_jig_t, iface,			"iface"),
101*1c60b9acSAndroid Build Coastguard Worker 	LSM_UNSIGNED	(sai_jig_t, port,			"port"),
102*1c60b9acSAndroid Build Coastguard Worker 	LSM_LIST	(sai_jig_t, target_owner, sai_jig_target_t, list,
103*1c60b9acSAndroid Build Coastguard Worker 			 NULL, lsm_sai_jig_target,		"targets"),
104*1c60b9acSAndroid Build Coastguard Worker };
105*1c60b9acSAndroid Build Coastguard Worker 
106*1c60b9acSAndroid Build Coastguard Worker static const lws_struct_map_t lsm_jig_schema[] = {
107*1c60b9acSAndroid Build Coastguard Worker         LSM_SCHEMA      (sai_jig_t, NULL, lsm_sai_jig,		"sai-jig"),
108*1c60b9acSAndroid Build Coastguard Worker };
109*1c60b9acSAndroid Build Coastguard Worker 
110*1c60b9acSAndroid Build Coastguard Worker static const char * const jig_conf =
111*1c60b9acSAndroid Build Coastguard Worker "{"
112*1c60b9acSAndroid Build Coastguard Worker 	"\"schema\":	\"sai-jig\","
113*1c60b9acSAndroid Build Coastguard Worker 	"\"port\":		44000,"
114*1c60b9acSAndroid Build Coastguard Worker 	"\"targets\":	["
115*1c60b9acSAndroid Build Coastguard Worker 		"{"
116*1c60b9acSAndroid Build Coastguard Worker 			"\"name\": \"linkit-7697-1\","
117*1c60b9acSAndroid Build Coastguard Worker                 	"\"gpios\": ["
118*1c60b9acSAndroid Build Coastguard Worker                 	        "{"
119*1c60b9acSAndroid Build Coastguard Worker 					"\"chip_index\":	0,"
120*1c60b9acSAndroid Build Coastguard Worker 					"\"name\":		\"nReset\","
121*1c60b9acSAndroid Build Coastguard Worker                                 	"\"offset\":	17,"
122*1c60b9acSAndroid Build Coastguard Worker                                 	"\"wire\":		\"RST\","
123*1c60b9acSAndroid Build Coastguard Worker 					"\"safe\":		0"
124*1c60b9acSAndroid Build Coastguard Worker 	                        "}, {"
125*1c60b9acSAndroid Build Coastguard Worker 					"\"name\":		\"usr\","
126*1c60b9acSAndroid Build Coastguard Worker 	                                "\"chip_index\":	0,"
127*1c60b9acSAndroid Build Coastguard Worker                                 	"\"offset\":	22,"
128*1c60b9acSAndroid Build Coastguard Worker                                 	"\"wire\":		\"P6\","
129*1c60b9acSAndroid Build Coastguard Worker 					"\"safe\":		0"
130*1c60b9acSAndroid Build Coastguard Worker 				"}"
131*1c60b9acSAndroid Build Coastguard Worker                         "], \"sequences\": ["
132*1c60b9acSAndroid Build Coastguard Worker                         	"{"
133*1c60b9acSAndroid Build Coastguard Worker 					"\"name\":		\"reset\","
134*1c60b9acSAndroid Build Coastguard Worker 					"\"seq\": ["
135*1c60b9acSAndroid Build Coastguard Worker 		                                "{ \"gpio_name\": \"nReset\", 	\"value\": 0 },"
136*1c60b9acSAndroid Build Coastguard Worker 		                                "{ \"gpio_name\": \"usr\",		\"value\": 0 },"
137*1c60b9acSAndroid Build Coastguard Worker 	        	                        "{				\"value\": 300 },"
138*1c60b9acSAndroid Build Coastguard Worker 		                                "{ \"gpio_name\": \"nReset\",	\"value\": 1 }"
139*1c60b9acSAndroid Build Coastguard Worker 					"]"
140*1c60b9acSAndroid Build Coastguard Worker                         	"}, {"
141*1c60b9acSAndroid Build Coastguard Worker 					"\"name\":		\"flash\","
142*1c60b9acSAndroid Build Coastguard Worker 					"\"seq\": ["
143*1c60b9acSAndroid Build Coastguard Worker 		                                "{ \"gpio_name\": \"nReset\",	\"value\": 0 },"
144*1c60b9acSAndroid Build Coastguard Worker 		                                "{ \"gpio_name\": \"usr\",		\"value\": 1 },"
145*1c60b9acSAndroid Build Coastguard Worker 	        	                        "{				\"value\": 300 },"
146*1c60b9acSAndroid Build Coastguard Worker 		                                "{ \"gpio_name\": \"nReset\",	\"value\": 1 },"
147*1c60b9acSAndroid Build Coastguard Worker 	        	                        "{				\"value\": 100 },"
148*1c60b9acSAndroid Build Coastguard Worker 		                                "{ \"gpio_name\": \"usr\",		\"value\": 0 }"
149*1c60b9acSAndroid Build Coastguard Worker 					"]"
150*1c60b9acSAndroid Build Coastguard Worker                         	"}"
151*1c60b9acSAndroid Build Coastguard Worker                 	"]"
152*1c60b9acSAndroid Build Coastguard Worker 		"}"
153*1c60b9acSAndroid Build Coastguard Worker 	"]"
154*1c60b9acSAndroid Build Coastguard Worker "}";
155*1c60b9acSAndroid Build Coastguard Worker 
156*1c60b9acSAndroid Build Coastguard Worker 
157*1c60b9acSAndroid Build Coastguard Worker 
158*1c60b9acSAndroid Build Coastguard Worker extern int test2(void);
159*1c60b9acSAndroid Build Coastguard Worker 
160*1c60b9acSAndroid Build Coastguard Worker /*
161*1c60b9acSAndroid Build Coastguard Worker  * in this example, the JSON is for one "builder" object, which may specify
162*1c60b9acSAndroid Build Coastguard Worker  * a child list "targets" of zero or more "target" objects.
163*1c60b9acSAndroid Build Coastguard Worker  */
164*1c60b9acSAndroid Build Coastguard Worker 
165*1c60b9acSAndroid Build Coastguard Worker static const char * const json_tests[] = {
166*1c60b9acSAndroid Build Coastguard Worker 	"{" /* test 1 */
167*1c60b9acSAndroid Build Coastguard Worker 		"\"schema\":\"com-warmcat-sai-builder\","
168*1c60b9acSAndroid Build Coastguard Worker 
169*1c60b9acSAndroid Build Coastguard Worker 		"\"hostname\":\"learn\","
170*1c60b9acSAndroid Build Coastguard Worker 		"\"nspawn_timeout\":1800,"
171*1c60b9acSAndroid Build Coastguard Worker 		"\"targets\":["
172*1c60b9acSAndroid Build Coastguard Worker 			"{"
173*1c60b9acSAndroid Build Coastguard Worker 				"\"name\":\"target1\","
174*1c60b9acSAndroid Build Coastguard Worker 				"\"someflag\":true"
175*1c60b9acSAndroid Build Coastguard Worker 			"},"
176*1c60b9acSAndroid Build Coastguard Worker 			"{"
177*1c60b9acSAndroid Build Coastguard Worker 				"\"name\":\"target2\","
178*1c60b9acSAndroid Build Coastguard Worker 				"\"someflag\":false"
179*1c60b9acSAndroid Build Coastguard Worker 			"}"
180*1c60b9acSAndroid Build Coastguard Worker 		"]"
181*1c60b9acSAndroid Build Coastguard Worker 	"}",
182*1c60b9acSAndroid Build Coastguard Worker 	"{" /* test 2 */
183*1c60b9acSAndroid Build Coastguard Worker 		"\"schema\":\"com-warmcat-sai-builder\","
184*1c60b9acSAndroid Build Coastguard Worker 
185*1c60b9acSAndroid Build Coastguard Worker 		"\"hostname\":\"learn\","
186*1c60b9acSAndroid Build Coastguard Worker 		"\"targets\":["
187*1c60b9acSAndroid Build Coastguard Worker 			"{"
188*1c60b9acSAndroid Build Coastguard Worker 				"\"name\":\"target1\""
189*1c60b9acSAndroid Build Coastguard Worker 			"},"
190*1c60b9acSAndroid Build Coastguard Worker 			"{"
191*1c60b9acSAndroid Build Coastguard Worker 				"\"name\":\"target2\""
192*1c60b9acSAndroid Build Coastguard Worker 			"},"
193*1c60b9acSAndroid Build Coastguard Worker 			"{"
194*1c60b9acSAndroid Build Coastguard Worker 				"\"name\":\"target3\""
195*1c60b9acSAndroid Build Coastguard Worker 			"}"
196*1c60b9acSAndroid Build Coastguard Worker 		"]"
197*1c60b9acSAndroid Build Coastguard Worker 	"}", "{" /* test 3 */
198*1c60b9acSAndroid Build Coastguard Worker 		"\"schema\":\"com-warmcat-sai-builder\","
199*1c60b9acSAndroid Build Coastguard Worker 
200*1c60b9acSAndroid Build Coastguard Worker 		"\"hostname\":\"learn\","
201*1c60b9acSAndroid Build Coastguard Worker 		"\"nspawn_timeout\":1800,"
202*1c60b9acSAndroid Build Coastguard Worker 		"\"targets\":["
203*1c60b9acSAndroid Build Coastguard Worker 			"{"
204*1c60b9acSAndroid Build Coastguard Worker 				"\"name\":\"target1\","
205*1c60b9acSAndroid Build Coastguard Worker 				"\"unrecognized\":\"xyz\","
206*1c60b9acSAndroid Build Coastguard Worker 				"\"child\": {"
207*1c60b9acSAndroid Build Coastguard Worker 					"\"somename\": \"abc\","
208*1c60b9acSAndroid Build Coastguard Worker 					"\"junk\": { \"x\": \"y\" }"
209*1c60b9acSAndroid Build Coastguard Worker 				"}"
210*1c60b9acSAndroid Build Coastguard Worker 			"},"
211*1c60b9acSAndroid Build Coastguard Worker 			"{"
212*1c60b9acSAndroid Build Coastguard Worker 				"\"name\":\"target2\""
213*1c60b9acSAndroid Build Coastguard Worker 			"}"
214*1c60b9acSAndroid Build Coastguard Worker 		"]"
215*1c60b9acSAndroid Build Coastguard Worker 	"}",
216*1c60b9acSAndroid Build Coastguard Worker 	"{" /* test 4 */
217*1c60b9acSAndroid Build Coastguard Worker 		"\"schema\":\"com-warmcat-sai-builder\","
218*1c60b9acSAndroid Build Coastguard Worker 
219*1c60b9acSAndroid Build Coastguard Worker 		"\"hostname\":\"learn\","
220*1c60b9acSAndroid Build Coastguard Worker 		"\"nspawn_timeout\":1800"
221*1c60b9acSAndroid Build Coastguard Worker 	"}",
222*1c60b9acSAndroid Build Coastguard Worker 	"{" /* test 5 */
223*1c60b9acSAndroid Build Coastguard Worker 		"\"schema\":\"com-warmcat-sai-builder\""
224*1c60b9acSAndroid Build Coastguard Worker 	"}",
225*1c60b9acSAndroid Build Coastguard Worker 	"{" /* test 6 ... check huge strings into smaller fixed char array */
226*1c60b9acSAndroid Build Coastguard Worker 		"\"schema\":\"com-warmcat-sai-builder\","
227*1c60b9acSAndroid Build Coastguard Worker 		"\"hostname\":\""
228*1c60b9acSAndroid Build Coastguard Worker 		"PYvtan6kqppjnS0KpYTCaiOLsJkc7XecAr1kcE0aCIciewYB+JcLG82mO1Vb1mJtjDwUjBxy2I6A"
229*1c60b9acSAndroid Build Coastguard Worker 		"zefzoWUWmqZbsv4MXR55j9bKlyz1liiSX63iO0x6JAwACMtE2MkgcLwR86TSWAD9D1QKIWqg5RJ/"
230*1c60b9acSAndroid Build Coastguard Worker 		"CRuVsW0DKAUMD52ql4JmPFuJpJgTq28z6PhYNzN3yI3bmQt6bzhA+A/xAsFzSBnb3MHYWzGMprr5"
231*1c60b9acSAndroid Build Coastguard Worker 		"3FAP1ISo5Ec9i+2ehV40sG6Q470sH3PGQZ0YRPO7Sh/SyrSQ/scONmxRc3AcXl7X/CSs417ii+CV"
232*1c60b9acSAndroid Build Coastguard Worker 		"8sq3ZgcxKNB7tNfN7idNx3upZ00G2BZy9jSy03cLKKLNaNUt0TQsxXbH55uDHzSEeZWvxJgT6zB1"
233*1c60b9acSAndroid Build Coastguard Worker 		"NoMhdC02w+oXim94M6z6COCnqT3rgkGk8PHMry9Bkh4yVpRmzIRfMmln/lEhdZgxky2+g5hhlSIG"
234*1c60b9acSAndroid Build Coastguard Worker 		"JYDCrdynD9kCfvfy6KGOpNIi1X+mhbbWn4lnL9ZKihL/RrfOV+oV4R26IDq+KqUiJBENeo8/GXkG"
235*1c60b9acSAndroid Build Coastguard Worker 		"LUH/87iPyzXKEMavr6fkrK0vTGto8yEYxmOyaVz8phG5rwf4jJgmYNoMbGo8gWvhqO7UAGy2g7MW"
236*1c60b9acSAndroid Build Coastguard Worker 		"v+B/t1eZZ+1euLsNrWAsFJiFbQKgdFfQT3RjB14iU8knlQ8usoy+pXssY2ddGJGVcGC21oZvstK9"
237*1c60b9acSAndroid Build Coastguard Worker 		"eu1eRZftda/wP+N5unT1Hw7kCoVzqxHieiYt47EGIOaaQ7XjZDK6qPN6O/grHnvJZm2vBkxuXgsY"
238*1c60b9acSAndroid Build Coastguard Worker 		"VkRQ7AuTWIecphqFsq7Wbc1YNbMW47SVU5zMD0WaCqbaaI0t4uIzRvPlD8cpiiTzFTrEHlIBTf8/"
239*1c60b9acSAndroid Build Coastguard Worker 		"uZjjEGGLhJR1jPqA9D1Ej3ChV+ye6F9JTUMlozRMsGuF8U4btDzH5xdnmvRS4Ar6LKEtAXGkj2yu"
240*1c60b9acSAndroid Build Coastguard Worker 		"yJln+v4RIWj2xOGPJovOqiXwi0FyM61f8U8gj0OiNA2/QlvrqQVDF7sMXgjvaE7iQt5vMETteZlx"
241*1c60b9acSAndroid Build Coastguard Worker 		"+z3f+jTFM/aon511W4+ZkRD+6AHwucvM9BEC\""
242*1c60b9acSAndroid Build Coastguard Worker 	"}",
243*1c60b9acSAndroid Build Coastguard Worker 	"{" /* test 7 ... check huge strings into char * */
244*1c60b9acSAndroid Build Coastguard Worker 		"\"schema\":\"com-warmcat-sai-builder\","
245*1c60b9acSAndroid Build Coastguard Worker 		"\"targets\":["
246*1c60b9acSAndroid Build Coastguard Worker 			"{"
247*1c60b9acSAndroid Build Coastguard Worker 				"\"name\":\""
248*1c60b9acSAndroid Build Coastguard Worker 		"PYvtan6kqppjnS0KpYTCaiOLsJkc7XecAr1kcE0aCIciewYB+JcLG82mO1Vb1mJtjDwUjBxy2I6A"
249*1c60b9acSAndroid Build Coastguard Worker 		"zefzoWUWmqZbsv4MXR55j9bKlyz1liiSX63iO0x6JAwACMtE2MkgcLwR86TSWAD9D1QKIWqg5RJ/"
250*1c60b9acSAndroid Build Coastguard Worker 		"CRuVsW0DKAUMD52ql4JmPFuJpJgTq28z6PhYNzN3yI3bmQt6bzhA+A/xAsFzSBnb3MHYWzGMprr5"
251*1c60b9acSAndroid Build Coastguard Worker 		"3FAP1ISo5Ec9i+2ehV40sG6Q470sH3PGQZ0YRPO7Sh/SyrSQ/scONmxRc3AcXl7X/CSs417ii+CV"
252*1c60b9acSAndroid Build Coastguard Worker 		"8sq3ZgcxKNB7tNfN7idNx3upZ00G2BZy9jSy03cLKKLNaNUt0TQsxXbH55uDHzSEeZWvxJgT6zB1"
253*1c60b9acSAndroid Build Coastguard Worker 		"NoMhdC02w+oXim94M6z6COCnqT3rgkGk8PHMry9Bkh4yVpRmzIRfMmln/lEhdZgxky2+g5hhlSIG"
254*1c60b9acSAndroid Build Coastguard Worker 		"JYDCrdynD9kCfvfy6KGOpNIi1X+mhbbWn4lnL9ZKihL/RrfOV+oV4R26IDq+KqUiJBENeo8/GXkG"
255*1c60b9acSAndroid Build Coastguard Worker 		"LUH/87iPyzXKEMavr6fkrK0vTGto8yEYxmOyaVz8phG5rwf4jJgmYNoMbGo8gWvhqO7UAGy2g7MW"
256*1c60b9acSAndroid Build Coastguard Worker 		"v+B/t1eZZ+1euLsNrWAsFJiFbQKgdFfQT3RjB14iU8knlQ8usoy+pXssY2ddGJGVcGC21oZvstK9"
257*1c60b9acSAndroid Build Coastguard Worker 		"eu1eRZftda/wP+N5unT1Hw7kCoVzqxHieiYt47EGIOaaQ7XjZDK6qPN6O/grHnvJZm2vBkxuXgsY"
258*1c60b9acSAndroid Build Coastguard Worker 		"VkRQ7AuTWIecphqFsq7Wbc1YNbMW47SVU5zMD0WaCqbaaI0t4uIzRvPlD8cpiiTzFTrEHlIBTf8/"
259*1c60b9acSAndroid Build Coastguard Worker 		"uZjjEGGLhJR1jPqA9D1Ej3ChV+ye6F9JTUMlozRMsGuF8U4btDzH5xdnmvRS4Ar6LKEtAXGkj2yu"
260*1c60b9acSAndroid Build Coastguard Worker 		"yJln+v4RIWj2xOGPJovOqiXwi0FyM61f8U8gj0OiNA2/QlvrqQVDF7sMXgjvaE7iQt5vMETteZlx"
261*1c60b9acSAndroid Build Coastguard Worker 		"+z3f+jTFM/aon511W4+ZkRD+6AHwucvM9BEC\"}]}"
262*1c60b9acSAndroid Build Coastguard Worker 	"}",
263*1c60b9acSAndroid Build Coastguard Worker 	"{" /* test 8 the "other" schema */
264*1c60b9acSAndroid Build Coastguard Worker 		"\"schema\":\"com-warmcat-sai-other\","
265*1c60b9acSAndroid Build Coastguard Worker 		"\"name\":\"somename\""
266*1c60b9acSAndroid Build Coastguard Worker 	"}",
267*1c60b9acSAndroid Build Coastguard Worker };
268*1c60b9acSAndroid Build Coastguard Worker 
269*1c60b9acSAndroid Build Coastguard Worker /*
270*1c60b9acSAndroid Build Coastguard Worker  * These are the expected outputs for each test, without pretty formatting.
271*1c60b9acSAndroid Build Coastguard Worker  *
272*1c60b9acSAndroid Build Coastguard Worker  * There are some differences to do with missing elements being rendered with
273*1c60b9acSAndroid Build Coastguard Worker  * default values.
274*1c60b9acSAndroid Build Coastguard Worker  */
275*1c60b9acSAndroid Build Coastguard Worker 
276*1c60b9acSAndroid Build Coastguard Worker static const char * const json_expected[] = {
277*1c60b9acSAndroid Build Coastguard Worker 	"{\"schema\":\"com-warmcat-sai-builder\",\"hostname\":\"learn\","
278*1c60b9acSAndroid Build Coastguard Worker 	  "\"nspawn_timeout\":1800,\"targets\":[{\"name\":\"target1\",\"someflag\":true},"
279*1c60b9acSAndroid Build Coastguard Worker 	  "{\"name\":\"target2\",\"someflag\":false}]}",
280*1c60b9acSAndroid Build Coastguard Worker 
281*1c60b9acSAndroid Build Coastguard Worker 	"{\"schema\":\"com-warmcat-sai-builder\",\"hostname\":\"learn\","
282*1c60b9acSAndroid Build Coastguard Worker 	 "\"nspawn_timeout\":0,\"targets\":[{\"name\":\"target1\",\"someflag\":false},"
283*1c60b9acSAndroid Build Coastguard Worker 	  "{\"name\":\"target2\",\"someflag\":false},{\"name\":\"target3\",\"someflag\":false}]}",
284*1c60b9acSAndroid Build Coastguard Worker 
285*1c60b9acSAndroid Build Coastguard Worker 	"{\"schema\":\"com-warmcat-sai-builder\",\"hostname\":\"learn\","
286*1c60b9acSAndroid Build Coastguard Worker 	"\"nspawn_timeout\":1800,\"targets\":[{\"name\":\"target1\",\"someflag\":false,"
287*1c60b9acSAndroid Build Coastguard Worker 	  "\"child\":{\"somename\":\"abc\"}},{\"name\":\"target2\",\"someflag\":false}]}",
288*1c60b9acSAndroid Build Coastguard Worker 
289*1c60b9acSAndroid Build Coastguard Worker 	"{\"schema\":\"com-warmcat-sai-builder\","
290*1c60b9acSAndroid Build Coastguard Worker 	  "\"hostname\":\"learn\",\"nspawn_timeout\":1800}",
291*1c60b9acSAndroid Build Coastguard Worker 
292*1c60b9acSAndroid Build Coastguard Worker 	"{\"schema\":\"com-warmcat-sai-builder\",\"hostname\":\"\","
293*1c60b9acSAndroid Build Coastguard Worker 	"\"nspawn_timeout\":0}",
294*1c60b9acSAndroid Build Coastguard Worker 
295*1c60b9acSAndroid Build Coastguard Worker 	"{\"schema\":\"com-warmcat-sai-builder\",\"hostname\":"
296*1c60b9acSAndroid Build Coastguard Worker 		"\"PYvtan6kqppjnS0KpYTCaiOLsJkc7Xe\","
297*1c60b9acSAndroid Build Coastguard Worker 	"\"nspawn_timeout\":0}",
298*1c60b9acSAndroid Build Coastguard Worker 
299*1c60b9acSAndroid Build Coastguard Worker 	"{\"schema\":\"com-warmcat-sai-builder\",\"hostname\":\"\","
300*1c60b9acSAndroid Build Coastguard Worker 	  "\"nspawn_timeout\":0,\"targets\":[{\"name\":\"PYvtan6kqppjnS0KpYTC"
301*1c60b9acSAndroid Build Coastguard Worker 		"aiOLsJkc7XecAr1kcE0aCIciewYB+JcLG82mO1Vb1mJtjDwUjBxy2I6Azefz"
302*1c60b9acSAndroid Build Coastguard Worker 		"oWUWmqZbsv4MXR55j9bKlyz1liiSX63iO0x6JAwACMtE2MkgcLwR86TSWAD9"
303*1c60b9acSAndroid Build Coastguard Worker 		"D1QKIWqg5RJ/CRuVsW0DKAUMD52ql4JmPFuJpJgTq28z6PhYNzN3yI3bmQt6"
304*1c60b9acSAndroid Build Coastguard Worker 		"bzhA+A/xAsFzSBnb3MHYWzGMprr53FAP1ISo5Ec9i+2ehV40sG6Q470sH3PG"
305*1c60b9acSAndroid Build Coastguard Worker 		"QZ0YRPO7Sh/SyrSQ/scONmxRc3AcXl7X/CSs417ii+CV8sq3ZgcxKNB7tNfN"
306*1c60b9acSAndroid Build Coastguard Worker 		"7idNx3upZ00G2BZy9jSy03cLKKLNaNUt0TQsxXbH55uDHzSEeZWvxJgT6zB1"
307*1c60b9acSAndroid Build Coastguard Worker 		"NoMhdC02w+oXim94M6z6COCnqT3rgkGk8PHMry9Bkh4yVpRmzIRfMmln/lEh"
308*1c60b9acSAndroid Build Coastguard Worker 		"dZgxky2+g5hhlSIGJYDCrdynD9kCfvfy6KGOpNIi1X+mhbbWn4lnL9ZKihL/"
309*1c60b9acSAndroid Build Coastguard Worker 		"RrfOV+oV4R26IDq+KqUiJBENeo8/GXkGLUH/87iPyzXKEMavr6fkrK0vTGto"
310*1c60b9acSAndroid Build Coastguard Worker 		"8yEYxmOyaVz8phG5rwf4jJgmYNoMbGo8gWvhqO7UAGy2g7MWv+B/t1eZZ+1e"
311*1c60b9acSAndroid Build Coastguard Worker 		"uLsNrWAsFJiFbQKgdFfQT3RjB14iU8knlQ8usoy+pXssY2ddGJGVcGC21oZv"
312*1c60b9acSAndroid Build Coastguard Worker 		"stK9eu1eRZftda/wP+N5unT1Hw7kCoVzqxHieiYt47EGIOaaQ7XjZDK6qPN6"
313*1c60b9acSAndroid Build Coastguard Worker 		"O/grHnvJZm2vBkxuXgsYVkRQ7AuTWIecphqFsq7Wbc1YNbMW47SVU5zMD0Wa"
314*1c60b9acSAndroid Build Coastguard Worker 		"CqbaaI0t4uIzRvPlD8cpiiTzFTrEHlIBTf8/uZjjEGGLhJR1jPqA9D1Ej3Ch"
315*1c60b9acSAndroid Build Coastguard Worker 		"V+ye6F9JTUMlozRMsGuF8U4btDzH5xdnmvRS4Ar6LKEtAXGkj2yuyJln+v4R"
316*1c60b9acSAndroid Build Coastguard Worker 		"IWj2xOGPJovOqiXwi0FyM61f8U8gj0OiNA2/QlvrqQVDF7sMXgjvaE7iQt5v"
317*1c60b9acSAndroid Build Coastguard Worker 		"METteZlx+z3f+jTFM/aon511W4+ZkRD+6AHwucvM9BEC\""
318*1c60b9acSAndroid Build Coastguard Worker 			",\"someflag\":false}]}",
319*1c60b9acSAndroid Build Coastguard Worker 	"{\"schema\":\"com-warmcat-sai-other\",\"name\":\"somename\"}"
320*1c60b9acSAndroid Build Coastguard Worker };
321*1c60b9acSAndroid Build Coastguard Worker 
322*1c60b9acSAndroid Build Coastguard Worker /*
323*1c60b9acSAndroid Build Coastguard Worker  * These annotate the members in the struct that will be serialized and
324*1c60b9acSAndroid Build Coastguard Worker  * deserialized with type and size information, as well as the name to use
325*1c60b9acSAndroid Build Coastguard Worker  * in the serialization format.
326*1c60b9acSAndroid Build Coastguard Worker  *
327*1c60b9acSAndroid Build Coastguard Worker  * Struct members that aren't annotated like this won't be serialized and
328*1c60b9acSAndroid Build Coastguard Worker  * when the struct is created during deserialiation, the will be set to 0
329*1c60b9acSAndroid Build Coastguard Worker  * or NULL.
330*1c60b9acSAndroid Build Coastguard Worker  */
331*1c60b9acSAndroid Build Coastguard Worker 
332*1c60b9acSAndroid Build Coastguard Worker /* child object */
333*1c60b9acSAndroid Build Coastguard Worker 
334*1c60b9acSAndroid Build Coastguard Worker typedef struct sai_child {
335*1c60b9acSAndroid Build Coastguard Worker 	const char *	somename;
336*1c60b9acSAndroid Build Coastguard Worker } sai_child_t;
337*1c60b9acSAndroid Build Coastguard Worker 
338*1c60b9acSAndroid Build Coastguard Worker lws_struct_map_t lsm_child[] = { /* describes serializable members */
339*1c60b9acSAndroid Build Coastguard Worker 	LSM_STRING_PTR	(sai_child_t, somename,			"somename"),
340*1c60b9acSAndroid Build Coastguard Worker };
341*1c60b9acSAndroid Build Coastguard Worker 
342*1c60b9acSAndroid Build Coastguard Worker /* target object */
343*1c60b9acSAndroid Build Coastguard Worker 
344*1c60b9acSAndroid Build Coastguard Worker typedef struct sai_target {
345*1c60b9acSAndroid Build Coastguard Worker 	struct lws_dll2 target_list;
346*1c60b9acSAndroid Build Coastguard Worker 	sai_child_t *		child;
347*1c60b9acSAndroid Build Coastguard Worker 
348*1c60b9acSAndroid Build Coastguard Worker 	const char *		name;
349*1c60b9acSAndroid Build Coastguard Worker 	char			someflag;
350*1c60b9acSAndroid Build Coastguard Worker } sai_target_t;
351*1c60b9acSAndroid Build Coastguard Worker 
352*1c60b9acSAndroid Build Coastguard Worker static const lws_struct_map_t lsm_target[] = {
353*1c60b9acSAndroid Build Coastguard Worker 	LSM_STRING_PTR	(sai_target_t, name,			"name"),
354*1c60b9acSAndroid Build Coastguard Worker 	LSM_BOOLEAN	(sai_target_t, someflag,		"someflag"),
355*1c60b9acSAndroid Build Coastguard Worker 	LSM_CHILD_PTR	(sai_target_t, child, sai_child_t,
356*1c60b9acSAndroid Build Coastguard Worker 			 NULL, lsm_child,			"child"),
357*1c60b9acSAndroid Build Coastguard Worker };
358*1c60b9acSAndroid Build Coastguard Worker 
359*1c60b9acSAndroid Build Coastguard Worker /* the first kind of struct / schema we can receive */
360*1c60b9acSAndroid Build Coastguard Worker 
361*1c60b9acSAndroid Build Coastguard Worker /* builder object */
362*1c60b9acSAndroid Build Coastguard Worker 
363*1c60b9acSAndroid Build Coastguard Worker typedef struct sai_builder {
364*1c60b9acSAndroid Build Coastguard Worker 	struct lws_dll2_owner	targets;
365*1c60b9acSAndroid Build Coastguard Worker 
366*1c60b9acSAndroid Build Coastguard Worker 	char 			hostname[32];
367*1c60b9acSAndroid Build Coastguard Worker 	unsigned int 		nspawn_timeout;
368*1c60b9acSAndroid Build Coastguard Worker } sai_builder_t;
369*1c60b9acSAndroid Build Coastguard Worker 
370*1c60b9acSAndroid Build Coastguard Worker static const lws_struct_map_t lsm_builder[] = {
371*1c60b9acSAndroid Build Coastguard Worker 	LSM_CARRAY	(sai_builder_t, hostname,		"hostname"),
372*1c60b9acSAndroid Build Coastguard Worker 	LSM_UNSIGNED	(sai_builder_t, nspawn_timeout,		"nspawn_timeout"),
373*1c60b9acSAndroid Build Coastguard Worker 	LSM_LIST	(sai_builder_t, targets,
374*1c60b9acSAndroid Build Coastguard Worker 			 sai_target_t, target_list,
375*1c60b9acSAndroid Build Coastguard Worker 			 NULL, lsm_target,			"targets"),
376*1c60b9acSAndroid Build Coastguard Worker };
377*1c60b9acSAndroid Build Coastguard Worker 
378*1c60b9acSAndroid Build Coastguard Worker /*
379*1c60b9acSAndroid Build Coastguard Worker  * the second kind of struct / schema we can receive
380*1c60b9acSAndroid Build Coastguard Worker  */
381*1c60b9acSAndroid Build Coastguard Worker 
382*1c60b9acSAndroid Build Coastguard Worker typedef struct sai_other {
383*1c60b9acSAndroid Build Coastguard Worker 	char 			name[32];
384*1c60b9acSAndroid Build Coastguard Worker } sai_other_t;
385*1c60b9acSAndroid Build Coastguard Worker 
386*1c60b9acSAndroid Build Coastguard Worker static const lws_struct_map_t lsm_other[] = {
387*1c60b9acSAndroid Build Coastguard Worker 	LSM_CARRAY	(sai_other_t, name,		"name"),
388*1c60b9acSAndroid Build Coastguard Worker };
389*1c60b9acSAndroid Build Coastguard Worker 
390*1c60b9acSAndroid Build Coastguard Worker /*
391*1c60b9acSAndroid Build Coastguard Worker  * meta composed pointers test
392*1c60b9acSAndroid Build Coastguard Worker  *
393*1c60b9acSAndroid Build Coastguard Worker  * We serialize a struct that consists of members that point to other objects,
394*1c60b9acSAndroid Build Coastguard Worker  * we expect this kind of thing
395*1c60b9acSAndroid Build Coastguard Worker  *
396*1c60b9acSAndroid Build Coastguard Worker  * {
397*1c60b9acSAndroid Build Coastguard Worker  *   "schema": "meta",
398*1c60b9acSAndroid Build Coastguard Worker  *   "t": { ... },
399*1c60b9acSAndroid Build Coastguard Worker  *   "e": { ...}
400*1c60b9acSAndroid Build Coastguard Worker  * }
401*1c60b9acSAndroid Build Coastguard Worker  */
402*1c60b9acSAndroid Build Coastguard Worker 
403*1c60b9acSAndroid Build Coastguard Worker typedef struct meta {
404*1c60b9acSAndroid Build Coastguard Worker 	sai_target_t	*t;
405*1c60b9acSAndroid Build Coastguard Worker 	sai_builder_t	*b;
406*1c60b9acSAndroid Build Coastguard Worker } meta_t;
407*1c60b9acSAndroid Build Coastguard Worker 
408*1c60b9acSAndroid Build Coastguard Worker static const lws_struct_map_t lsm_meta[] = {
409*1c60b9acSAndroid Build Coastguard Worker 	LSM_CHILD_PTR	(meta_t, t, sai_target_t, NULL, lsm_target, "t"),
410*1c60b9acSAndroid Build Coastguard Worker 	LSM_CHILD_PTR	(meta_t, b, sai_child_t, NULL, lsm_builder, "e"),
411*1c60b9acSAndroid Build Coastguard Worker };
412*1c60b9acSAndroid Build Coastguard Worker 
413*1c60b9acSAndroid Build Coastguard Worker static const lws_struct_map_t lsm_schema_meta[] = {
414*1c60b9acSAndroid Build Coastguard Worker 	LSM_SCHEMA	(meta_t, NULL, lsm_meta, "meta.schema"),
415*1c60b9acSAndroid Build Coastguard Worker };
416*1c60b9acSAndroid Build Coastguard Worker 
417*1c60b9acSAndroid Build Coastguard Worker /*
418*1c60b9acSAndroid Build Coastguard Worker  * Schema table
419*1c60b9acSAndroid Build Coastguard Worker  *
420*1c60b9acSAndroid Build Coastguard Worker  * Before we can understand the serialization top level format, we must read
421*1c60b9acSAndroid Build Coastguard Worker  * the schema, use the table below to create the right toplevel object for the
422*1c60b9acSAndroid Build Coastguard Worker  * schema name, and select the correct map tables to interpret the rest of the
423*1c60b9acSAndroid Build Coastguard Worker  * serialization.
424*1c60b9acSAndroid Build Coastguard Worker  *
425*1c60b9acSAndroid Build Coastguard Worker  * In this example there are two completely separate structs / schemas possible
426*1c60b9acSAndroid Build Coastguard Worker  * to receive, and we disambiguate and create the correct one using the schema
427*1c60b9acSAndroid Build Coastguard Worker  * JSON node.
428*1c60b9acSAndroid Build Coastguard Worker  *
429*1c60b9acSAndroid Build Coastguard Worker  * Therefore the schema table below is the starting point for the JSON
430*1c60b9acSAndroid Build Coastguard Worker  * deserialization.
431*1c60b9acSAndroid Build Coastguard Worker  */
432*1c60b9acSAndroid Build Coastguard Worker 
433*1c60b9acSAndroid Build Coastguard Worker static const lws_struct_map_t lsm_schema_map[] = {
434*1c60b9acSAndroid Build Coastguard Worker 	LSM_SCHEMA	(sai_builder_t, NULL,
435*1c60b9acSAndroid Build Coastguard Worker 			 lsm_builder,		"com-warmcat-sai-builder"),
436*1c60b9acSAndroid Build Coastguard Worker 	LSM_SCHEMA	(sai_other_t, NULL,
437*1c60b9acSAndroid Build Coastguard Worker 			 lsm_other,		"com-warmcat-sai-other"),
438*1c60b9acSAndroid Build Coastguard Worker };
439*1c60b9acSAndroid Build Coastguard Worker 
440*1c60b9acSAndroid Build Coastguard Worker typedef struct sai_cancel {
441*1c60b9acSAndroid Build Coastguard Worker 	char task_uuid[65];
442*1c60b9acSAndroid Build Coastguard Worker } sai_cancel_t;
443*1c60b9acSAndroid Build Coastguard Worker 
444*1c60b9acSAndroid Build Coastguard Worker const lws_struct_map_t lsm_task_cancel[] = {
445*1c60b9acSAndroid Build Coastguard Worker 	LSM_CARRAY	(sai_cancel_t, task_uuid,	 "uuid"),
446*1c60b9acSAndroid Build Coastguard Worker };
447*1c60b9acSAndroid Build Coastguard Worker 
448*1c60b9acSAndroid Build Coastguard Worker static const lws_struct_map_t t2_map[] = {
449*1c60b9acSAndroid Build Coastguard Worker 	LSM_SCHEMA	(sai_cancel_t, NULL, lsm_task_cancel,
450*1c60b9acSAndroid Build Coastguard Worker 					      "com.warmcat.sai.taskinfo"),
451*1c60b9acSAndroid Build Coastguard Worker 	LSM_SCHEMA	(sai_cancel_t, NULL, lsm_task_cancel,
452*1c60b9acSAndroid Build Coastguard Worker 					      "com.warmcat.sai.eventinfo"),
453*1c60b9acSAndroid Build Coastguard Worker 	LSM_SCHEMA	(sai_cancel_t, NULL, lsm_task_cancel,
454*1c60b9acSAndroid Build Coastguard Worker 			/* shares struct */   "com.warmcat.sai.taskreset"),
455*1c60b9acSAndroid Build Coastguard Worker 	LSM_SCHEMA	(sai_cancel_t, NULL, lsm_task_cancel,
456*1c60b9acSAndroid Build Coastguard Worker 			/* shares struct */   "com.warmcat.sai.eventreset"),
457*1c60b9acSAndroid Build Coastguard Worker 	LSM_SCHEMA	(sai_cancel_t, NULL, lsm_task_cancel,
458*1c60b9acSAndroid Build Coastguard Worker 			/* shares struct */   "com.warmcat.sai.eventdelete"),
459*1c60b9acSAndroid Build Coastguard Worker 	LSM_SCHEMA	(sai_cancel_t,		 NULL, lsm_task_cancel,
460*1c60b9acSAndroid Build Coastguard Worker 					      "com.warmcat.sai.taskcan"),
461*1c60b9acSAndroid Build Coastguard Worker };
462*1c60b9acSAndroid Build Coastguard Worker 
463*1c60b9acSAndroid Build Coastguard Worker static const char *t2 =
464*1c60b9acSAndroid Build Coastguard Worker 	"{\"schema\":\"com.warmcat.sai.taskcan\","
465*1c60b9acSAndroid Build Coastguard Worker 	 "\"uuid\": \"071ab46ab4296e5de674c628fec17c55088254679f7714ad991f8c4873dca\"}\x01\x02\xff\xff\xff\xff";
466*1c60b9acSAndroid Build Coastguard Worker 
467*1c60b9acSAndroid Build Coastguard Worker typedef struct xlws_wifi_creds {
468*1c60b9acSAndroid Build Coastguard Worker 	lws_dll2_t	list;
469*1c60b9acSAndroid Build Coastguard Worker 	char 		ssid[33];
470*1c60b9acSAndroid Build Coastguard Worker 	char		passphrase[64];
471*1c60b9acSAndroid Build Coastguard Worker 	int		alg;
472*1c60b9acSAndroid Build Coastguard Worker 	char		bssid[6];
473*1c60b9acSAndroid Build Coastguard Worker } xlws_wifi_creds_t;
474*1c60b9acSAndroid Build Coastguard Worker 
475*1c60b9acSAndroid Build Coastguard Worker typedef struct xlws_netdevs {
476*1c60b9acSAndroid Build Coastguard Worker 	lws_dll2_owner_t	owner_creds;
477*1c60b9acSAndroid Build Coastguard Worker } xlws_netdevs_t;
478*1c60b9acSAndroid Build Coastguard Worker 
479*1c60b9acSAndroid Build Coastguard Worker static const lws_struct_map_t lsm_wifi_creds[] = {
480*1c60b9acSAndroid Build Coastguard Worker 	LSM_CARRAY	(xlws_wifi_creds_t, ssid,		"ssid"),
481*1c60b9acSAndroid Build Coastguard Worker 	LSM_CARRAY	(xlws_wifi_creds_t, passphrase,		"passphrase"),
482*1c60b9acSAndroid Build Coastguard Worker 	LSM_UNSIGNED	(xlws_wifi_creds_t, alg,			"alg"),
483*1c60b9acSAndroid Build Coastguard Worker 	LSM_STRING_PTR	(xlws_wifi_creds_t, bssid,		"bssid"),
484*1c60b9acSAndroid Build Coastguard Worker };
485*1c60b9acSAndroid Build Coastguard Worker 
486*1c60b9acSAndroid Build Coastguard Worker static const lws_struct_map_t lsm_netdev_credentials[] = {
487*1c60b9acSAndroid Build Coastguard Worker 	LSM_LIST	(xlws_netdevs_t, owner_creds, xlws_wifi_creds_t, list,
488*1c60b9acSAndroid Build Coastguard Worker 			 NULL, lsm_wifi_creds,			"credentials"),
489*1c60b9acSAndroid Build Coastguard Worker };
490*1c60b9acSAndroid Build Coastguard Worker 
491*1c60b9acSAndroid Build Coastguard Worker static const lws_struct_map_t lsm_netdev_schema[] = {
492*1c60b9acSAndroid Build Coastguard Worker 	LSM_SCHEMA	(xlws_netdevs_t, NULL, lsm_netdev_credentials,
493*1c60b9acSAndroid Build Coastguard Worker 					      "com.warmcat.sai.taskinfo"),
494*1c60b9acSAndroid Build Coastguard Worker };
495*1c60b9acSAndroid Build Coastguard Worker 
496*1c60b9acSAndroid Build Coastguard Worker 
497*1c60b9acSAndroid Build Coastguard Worker static int
show_target(struct lws_dll2 * d,void * user)498*1c60b9acSAndroid Build Coastguard Worker show_target(struct lws_dll2 *d, void *user)
499*1c60b9acSAndroid Build Coastguard Worker {
500*1c60b9acSAndroid Build Coastguard Worker 	sai_target_t *t = lws_container_of(d, sai_target_t, target_list);
501*1c60b9acSAndroid Build Coastguard Worker 
502*1c60b9acSAndroid Build Coastguard Worker 	lwsl_notice("    target.name '%s' (target %p)\n", t->name, t);
503*1c60b9acSAndroid Build Coastguard Worker 
504*1c60b9acSAndroid Build Coastguard Worker 	if (t->child)
505*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("      child %p, target.child.somename '%s'\n",
506*1c60b9acSAndroid Build Coastguard Worker 			  t->child, t->child->somename);
507*1c60b9acSAndroid Build Coastguard Worker 
508*1c60b9acSAndroid Build Coastguard Worker 	return 0;
509*1c60b9acSAndroid Build Coastguard Worker }
510*1c60b9acSAndroid Build Coastguard Worker 
511*1c60b9acSAndroid Build Coastguard Worker 
main(int argc,const char ** argv)512*1c60b9acSAndroid Build Coastguard Worker int main(int argc, const char **argv)
513*1c60b9acSAndroid Build Coastguard Worker {
514*1c60b9acSAndroid Build Coastguard Worker 	int n, m, e = 0, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE;
515*1c60b9acSAndroid Build Coastguard Worker #if 1
516*1c60b9acSAndroid Build Coastguard Worker 	lws_struct_serialize_t *ser;
517*1c60b9acSAndroid Build Coastguard Worker 	uint8_t buf[4096];
518*1c60b9acSAndroid Build Coastguard Worker 	size_t written;
519*1c60b9acSAndroid Build Coastguard Worker #endif
520*1c60b9acSAndroid Build Coastguard Worker 	struct lejp_ctx ctx;
521*1c60b9acSAndroid Build Coastguard Worker 	lws_struct_args_t a;
522*1c60b9acSAndroid Build Coastguard Worker 	sai_builder_t *b, mb;
523*1c60b9acSAndroid Build Coastguard Worker 	sai_target_t mt;
524*1c60b9acSAndroid Build Coastguard Worker 	sai_other_t *o;
525*1c60b9acSAndroid Build Coastguard Worker 	const char *p;
526*1c60b9acSAndroid Build Coastguard Worker 	meta_t meta;
527*1c60b9acSAndroid Build Coastguard Worker 
528*1c60b9acSAndroid Build Coastguard Worker 	if ((p = lws_cmdline_option(argc, argv, "-d")))
529*1c60b9acSAndroid Build Coastguard Worker 		logs = atoi(p);
530*1c60b9acSAndroid Build Coastguard Worker 
531*1c60b9acSAndroid Build Coastguard Worker 	lws_set_log_level(logs, NULL);
532*1c60b9acSAndroid Build Coastguard Worker 	lwsl_user("LWS API selftest: lws_struct JSON\n");
533*1c60b9acSAndroid Build Coastguard Worker 
534*1c60b9acSAndroid Build Coastguard Worker 	for (m = 0; m < (int)LWS_ARRAY_SIZE(json_tests); m++) {
535*1c60b9acSAndroid Build Coastguard Worker 
536*1c60b9acSAndroid Build Coastguard Worker 		/* 1. deserialize the canned JSON into structs */
537*1c60b9acSAndroid Build Coastguard Worker 
538*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: ++++++++++++++++ test %d\n", __func__, m + 1);
539*1c60b9acSAndroid Build Coastguard Worker 
540*1c60b9acSAndroid Build Coastguard Worker 		memset(&a, 0, sizeof(a));
541*1c60b9acSAndroid Build Coastguard Worker 		a.map_st[0] = lsm_schema_map;
542*1c60b9acSAndroid Build Coastguard Worker 		a.map_entries_st[0] = LWS_ARRAY_SIZE(lsm_schema_map);
543*1c60b9acSAndroid Build Coastguard Worker 		a.ac_block_size = 512;
544*1c60b9acSAndroid Build Coastguard Worker 
545*1c60b9acSAndroid Build Coastguard Worker 		lws_struct_json_init_parse(&ctx, NULL, &a);
546*1c60b9acSAndroid Build Coastguard Worker 		n = lejp_parse(&ctx, (uint8_t *)json_tests[m],
547*1c60b9acSAndroid Build Coastguard Worker 						 (int)strlen(json_tests[m]));
548*1c60b9acSAndroid Build Coastguard Worker 		if (n < 0) {
549*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: notification JSON decode failed '%s'\n",
550*1c60b9acSAndroid Build Coastguard Worker 					__func__, lejp_error_to_string(n));
551*1c60b9acSAndroid Build Coastguard Worker 			e++;
552*1c60b9acSAndroid Build Coastguard Worker 			goto done;
553*1c60b9acSAndroid Build Coastguard Worker 		}
554*1c60b9acSAndroid Build Coastguard Worker 		lwsac_info(a.ac);
555*1c60b9acSAndroid Build Coastguard Worker 
556*1c60b9acSAndroid Build Coastguard Worker 		if (m + 1 != 8) {
557*1c60b9acSAndroid Build Coastguard Worker 			b = a.dest;
558*1c60b9acSAndroid Build Coastguard Worker 			if (!b) {
559*1c60b9acSAndroid Build Coastguard Worker 				lwsl_err("%s: didn't produce any output\n", __func__);
560*1c60b9acSAndroid Build Coastguard Worker 				e++;
561*1c60b9acSAndroid Build Coastguard Worker 				goto done;
562*1c60b9acSAndroid Build Coastguard Worker 			}
563*1c60b9acSAndroid Build Coastguard Worker 
564*1c60b9acSAndroid Build Coastguard Worker 			if (a.top_schema_index) {
565*1c60b9acSAndroid Build Coastguard Worker 				lwsl_err("%s: wrong top_schema_index\n", __func__);
566*1c60b9acSAndroid Build Coastguard Worker 				e++;
567*1c60b9acSAndroid Build Coastguard Worker 				goto done;
568*1c60b9acSAndroid Build Coastguard Worker 			}
569*1c60b9acSAndroid Build Coastguard Worker 
570*1c60b9acSAndroid Build Coastguard Worker 			lwsl_notice("builder.hostname = '%s', timeout = %d, targets (%d)\n",
571*1c60b9acSAndroid Build Coastguard Worker 				    b->hostname, b->nspawn_timeout,
572*1c60b9acSAndroid Build Coastguard Worker 				    b->targets.count);
573*1c60b9acSAndroid Build Coastguard Worker 
574*1c60b9acSAndroid Build Coastguard Worker 			lws_dll2_foreach_safe(&b->targets, NULL, show_target);
575*1c60b9acSAndroid Build Coastguard Worker 		} else {
576*1c60b9acSAndroid Build Coastguard Worker 			o = a.dest;
577*1c60b9acSAndroid Build Coastguard Worker 			if (!o) {
578*1c60b9acSAndroid Build Coastguard Worker 				lwsl_err("%s: didn't produce any output\n", __func__);
579*1c60b9acSAndroid Build Coastguard Worker 				e++;
580*1c60b9acSAndroid Build Coastguard Worker 				goto done;
581*1c60b9acSAndroid Build Coastguard Worker 			}
582*1c60b9acSAndroid Build Coastguard Worker 
583*1c60b9acSAndroid Build Coastguard Worker 			if (a.top_schema_index != 1) {
584*1c60b9acSAndroid Build Coastguard Worker 				lwsl_err("%s: wrong top_schema_index\n", __func__);
585*1c60b9acSAndroid Build Coastguard Worker 				e++;
586*1c60b9acSAndroid Build Coastguard Worker 				goto done;
587*1c60b9acSAndroid Build Coastguard Worker 			}
588*1c60b9acSAndroid Build Coastguard Worker 
589*1c60b9acSAndroid Build Coastguard Worker 			lwsl_notice("other.name = '%s'\n", o->name);
590*1c60b9acSAndroid Build Coastguard Worker 		}
591*1c60b9acSAndroid Build Coastguard Worker 
592*1c60b9acSAndroid Build Coastguard Worker 		/* 2. serialize the structs into JSON and confirm */
593*1c60b9acSAndroid Build Coastguard Worker 
594*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s:    .... strarting serialization of test %d\n",
595*1c60b9acSAndroid Build Coastguard Worker 				__func__, m + 1);
596*1c60b9acSAndroid Build Coastguard Worker 
597*1c60b9acSAndroid Build Coastguard Worker 		if (m + 1 != 8) {
598*1c60b9acSAndroid Build Coastguard Worker 			ser = lws_struct_json_serialize_create(lsm_schema_map,
599*1c60b9acSAndroid Build Coastguard Worker 						LWS_ARRAY_SIZE(lsm_schema_map),
600*1c60b9acSAndroid Build Coastguard Worker 						       0//LSSERJ_FLAG_PRETTY
601*1c60b9acSAndroid Build Coastguard Worker 						       , b);
602*1c60b9acSAndroid Build Coastguard Worker 		} else {
603*1c60b9acSAndroid Build Coastguard Worker 			ser = lws_struct_json_serialize_create(&lsm_schema_map[1],
604*1c60b9acSAndroid Build Coastguard Worker 						1,
605*1c60b9acSAndroid Build Coastguard Worker 						       0//LSSERJ_FLAG_PRETTY
606*1c60b9acSAndroid Build Coastguard Worker 						       , o);
607*1c60b9acSAndroid Build Coastguard Worker 		}
608*1c60b9acSAndroid Build Coastguard Worker 		if (!ser) {
609*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: unable to init serialization\n", __func__);
610*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
611*1c60b9acSAndroid Build Coastguard Worker 		}
612*1c60b9acSAndroid Build Coastguard Worker 
613*1c60b9acSAndroid Build Coastguard Worker 		do {
614*1c60b9acSAndroid Build Coastguard Worker 			n = (int)lws_struct_json_serialize(ser, buf, sizeof(buf),
615*1c60b9acSAndroid Build Coastguard Worker 						      &written);
616*1c60b9acSAndroid Build Coastguard Worker 			switch (n) {
617*1c60b9acSAndroid Build Coastguard Worker 			case LSJS_RESULT_FINISH:
618*1c60b9acSAndroid Build Coastguard Worker 				puts((const char *)buf);
619*1c60b9acSAndroid Build Coastguard Worker 				break;
620*1c60b9acSAndroid Build Coastguard Worker 			case LSJS_RESULT_CONTINUE:
621*1c60b9acSAndroid Build Coastguard Worker 			case LSJS_RESULT_ERROR:
622*1c60b9acSAndroid Build Coastguard Worker 				goto bail;
623*1c60b9acSAndroid Build Coastguard Worker 			}
624*1c60b9acSAndroid Build Coastguard Worker 		} while(n == LSJS_RESULT_CONTINUE);
625*1c60b9acSAndroid Build Coastguard Worker 
626*1c60b9acSAndroid Build Coastguard Worker 		if (strcmp(json_expected[m], (char *)buf)) {
627*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: test %d: expected %s\n", __func__, m + 1,
628*1c60b9acSAndroid Build Coastguard Worker 					json_expected[m]);
629*1c60b9acSAndroid Build Coastguard Worker 			e++;
630*1c60b9acSAndroid Build Coastguard Worker 			goto done;
631*1c60b9acSAndroid Build Coastguard Worker 		}
632*1c60b9acSAndroid Build Coastguard Worker 
633*1c60b9acSAndroid Build Coastguard Worker 		lws_struct_json_serialize_destroy(&ser);
634*1c60b9acSAndroid Build Coastguard Worker 
635*1c60b9acSAndroid Build Coastguard Worker done:
636*1c60b9acSAndroid Build Coastguard Worker 		lwsac_free(&a.ac);
637*1c60b9acSAndroid Build Coastguard Worker 	}
638*1c60b9acSAndroid Build Coastguard Worker 
639*1c60b9acSAndroid Build Coastguard Worker 	if (e)
640*1c60b9acSAndroid Build Coastguard Worker 		goto bail;
641*1c60b9acSAndroid Build Coastguard Worker 
642*1c60b9acSAndroid Build Coastguard Worker 	/* ad-hoc tests */
643*1c60b9acSAndroid Build Coastguard Worker 
644*1c60b9acSAndroid Build Coastguard Worker 	memset(&meta, 0, sizeof(meta));
645*1c60b9acSAndroid Build Coastguard Worker 	memset(&mb, 0, sizeof(mb));
646*1c60b9acSAndroid Build Coastguard Worker 	memset(&mt, 0, sizeof(mt));
647*1c60b9acSAndroid Build Coastguard Worker 
648*1c60b9acSAndroid Build Coastguard Worker 	meta.t = &mt;
649*1c60b9acSAndroid Build Coastguard Worker 	meta.b = &mb;
650*1c60b9acSAndroid Build Coastguard Worker 
651*1c60b9acSAndroid Build Coastguard Worker 	meta.t->name = "mytargetname";
652*1c60b9acSAndroid Build Coastguard Worker 	lws_strncpy(meta.b->hostname, "myhostname", sizeof(meta.b->hostname));
653*1c60b9acSAndroid Build Coastguard Worker 	ser = lws_struct_json_serialize_create(lsm_schema_meta, 1, 0,
654*1c60b9acSAndroid Build Coastguard Worker 					       &meta);
655*1c60b9acSAndroid Build Coastguard Worker 	if (!ser) {
656*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: failed to create json\n", __func__);
657*1c60b9acSAndroid Build Coastguard Worker 
658*1c60b9acSAndroid Build Coastguard Worker 
659*1c60b9acSAndroid Build Coastguard Worker 	}
660*1c60b9acSAndroid Build Coastguard Worker 	do {
661*1c60b9acSAndroid Build Coastguard Worker 		n = (int)lws_struct_json_serialize(ser, buf, sizeof(buf), &written);
662*1c60b9acSAndroid Build Coastguard Worker 		switch (n) {
663*1c60b9acSAndroid Build Coastguard Worker 		case LSJS_RESULT_CONTINUE:
664*1c60b9acSAndroid Build Coastguard Worker 		case LSJS_RESULT_FINISH:
665*1c60b9acSAndroid Build Coastguard Worker 			puts((const char *)buf);
666*1c60b9acSAndroid Build Coastguard Worker 			if (strcmp((const char *)buf,
667*1c60b9acSAndroid Build Coastguard Worker 				"{\"schema\":\"meta.schema\","
668*1c60b9acSAndroid Build Coastguard Worker 				"\"t\":{\"name\":\"mytargetname\","
669*1c60b9acSAndroid Build Coastguard Worker 					"\"someflag\":false},"
670*1c60b9acSAndroid Build Coastguard Worker 				"\"e\":{\"hostname\":\"myhostname\","
671*1c60b9acSAndroid Build Coastguard Worker 					"\"nspawn_timeout\":0}}")) {
672*1c60b9acSAndroid Build Coastguard Worker 				lwsl_err("%s: meta test fail\n", __func__);
673*1c60b9acSAndroid Build Coastguard Worker 				goto bail;
674*1c60b9acSAndroid Build Coastguard Worker 			}
675*1c60b9acSAndroid Build Coastguard Worker 			break;
676*1c60b9acSAndroid Build Coastguard Worker 		case LSJS_RESULT_ERROR:
677*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
678*1c60b9acSAndroid Build Coastguard Worker 		}
679*1c60b9acSAndroid Build Coastguard Worker 	} while(n == LSJS_RESULT_CONTINUE);
680*1c60b9acSAndroid Build Coastguard Worker 
681*1c60b9acSAndroid Build Coastguard Worker 	lws_struct_json_serialize_destroy(&ser);
682*1c60b9acSAndroid Build Coastguard Worker 
683*1c60b9acSAndroid Build Coastguard Worker 	lwsl_notice("Test set 2\n");
684*1c60b9acSAndroid Build Coastguard Worker 
685*1c60b9acSAndroid Build Coastguard Worker 	memset(&a, 0, sizeof(a));
686*1c60b9acSAndroid Build Coastguard Worker 	a.map_st[0] = t2_map;
687*1c60b9acSAndroid Build Coastguard Worker 	a.map_entries_st[0] = LWS_ARRAY_SIZE(t2_map);
688*1c60b9acSAndroid Build Coastguard Worker 	a.ac_block_size = 128;
689*1c60b9acSAndroid Build Coastguard Worker 
690*1c60b9acSAndroid Build Coastguard Worker 	lws_struct_json_init_parse(&ctx, NULL, &a);
691*1c60b9acSAndroid Build Coastguard Worker 	m = lejp_parse(&ctx, (uint8_t *)t2, (int)strlen(t2));
692*1c60b9acSAndroid Build Coastguard Worker 	if (m < 0 || !a.dest) {
693*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: notification JSON decode failed '%s'\n",
694*1c60b9acSAndroid Build Coastguard Worker 				__func__, lejp_error_to_string(m));
695*1c60b9acSAndroid Build Coastguard Worker 		goto bail;
696*1c60b9acSAndroid Build Coastguard Worker 	}
697*1c60b9acSAndroid Build Coastguard Worker 
698*1c60b9acSAndroid Build Coastguard Worker 	lwsl_notice("Test set 2: %d: %s\n", m,
699*1c60b9acSAndroid Build Coastguard Worker 			((sai_cancel_t *)a.dest)->task_uuid);
700*1c60b9acSAndroid Build Coastguard Worker 
701*1c60b9acSAndroid Build Coastguard Worker 	lwsac_free(&a.ac);
702*1c60b9acSAndroid Build Coastguard Worker 
703*1c60b9acSAndroid Build Coastguard Worker 	if (test2())
704*1c60b9acSAndroid Build Coastguard Worker 		goto bail;
705*1c60b9acSAndroid Build Coastguard Worker 
706*1c60b9acSAndroid Build Coastguard Worker 	{
707*1c60b9acSAndroid Build Coastguard Worker 		lws_struct_serialize_t *js;
708*1c60b9acSAndroid Build Coastguard Worker 		xlws_wifi_creds_t creds;
709*1c60b9acSAndroid Build Coastguard Worker 		xlws_netdevs_t netdevs;
710*1c60b9acSAndroid Build Coastguard Worker 		unsigned char *buf;
711*1c60b9acSAndroid Build Coastguard Worker 		size_t w;
712*1c60b9acSAndroid Build Coastguard Worker 		int n;
713*1c60b9acSAndroid Build Coastguard Worker 
714*1c60b9acSAndroid Build Coastguard Worker 		memset(&creds, 0, sizeof(creds));
715*1c60b9acSAndroid Build Coastguard Worker 		memset(&netdevs, 0, sizeof(netdevs));
716*1c60b9acSAndroid Build Coastguard Worker 
717*1c60b9acSAndroid Build Coastguard Worker 		lws_strncpy(creds.ssid, "xxx", sizeof(creds.ssid));
718*1c60b9acSAndroid Build Coastguard Worker 		lws_strncpy(creds.passphrase, "yyy", sizeof(creds.passphrase));
719*1c60b9acSAndroid Build Coastguard Worker 		lws_dll2_add_tail(&creds.list, &netdevs.owner_creds);
720*1c60b9acSAndroid Build Coastguard Worker 
721*1c60b9acSAndroid Build Coastguard Worker 		buf = malloc(2048); /* length should be computed */
722*1c60b9acSAndroid Build Coastguard Worker 
723*1c60b9acSAndroid Build Coastguard Worker 		js = lws_struct_json_serialize_create(lsm_netdev_schema,
724*1c60b9acSAndroid Build Coastguard Worker 			LWS_ARRAY_SIZE(lsm_netdev_schema), 0, &netdevs);
725*1c60b9acSAndroid Build Coastguard Worker 		if (!js)
726*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
727*1c60b9acSAndroid Build Coastguard Worker 
728*1c60b9acSAndroid Build Coastguard Worker 		n = (int)lws_struct_json_serialize(js, buf, 2048, &w);
729*1c60b9acSAndroid Build Coastguard Worker 		lws_struct_json_serialize_destroy(&js);
730*1c60b9acSAndroid Build Coastguard Worker 		if (n != LSJS_RESULT_FINISH)
731*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
732*1c60b9acSAndroid Build Coastguard Worker 		if (strcmp("{\"schema\":\"com.warmcat.sai.taskinfo\",\"credentials\":[{\"ssid\":\"xxx\",\"passphrase\":\"yyy\",\"alg\":0}]}", (const char *)buf)) {
733*1c60b9acSAndroid Build Coastguard Worker 			puts((const char *)buf);
734*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
735*1c60b9acSAndroid Build Coastguard Worker 		}
736*1c60b9acSAndroid Build Coastguard Worker 		free(buf);
737*1c60b9acSAndroid Build Coastguard Worker 	}
738*1c60b9acSAndroid Build Coastguard Worker 
739*1c60b9acSAndroid Build Coastguard Worker 	{
740*1c60b9acSAndroid Build Coastguard Worker 		struct x { lws_dll2_t list; const char *sz; };
741*1c60b9acSAndroid Build Coastguard Worker 		struct x x1, x2, *xp;
742*1c60b9acSAndroid Build Coastguard Worker 		lws_dll2_owner_t o;
743*1c60b9acSAndroid Build Coastguard Worker 
744*1c60b9acSAndroid Build Coastguard Worker 		lws_dll2_owner_clear(&o);
745*1c60b9acSAndroid Build Coastguard Worker 		memset(&x1, 0, sizeof(x1));
746*1c60b9acSAndroid Build Coastguard Worker 		memset(&x2, 0, sizeof(x2));
747*1c60b9acSAndroid Build Coastguard Worker 
748*1c60b9acSAndroid Build Coastguard Worker 		x1.sz = "nope";
749*1c60b9acSAndroid Build Coastguard Worker 		x2.sz = "yes";
750*1c60b9acSAndroid Build Coastguard Worker 
751*1c60b9acSAndroid Build Coastguard Worker 		lws_dll2_add_tail(&x1.list, &o);
752*1c60b9acSAndroid Build Coastguard Worker 		lws_dll2_add_tail(&x2.list, &o);
753*1c60b9acSAndroid Build Coastguard Worker 
754*1c60b9acSAndroid Build Coastguard Worker 		xp = lws_dll2_search_sz_pl(&o, "yes", 3, struct x, list, sz);
755*1c60b9acSAndroid Build Coastguard Worker 		if (xp != &x2) {
756*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: 1 xp %p\n", __func__, xp);
757*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
758*1c60b9acSAndroid Build Coastguard Worker 		}
759*1c60b9acSAndroid Build Coastguard Worker 		xp = lws_dll2_search_sz_pl(&o, "nope", 4, struct x, list, sz);
760*1c60b9acSAndroid Build Coastguard Worker 		if (xp != &x1) {
761*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: 2 xp %p\n", __func__, xp);
762*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
763*1c60b9acSAndroid Build Coastguard Worker 		}
764*1c60b9acSAndroid Build Coastguard Worker 		xp = lws_dll2_search_sz_pl(&o, "wrong", 4, struct x, list, sz);
765*1c60b9acSAndroid Build Coastguard Worker 		if (xp) {
766*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: 3 xp %p\n", __func__, xp);
767*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
768*1c60b9acSAndroid Build Coastguard Worker 		}
769*1c60b9acSAndroid Build Coastguard Worker 	}
770*1c60b9acSAndroid Build Coastguard Worker 
771*1c60b9acSAndroid Build Coastguard Worker 	{
772*1c60b9acSAndroid Build Coastguard Worker 		lws_struct_args_t a;
773*1c60b9acSAndroid Build Coastguard Worker 		struct lejp_ctx ctx;
774*1c60b9acSAndroid Build Coastguard Worker 		int m;
775*1c60b9acSAndroid Build Coastguard Worker 
776*1c60b9acSAndroid Build Coastguard Worker 		memset(&a, 0, sizeof(a));
777*1c60b9acSAndroid Build Coastguard Worker 		a.map_st[0] = lsm_jig_schema;
778*1c60b9acSAndroid Build Coastguard Worker 		a.map_entries_st[0] = LWS_ARRAY_SIZE(lsm_jig_schema);
779*1c60b9acSAndroid Build Coastguard Worker 		a.ac_block_size = 512;
780*1c60b9acSAndroid Build Coastguard Worker 
781*1c60b9acSAndroid Build Coastguard Worker 		lws_struct_json_init_parse(&ctx, NULL, &a);
782*1c60b9acSAndroid Build Coastguard Worker 
783*1c60b9acSAndroid Build Coastguard Worker 		m = lejp_parse(&ctx, (uint8_t *)jig_conf, (int)strlen(jig_conf));
784*1c60b9acSAndroid Build Coastguard Worker 
785*1c60b9acSAndroid Build Coastguard Worker 		if (m < 0 || !a.dest) {
786*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: line %d: JSON decode failed '%s'\n",
787*1c60b9acSAndroid Build Coastguard Worker 				    __func__, ctx.line, lejp_error_to_string(m));
788*1c60b9acSAndroid Build Coastguard Worker 			goto bail;
789*1c60b9acSAndroid Build Coastguard Worker 		}
790*1c60b9acSAndroid Build Coastguard Worker 	}
791*1c60b9acSAndroid Build Coastguard Worker 
792*1c60b9acSAndroid Build Coastguard Worker 	lwsl_user("Completed: PASS\n");
793*1c60b9acSAndroid Build Coastguard Worker 
794*1c60b9acSAndroid Build Coastguard Worker 	return 0;
795*1c60b9acSAndroid Build Coastguard Worker 
796*1c60b9acSAndroid Build Coastguard Worker bail:
797*1c60b9acSAndroid Build Coastguard Worker 
798*1c60b9acSAndroid Build Coastguard Worker 	lwsl_user("Completed: FAIL\n");
799*1c60b9acSAndroid Build Coastguard Worker 
800*1c60b9acSAndroid Build Coastguard Worker 	return 1;
801*1c60b9acSAndroid Build Coastguard Worker }
802