1 /*
2  * Copyright (C) 2015-2019 Alibaba Group Holding Limited
3  */
4 
5 #include <stdarg.h>
6 #include <string.h>
7 
8 #include "aos_network.h"
9 #include "aos_system.h"
10 #include "be_inl.h"
11 #include "board_config.h"
12 
13 #define MOD_STR "CELLULAR"
14 
15 typedef struct {
16     int status;
17     int js_cb_ref;
18 } network_status_notify_param_t;
19 
20 static int g_js_cb_ref = 0;
21 /*************************************************************************************
22  * Function:    native_aiot_close
23  * Description: js native addon for
24  *            UDP.close(sock_id)
25  * Called by:   js api
26  * Input:       sock_id: interger
27  *
28  * Output:      return 0 when UDP.close call ok
29  *            return error number UDP.close call fail
30  **************************************************************************************/
native_cellular_get_simInfo(duk_context * ctx)31 static duk_ret_t native_cellular_get_simInfo(duk_context *ctx)
32 {
33     int ret = -1;
34     amp_sim_info_t sim_info;
35 
36     memset(&sim_info, 0, sizeof(sim_info));
37 
38     ret = amp_get_sim_info(&sim_info);
39     if (ret != 0) {
40         amp_debug(MOD_STR, "get sim card info failed");
41         goto out;
42     }
43 
44     duk_push_object(ctx);
45 
46     AMP_ADD_STRING("imsi", sim_info.imsi);
47     AMP_ADD_STRING("imei", sim_info.imei);
48     AMP_ADD_STRING("iccid", sim_info.iccid);
49 
50     return 1;
51 
52 out:
53     duk_push_int(ctx, ret);
54     return 1;
55 }
56 
57 /*************************************************************************************
58  * Function:    native_aiot_close
59  * Description: js native addon for
60  *            UDP.close(sock_id)
61  * Called by:   js api
62  * Input:       sock_id: interger
63  *
64  * Output:      return 0 when UDP.close call ok
65  *            return error number UDP.close call fail
66  **************************************************************************************/
native_cellular_get_locatorInfo(duk_context * ctx)67 static duk_ret_t native_cellular_get_locatorInfo(duk_context *ctx)
68 {
69     int ret = -1;
70     amp_locator_info_t locator_info;
71 
72     memset(&locator_info, 0, sizeof(locator_info));
73 
74     ret = amp_get_locator_info(&locator_info);
75     if (ret != 0) {
76         amp_debug(MOD_STR, "get locator card info failed");
77         goto out;
78     }
79 
80     duk_push_object(ctx);
81 
82     AMP_ADD_INT("cellid", locator_info.cellid);
83     AMP_ADD_INT("lac", locator_info.lac);
84     AMP_ADD_STRING("mcc", locator_info.mcc);
85     AMP_ADD_STRING("mnc", locator_info.mnc);
86     AMP_ADD_INT("signal", locator_info.signal);
87 
88     return 1;
89 
90 out:
91     duk_push_int(ctx, ret);
92     return 1;
93 }
94 
95 /*************************************************************************************
96  * Function:    native_aiot_close
97  * Description: js native addon for
98  *            UDP.close(sock_id)
99  * Called by:   js api
100  * Input:       sock_id: interger
101  *
102  * Output:      return 0 when UDP.close call ok
103  *            return error number UDP.close call fail
104  **************************************************************************************/
cellInfo_receive_callback(amp_locator_info_t * locator_info,int cell_num)105 void cellInfo_receive_callback(amp_locator_info_t *locator_info, int cell_num)
106 {
107     int ret = -1;
108     int i;
109 
110     duk_context *ctx = be_get_context();
111     be_push_ref(ctx, g_js_cb_ref);
112     int arr_idx = duk_push_array(ctx);
113     for (i = 0; i < cell_num; i++) {
114         duk_push_object(ctx);
115 
116         AMP_ADD_INT("cellid", locator_info[i].cellid);
117         AMP_ADD_INT("lac", locator_info[i].lac);
118         AMP_ADD_STRING("mcc", locator_info[i].mcc);
119         AMP_ADD_STRING("mnc", locator_info[i].mnc);
120 
121         duk_put_prop_index(ctx, arr_idx, i);
122     }
123     if (duk_pcall(ctx, 1) != DUK_EXEC_SUCCESS) {
124         amp_console("%s", duk_safe_to_stacktrace(ctx, -1));
125     }
126     duk_pop(ctx);
127 }
128 
native_cellular_neighborCellInfo(duk_context * ctx)129 static duk_ret_t native_cellular_neighborCellInfo(duk_context *ctx)
130 {
131     int ret = -1;
132     // int i,cellnum = 0;
133 
134     // if (!duk_is_function(ctx, 0)) {
135     //     amp_warn(MOD_STR, "parameter must be function");
136     //     goto out;
137     // }
138 
139     // duk_dup(ctx, 1);
140     // g_js_cb_ref = be_ref(ctx);
141 
142     ret = amp_get_neighbor_locator_info(cellInfo_receive_callback);
143     if (ret != 0) {
144         amp_debug(MOD_STR, "get locator card info failed");
145         goto out;
146     }
147 
148     return 1;
149 
150 out:
151     duk_push_int(ctx, ret);
152     return 1;
153 }
154 
native_cellular_getStatus(duk_context * ctx)155 static duk_ret_t native_cellular_getStatus(duk_context *ctx)
156 {
157     int ret = -1;
158 
159     ret = aos_get_network_status();
160     if (ret != 1) {
161         amp_debug(MOD_STR, "network status disconnect %d", ret);
162         goto out;
163     }
164 
165 out:
166     duk_push_int(ctx, ret);
167     return 1;
168 }
169 
network_status_notify(void * pdata)170 static void network_status_notify(void *pdata)
171 {
172     int i = 0;
173     network_status_notify_param_t *p = (network_status_notify_param_t *)pdata;
174     duk_context *ctx = be_get_context();
175 
176     be_push_ref(ctx, p->js_cb_ref);
177     duk_push_int(ctx, p->status);
178     if (duk_pcall(ctx, 1) != DUK_EXEC_SUCCESS) {
179         amp_console("%s", duk_safe_to_stacktrace(ctx, -1));
180     }
181     aos_free(p);
182     duk_pop(ctx);
183     duk_gc(ctx, 0);
184 }
185 
network_status_callback(int status,void * args)186 static void network_status_callback(int status, void *args)
187 {
188     int js_cb_ref = (int)args;
189     network_status_notify_param_t *p =
190         aos_calloc(1, sizeof(network_status_notify_param_t));
191     if (!p) {
192         amp_warn(MOD_STR, "allocate memory failed");
193         duk_context *ctx = be_get_context();
194         be_unref(ctx, js_cb_ref);
195         return;
196     }
197 
198     p->status = status;
199     p->js_cb_ref = js_cb_ref;
200 
201     py_task_schedule_call(network_status_notify, p);
202 }
203 
native_cellular_onconnect(duk_context * ctx)204 static duk_ret_t native_cellular_onconnect(duk_context *ctx)
205 {
206     int ret = -1;
207     int js_cb_ref;
208 
209     if (!duk_is_function(ctx, 0)) {
210         amp_warn(MOD_STR, "parameter must be function");
211         goto out;
212     }
213 
214     duk_dup(ctx, 0);
215     js_cb_ref = be_ref(ctx);
216 
217     ret = aos_network_status_registercb(network_status_callback, js_cb_ref);
218     if (ret != 0) {
219         duk_context *ctx = be_get_context();
220         be_unref(ctx, js_cb_ref);
221         return -1;
222     }
223 
224 out:
225     duk_push_int(ctx, ret);
226     return 1;
227 }
228 
native_get_netshare_mode(duk_context * ctx)229 static duk_ret_t native_get_netshare_mode(duk_context *ctx)
230 {
231     int ret = -1;
232 
233     ret = amp_get_netsharemode();
234 
235 out:
236     duk_push_int(ctx, ret);
237     return 1;
238 }
239 
native_set_netshare_mode(duk_context * ctx)240 static duk_ret_t native_set_netshare_mode(duk_context *ctx)
241 {
242     int ret = -1;
243     int share_mode = 0;
244 
245     if (!duk_is_number(ctx, 0)) {
246         amp_warn(MOD_STR, "parameter must be number");
247         goto out;
248     }
249 
250     share_mode = duk_get_number(ctx, 0);
251     amp_error(MOD_STR, "native set net share mode = %d", share_mode);
252     ret = amp_set_netsharemode(share_mode);
253     if (ret != 0) {
254         return -1;
255     }
256     amp_error(MOD_STR, "native set net share mode success");
257 out:
258     duk_push_int(ctx, ret);
259     return 1;
260 }
261 
native_get_netshare_config(duk_context * ctx)262 static duk_ret_t native_get_netshare_config(duk_context *ctx)
263 {
264     int ret = -1;
265     amp_sharemode_info_t *share_mode_info;
266 
267     share_mode_info = aos_malloc(sizeof(amp_sharemode_info_t));
268     if (share_mode_info == NULL) {
269         amp_debug(MOD_STR, "get net share config failed");
270         goto out;
271     }
272     memset(share_mode_info, 0, sizeof(amp_sharemode_info_t));
273 
274     ret = amp_get_netshareconfig(share_mode_info);
275     if (ret != 0) {
276         amp_debug(MOD_STR, "get net share config failed");
277         goto out;
278     }
279 
280     duk_push_object(ctx);
281 
282     AMP_ADD_INT("action", share_mode_info->action);
283     AMP_ADD_INT("auto_connect", share_mode_info->auto_connect);
284     AMP_ADD_STRING("apn", share_mode_info->apn);
285     AMP_ADD_STRING("username", share_mode_info->username);
286     AMP_ADD_STRING("password", share_mode_info->password);
287     AMP_ADD_INT("ip_type", share_mode_info->ip_type);
288     AMP_ADD_INT("share_mode", share_mode_info->share_mode);
289 
290     aos_free(share_mode_info);
291     return 1;
292 
293 out:
294     if (share_mode_info) {
295         aos_free(share_mode_info);
296     }
297     duk_push_int(ctx, ret);
298     return 1;
299 }
300 
native_set_netshare_config(duk_context * ctx)301 static duk_ret_t native_set_netshare_config(duk_context *ctx)
302 {
303     int ret = -1;
304     amp_sharemode_info_t *share_mode_info;
305 
306     /* check paramters */
307     if (!duk_is_object(ctx, 0)) {
308         amp_warn(MOD_STR, "parameter must be object\n");
309         goto out;
310     }
311 
312     /* get device certificate */
313     duk_get_prop_string(ctx, 0, "ucid");
314     duk_get_prop_string(ctx, 0, "action");
315     duk_get_prop_string(ctx, 0, "autoConnect");
316     duk_get_prop_string(ctx, 0, "apn");
317     duk_get_prop_string(ctx, 0, "username");
318     duk_get_prop_string(ctx, 0, "password");
319     duk_get_prop_string(ctx, 0, "authType");
320     duk_get_prop_string(ctx, 0, "ipType");
321 
322     // if (!duk_is_number(ctx, -8) || !duk_is_number(ctx, -7) ||
323     //     !duk_is_number(ctx, -6) || !duk_is_string(ctx, -5) ||
324     //     !duk_is_string(ctx, -4) || !duk_is_string(ctx, -3) ||
325     //     !duk_is_number(ctx, -2) || !duk_is_number(ctx, -1))
326     // {
327     //     amp_warn(MOD_STR,
328     //         "Parameter 1 must be an object like {host: string, "
329     //         "port: uint, client_id: string, username: string, "
330     //         "password: string, keepalive_interval: uint} %d %d %d %d %d %d %d
331     //         %d %d", duk_is_number(ctx, -8), duk_is_number(ctx, -7),
332     //         duk_is_number(ctx, -6), duk_is_string(ctx, -5),
333     //         duk_is_string(ctx, -4), duk_is_string(ctx, -3),
334     //         duk_is_string(ctx, -2), duk_is_boolean(ctx, -2),
335     //         duk_is_number(ctx, -1));
336     //     // duk_pop_n(ctx, 8);
337     //     // goto out;
338     // }
339 
340     const uint16_t ipType = duk_get_number(ctx, -1);
341     const uint16_t authType = duk_get_number(ctx, -2);
342     const char *password = duk_get_string(ctx, -3);
343     const char *username = duk_get_string(ctx, -4);
344     const char *apn = duk_get_string(ctx, -5);
345     const uint16_t autoConnect = duk_get_number(ctx, -6);
346     const uint16_t action = duk_get_number(ctx, -7);
347     const uint16_t ucid = duk_get_number(ctx, -8);
348 
349     share_mode_info = aos_malloc(sizeof(amp_sharemode_info_t));
350     if (share_mode_info == NULL) {
351         amp_debug(MOD_STR, "set net share config failed");
352         goto out;
353     }
354     memset(share_mode_info, 0, sizeof(amp_sharemode_info_t));
355 
356     share_mode_info->action = action;
357     share_mode_info->auto_connect = autoConnect;
358     memcpy(share_mode_info->apn, apn, strlen(apn));
359     memcpy(share_mode_info->username, username, strlen(username));
360     memcpy(share_mode_info->password, password, strlen(password));
361     share_mode_info->ip_type = ipType;
362 
363     ret = amp_set_netshareconfig(ucid, authType, share_mode_info);
364     if (ret != 0) {
365         amp_warn(MOD_STR, "amp set net share config failed!");
366         aos_free(share_mode_info);
367         return -1;
368     }
369 
370 out:
371     if (share_mode_info) {
372         aos_free(share_mode_info);
373     }
374     duk_push_int(ctx, ret);
375     return 1;
376 }
377 
module_cellular_register(void)378 void module_cellular_register(void)
379 {
380     duk_context *ctx = be_get_context();
381 
382     duk_push_object(ctx);
383 
384     AMP_ADD_FUNCTION("getSimInfo", native_cellular_get_simInfo, 0);
385     AMP_ADD_FUNCTION("getLocatorInfo", native_cellular_get_locatorInfo, 0);
386     AMP_ADD_FUNCTION("getStatus", native_cellular_getStatus, 0);
387     AMP_ADD_FUNCTION("onConnect", native_cellular_onconnect, 1);
388     AMP_ADD_FUNCTION("getNeighborCellInfo", native_cellular_neighborCellInfo,
389                      0);
390     AMP_ADD_FUNCTION("getNetSharemode", native_get_netshare_mode, 0);
391     AMP_ADD_FUNCTION("setNetSharemode", native_set_netshare_mode, 1);
392     AMP_ADD_FUNCTION("getNetShareconfig", native_get_netshare_config, 0);
393     AMP_ADD_FUNCTION("setNetShareconfig", native_set_netshare_config, 1);
394 
395     duk_put_prop_string(ctx, -2, "CELLULAR");
396 }
397