V7_PRIVATE val_t rx_exec(struct v7 *v7, val_t rx, val_t str, int lind) { if (v7_is_regexp(rx)) { val_t s = to_string(v7, str); size_t len; struct slre_loot sub; struct slre_cap *ptok = sub.caps; char *const str = (char *) v7_to_string(v7, &s, &len); const char *const end = str + len; const char *begin = str; struct v7_regexp *rp = v7_to_regexp(rx); int flag_g = slre_get_flags(rp->compiled_regexp) & SLRE_FLAG_G; if (rp->lastIndex < 0) rp->lastIndex = 0; if (flag_g || lind) begin = utfnshift(str, rp->lastIndex); if (!slre_exec(rp->compiled_regexp, 0, begin, end, &sub)) { int i; val_t arr = v7_create_array(v7); for (i = 0; i < sub.num_captures; i++, ptok++) v7_array_push(v7, arr, v7_create_string(v7, ptok->start, ptok->end - ptok->start, 1)); if (flag_g) rp->lastIndex = utfnlen(str, sub.caps->end - str); v7_set_property(v7, arr, "index", 5, V7_PROPERTY_READ_ONLY, v7_create_number(utfnlen(str, sub.caps->start - str))); return arr; } else rp->lastIndex = 0; } return v7_create_null(); }
ICACHE_FLASH_ATTR static v7_val_t Wifi_status(struct v7 *v7, v7_val_t this_obj, v7_val_t args) { uint8 st = wifi_station_get_connect_status(); const char *msg; (void) this_obj; (void) args; switch (st) { case STATION_IDLE: msg = "idle"; break; case STATION_CONNECTING: msg = "connecting"; break; case STATION_WRONG_PASSWORD: msg = "bad pass"; break; case STATION_NO_AP_FOUND: msg = "no ap"; break; case STATION_CONNECT_FAIL: msg = "connect failed"; break; case STATION_GOT_IP: msg = "got ip"; break; } return v7_create_string(v7, msg, strlen(msg), 1); }
/* * If resolved successfuly it will connect. Otherwise invokes * user callback as cb(undefined, error_message) */ static void http_get_dns_cb(const char *name, ip_addr_t *ipaddr, void *arg) { /* WIP: for now return the dns address as if it were the `get` response */ struct espconn *conn = (struct espconn *) arg; struct http_ctx *ctx = (struct http_ctx *) conn->proto.tcp; static char err_msg[] = "cannot resolve"; if (ipaddr == NULL) { v7_val_t res, cb_args = v7_create_object(v7); v7_own(v7, &cb_args); v7_array_set(v7, cb_args, 0, ctx->cb); v7_array_set(v7, cb_args, 1, v7_create_string(v7, err_msg, sizeof(err_msg), 1)); http_free(conn); if (v7_exec_with(v7, &res, "this[0](undefined, this[1])", cb_args) != V7_OK) { v7_fprintln(stderr, v7, res); } v7_disown(v7, &cb_args); v7_disown(v7, &ctx->body); /* body has not been sent yet */ v7_disown(v7, &ctx->cb); } else { memcpy(conn->proto.tcp->remote_ip, &ipaddr->addr, 4); conn->proto.tcp->remote_port = ctx->port; conn->proto.tcp->local_port = espconn_port(); espconn_regist_connectcb(conn, http_connect_cb); espconn_regist_disconcb(conn, http_disconnect_cb); espconn_regist_reconcb(conn, http_error_cb); espconn_connect(conn); } }
/* Invoke user callback as cb(data, undefined) */ static void http_disconnect_cb(void *arg) { struct espconn *conn = (struct espconn *) arg; struct http_ctx *ctx = (struct http_ctx *) conn->proto.tcp; v7_val_t data, cb_args; char *body; int i; v7_val_t res; body = ctx->resp; for (i = 0; i + 3 < ctx->resp_pos; i++) { if (memcmp(ctx->resp + i, "\r\n\r\n", 4) == 0) { body = ctx->resp + i + 4; break; } } cb_args = v7_create_object(v7); v7_own(v7, &cb_args); data = v7_create_string(v7, body, ctx->resp_pos - (body - ctx->resp), 1); v7_own(v7, &data); http_free(conn); v7_array_set(v7, cb_args, 0, ctx->cb); v7_array_set(v7, cb_args, 1, data); v7_disown(v7, &data); if (v7_exec_with(v7, &res, "this[0](this[1])", cb_args) != V7_OK) { v7_fprintln(stderr, v7, res); } v7_disown(v7, &cb_args); v7_disown(v7, &ctx->cb); }
V7_PRIVATE val_t Regex_ctor(struct v7 *v7, val_t this_obj, val_t args) { long argnum = v7_array_length(v7, args); if (argnum > 0) { val_t ro = to_string(v7, v7_array_get(v7, args, 0)); size_t re_len, flags_len = 0; const char *re = v7_to_string(v7, &ro, &re_len), *flags = NULL; struct slre_prog *p = NULL; struct v7_regexp *rp; (void) this_obj; if (argnum > 1) { val_t fl = to_string(v7, v7_array_get(v7, args, 1)); flags = v7_to_string(v7, &fl, &flags_len); } if (slre_compile(re, re_len, flags, flags_len, &p, 1) != SLRE_OK || p == NULL) { throw_exception(v7, TYPE_ERROR, "Invalid regex"); return v7_create_undefined(); } else { rp = (struct v7_regexp *) malloc(sizeof(*rp)); rp->regexp_string = v7_create_string(v7, re, re_len, 1); rp->compiled_regexp = p; rp->lastIndex = 0; return v7_pointer_to_value(rp) | V7_TAG_REGEXP; } } return v7_create_regexp(v7, "(?:)", 4, NULL, 0); }
static val_t Json_stringify(struct v7 *v7, val_t this_obj, val_t args) { val_t arg0 = v7_array_get(v7, args, 0); char buf[100], *p = v7_to_json(v7, arg0, buf, sizeof(buf)); val_t res = v7_create_string(v7, p, strlen(p), 1); (void) this_obj; if (p != buf) free(p); return res; }
static v7_val_t Wifi_ip(struct v7 *v7) { v7_val_t res; char *ip = sj_wifi_get_sta_ip(); if (ip == NULL) return v7_create_undefined(); res = v7_create_string(v7, ip, strlen(ip), 1); free(ip); return res; }
static v7_val_t Wifi_show(struct v7 *v7) { v7_val_t res; char *ssid = sj_wifi_get_connected_ssid(); if (ssid == NULL) return v7_create_undefined(); res = v7_create_string(v7, ssid, strlen(ssid), 1); free(ssid); return res; }
static v7_val_t Wifi_status(struct v7 *v7) { v7_val_t res; char *status = sj_wifi_get_status(); if (status == NULL) return v7_create_undefined(); res = v7_create_string(v7, status, strlen(status), 1); free(status); return res; }
static val_t Regex_source(struct v7 *v7, val_t this_obj, val_t args) { val_t r = i_value_of(v7, this_obj); const char *buf = 0; size_t len = 0; (void) args; if (v7_is_regexp(r)) buf = v7_to_string(v7, &v7_to_regexp(r)->regexp_string, &len); return v7_create_string(v7, buf, len, 1); }
size_t sj_uart_recv_cb(void *ctx, const char *d, size_t len) { struct user_data *ud = (struct user_data *) ctx; v7_val_t s, cb = ud->cb; size_t want = ud->want; if (len < want || v7_is_undefined(ud->cb)) return 0; ud->cb = v7_create_undefined(); ud->want = 0; s = v7_create_string(ud->v7, d, want, 1); sj_invoke_cb1(ud->v7, cb, s); return want; }
void sj_http_error_callback(struct v7 *v7, v7_val_t cb, int err_no) { char err_msg[128]; v7_val_t res, cb_args; cb_args = v7_create_object(v7); v7_own(v7, &cb_args); snprintf(err_msg, sizeof(err_msg), "connection error: %d\n", err_no); v7_array_set(v7, cb_args, 0, cb); v7_array_set(v7, cb_args, 1, v7_create_string(v7, err_msg, sizeof(err_msg), 1)); if (v7_exec_with(v7, &res, "this[0](undefined, this[1])", cb_args) != V7_OK) { v7_fprintln(stderr, v7, res); } v7_disown(v7, &cb_args); }
/* * Returns the IP address of an interface. * * Pass either Wifi.STATION or Wifi.SOFTAP * Defaults to Wifi.STATION if called without argument. */ ICACHE_FLASH_ATTR static v7_val_t Wifi_ip(struct v7 *v7, v7_val_t this_obj, v7_val_t args) { v7_val_t arg = v7_array_get(v7, args, 0); int err; struct ip_info info; char ip[17]; (void) this_obj; (void) args; err = wifi_get_ip_info(v7_is_double(arg) ? v7_to_double(arg) : 0, &info); if (err == 0) { v7_throw(v7, "cannot get ip info"); } snprintf(ip, sizeof(ip), IPSTR, IP2STR(&info.ip)); return v7_create_string(v7, ip, strlen(ip), 1); }
static void ws_ev_handler(struct ns_connection *nc, int ev, void *ev_data) { struct websocket_message *wm = (struct websocket_message *) ev_data; struct user_data *ud = (struct user_data *) nc->user_data; struct v7 *v7 = ud->v7; switch (ev) { case NS_CONNECT: if (*(int *) ev_data == 0) { char *proto = NULL; if (ud->proto != NULL) { int tmp = asprintf(&proto, "Sec-WebSocket-Protocol: %s\n", ud->proto); (void) tmp; /* Shutup compiler */ } ns_send_websocket_handshake(nc, "/", proto); if (proto != NULL) { free(proto); } } else { invoke_cb(ud, "onerror", v7_create_null()); } break; case NS_WEBSOCKET_HANDSHAKE_DONE: v7_set(v7, ud->ws, "_nc", ~0, V7_PROPERTY_HIDDEN, v7_create_foreign(nc)); invoke_cb(ud, "onopen", v7_create_null()); break; case NS_WEBSOCKET_FRAME: { v7_val_t ev, data; ev = v7_create_object(v7); v7_own(v7, &ev); data = v7_create_string(v7, (char *) wm->data, wm->size, 1); v7_set(v7, ev, "data", ~0, 0, data); invoke_cb(ud, "onmessage", ev); v7_disown(v7, &ev); break; } case NS_CLOSE: invoke_cb(ud, "onclose", v7_create_null()); nc->user_data = NULL; v7_set(v7, ud->ws, "_nc", ~0, V7_PROPERTY_HIDDEN, v7_create_undefined()); v7_disown(v7, &ud->ws); free(ud); break; } }
void sj_init_v7_ext(struct v7 *v7) { v7_val_t os, gc; v7_set(v7, v7_get_global(v7), "version", 7, 0, v7_create_string(v7, sj_version, strlen(sj_version), 1)); v7_set_method(v7, v7_get_global(v7), "usleep", global_usleep); gc = v7_create_object(v7); v7_set(v7, v7_get_global(v7), "GC", 2, 0, gc); v7_set_method(v7, gc, "stat", GC_stat); v7_set_method(v7, gc, "gc", GC_gc); os = v7_create_object(v7); v7_set(v7, v7_get_global(v7), "OS", 2, 0, os); v7_set_method(v7, os, "prof", OS_prof); v7_set_method(v7, os, "wdt_feed", OS_wdt_feed); v7_set_method(v7, os, "reset", OS_reset); }
/* Invoke user callback as cb(undefined, err_msg) */ static void http_error_cb(void *arg, int8_t err) { struct espconn *conn = (struct espconn *) arg; struct http_ctx *ctx = (struct http_ctx *) conn->proto.tcp; char err_msg[128]; v7_val_t res, cb_args; cb_args = v7_create_object(v7); v7_own(v7, &cb_args); snprintf(err_msg, sizeof(err_msg), "connection error: %d\n", err); v7_array_set(v7, cb_args, 0, ctx->cb); v7_array_set(v7, cb_args, 1, v7_create_string(v7, err_msg, sizeof(err_msg), 1)); http_free(conn); if (v7_exec_with(v7, &res, "this[0](undefined, this[1])", cb_args) != V7_OK) { v7_fprintln(stderr, v7, res); } v7_disown(v7, &cb_args); }
void sj_http_success_callback(struct v7 *v7, v7_val_t cb, const char *data, size_t data_len) { v7_val_t datav, cb_args; v7_val_t res; cb_args = v7_create_object(v7); v7_own(v7, &cb_args); datav = v7_create_string(v7, data, data_len, 1); v7_own(v7, &datav); v7_array_set(v7, cb_args, 0, cb); v7_array_set(v7, cb_args, 1, datav); v7_disown(v7, &datav); if (v7_exec_with(v7, &res, "this[0](this[1])", cb_args) != V7_OK) { v7_fprintln(stderr, v7, res); } v7_disown(v7, &cb_args); v7_disown(v7, &cb); }
void sj_wifi_scan_done(const char **ssids) { struct v7 *v7 = s_v7; v7_val_t cb = v7_get(v7, s_wifi, "_scb", ~0); v7_val_t res = v7_create_undefined(); const char **p; if (!v7_is_function(cb)) return; v7_own(v7, &res); if (ssids != NULL) { res = v7_create_array(v7); for (p = ssids; *p != NULL; p++) { v7_array_push(v7, res, v7_create_string(v7, *p, strlen(*p), 1)); } } else { res = v7_create_undefined(); } sj_invoke_cb1(v7, cb, res); v7_disown(v7, &res); v7_set(v7, s_wifi, "_scb", ~0, V7_PROPERTY_DONT_ENUM | V7_PROPERTY_HIDDEN, v7_create_undefined()); }
void sj_http_error_callback(struct v7 *v7, v7_val_t cb, int err_no) { char err_msg[32]; snprintf(err_msg, sizeof(err_msg), "connection error: %d\n", err_no); sj_invoke_cb2(v7, cb, v7_create_undefined(), v7_create_string(v7, err_msg, ~0, 1)); }
void sj_http_success_callback(struct v7 *v7, v7_val_t cb, const char *data, size_t data_len) { sj_invoke_cb1(v7, cb, v7_create_string(v7, data, data_len, 1)); }
void wifi_changed_cb(System_Event_t *evt) { enum sj_wifi_status sj_ev = -1; /* TODO(rojer): Share this logic between platforms. */ if (wifi_setting_up && #ifndef RTOS_SDK evt->event == EVENT_STAMODE_GOT_IP #else evt->event_id == EVENT_STAMODE_GOT_IP #endif ) { struct station_config config; v7_val_t res; v7_val_t conf = v7_get(v7, v7_get_global_object(v7), "conf", ~0); v7_val_t known, wifi; if (v7_is_undefined(conf)) { fprintf(stderr, "cannot save conf, no conf object\n"); return; } wifi = v7_get(v7, conf, "wifi", ~0); if (v7_is_undefined(wifi)) { wifi = v7_create_object(v7); v7_set(v7, conf, "wifi", ~0, 0, wifi); } known = v7_get(v7, conf, "known", ~0); if (v7_is_undefined(known)) { known = v7_create_object(v7); v7_set(v7, wifi, "known", ~0, 0, known); } wifi_station_get_config(&config); v7_set(v7, known, (const char *) config.ssid, ~0, 0, v7_create_string(v7, (const char *) config.password, strlen((const char *) config.password), 1)); v7_exec(v7, "conf.save()", &res); wifi_setting_up = 0; } #ifndef RTOS_SDK switch (evt->event) { #else switch (evt->event_id) { #endif case EVENT_STAMODE_DISCONNECTED: sj_ev = SJ_WIFI_DISCONNECTED; break; case EVENT_STAMODE_CONNECTED: sj_ev = SJ_WIFI_CONNECTED; break; case EVENT_STAMODE_GOT_IP: sj_ev = SJ_WIFI_IP_ACQUIRED; break; } if (sj_ev >= 0) sj_wifi_on_change_callback(sj_ev); } char *sj_wifi_get_connected_ssid() { struct station_config conf; if (!wifi_station_get_config(&conf)) return NULL; return strdup((const char *) conf.ssid); } char *sj_wifi_get_sta_ip() { struct ip_info info; char *ip; if (!wifi_get_ip_info(0, &info) || info.ip.addr == 0) return NULL; if (asprintf(&ip, IPSTR, IP2STR(&info.ip)) < 0) { return NULL; } return ip; } void wifi_scan_done(void *arg, STATUS status) { if (status == OK) { STAILQ_HEAD(, bss_info) *info = arg; struct bss_info *p; const char **ssids; int n = 0; STAILQ_FOREACH(p, info, next) n++; ssids = calloc(n + 1, sizeof(*ssids)); n = 0; STAILQ_FOREACH(p, info, next) { ssids[n++] = (const char *) p->ssid; } wifi_scan_cb(ssids); free(ssids); } else {
void call_listener_func(vm_gsm_tel_call_listener_data_t* data) { vm_log_info("call_listener_func"); if(data->call_type == VM_GSM_TEL_INDICATION_INCOMING_CALL) { vm_gsm_tel_call_info_t* ind = (vm_gsm_tel_call_info_t*)data->data; g_uid_info.call_id = ind->uid_info.call_id; g_uid_info.group_id = ind->uid_info.group_id; g_uid_info.sim = ind->uid_info.sim; strcpy(g_incoming_number, (char*)ind->num_uri); g_call_status = RECEIVINGCALL; vm_log_info("incoming call"); // to-do: js callback { v7_val_t cb = v7_get(v7, v7_get_global(v7), INCOMING_CALL_CB, sizeof(INCOMING_CALL_CB) - 1); if (v7_is_function(cb)) { v7_val_t res; v7_val_t number = v7_create_string(v7, g_incoming_number, strlen(g_incoming_number), 1); if (v7_apply(v7, &res, cb, v7_create_undefined(), number) != V7_OK) { /* TODO(mkm): make it print stack trace */ fprintf(stderr, "cb threw an exception\n"); } } } } else if(data->call_type == VM_GSM_TEL_INDICATION_OUTGOING_CALL) { vm_gsm_tel_call_info_t* ind = (vm_gsm_tel_call_info_t*)data->data; g_uid_info.call_id = ind->uid_info.call_id; g_uid_info.group_id = ind->uid_info.group_id; g_uid_info.sim = ind->uid_info.sim; strcpy(g_incoming_number, (char*)ind->num_uri); g_call_status = CALLING; vm_log_info("calling"); } else if(data->call_type == VM_GSM_TEL_INDICATION_CONNECTED) { vm_gsm_tel_connect_indication_t* ind = (vm_gsm_tel_connect_indication_t*)data->data; g_uid_info.call_id = ind->uid_info.call_id; g_uid_info.group_id = ind->uid_info.group_id; g_uid_info.sim = ind->uid_info.sim; g_call_status = TALKING; vm_log_info("connected"); } else if(data->call_type == VM_GSM_TEL_INDICATION_CALL_ENDED) { g_call_status = IDLE_CALL; vm_log_info("endded"); } else { vm_log_info("bad operation type"); } vm_log_info("g_call_status is %d", g_call_status); }