void esp_sj_uart_init(struct v7 *v7) { sj_us[0].v7 = sj_us[1].v7 = v7; os_timer_setfn(&sj_us[0].timer, esp_sj_uart_dispatcher, (void *) 0); os_timer_setfn(&sj_us[1].timer, esp_sj_uart_dispatcher, (void *) 1); s_uart_proto = v7_mk_object(v7); v7_set_method(v7, s_uart_proto, "configure", UART_configure); v7_set_method(v7, s_uart_proto, "onRecv", UART_onRecv); v7_set_method(v7, s_uart_proto, "recv", UART_recv); v7_set_method(v7, s_uart_proto, "setRXEnabled", UART_setRXEnabled); v7_set_method(v7, s_uart_proto, "onTXEmpty", UART_onTXEmpty); v7_set_method(v7, s_uart_proto, "sendAvail", UART_sendAvail); v7_set_method(v7, s_uart_proto, "send", UART_send); v7_set_method(v7, v7_get_global(v7), "UART", UART_get); sj_us[0].uart_no = 0; sj_us[0].obj = v7_mk_object(v7); v7_set_proto(v7, sj_us[0].obj, s_uart_proto); v7_set(v7, sj_us[0].obj, "_u", ~0, v7_mk_number(0)); v7_own(v7, &sj_us[0].obj); sj_us[1].uart_no = 1; sj_us[1].obj = v7_mk_object(v7); v7_set_proto(v7, sj_us[1].obj, s_uart_proto); v7_set(v7, sj_us[1].obj, "_u", ~0, v7_mk_number(1)); v7_own(v7, &sj_us[1].obj); }
/* 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); }
void sj_init_uart(struct v7 *v7) { v7_val_t uart = V7_UNDEFINED, uart_proto = V7_UNDEFINED, uart_ctor = V7_UNDEFINED; v7_own(v7, &uart); v7_own(v7, &uart_proto); v7_own(v7, &uart_ctor); uart = v7_mk_object(v7); uart_proto = v7_mk_object(v7); uart_ctor = v7_mk_function_with_proto(v7, UART_ctor, uart_proto); v7_def(v7, uart, "dev", ~0, _V7_DESC_HIDDEN(1), uart_ctor); v7_set_method(v7, uart_proto, "read", UART_read); v7_set_method(v7, uart_proto, "write", UART_write); v7_set_method(v7, uart_proto, "recv", UART_recv); v7_set(v7, v7_get_global(v7), "UART", ~0, uart); { enum v7_err rcode = v7_exec( v7, "UART.open = function (d) { return new UART.dev(d); }", NULL); assert(rcode == V7_OK); #if defined(NDEBUG) (void) rcode; #endif } v7_disown(v7, &uart_ctor); v7_disown(v7, &uart_proto); v7_disown(v7, &uart); }
void sj_print_exception(struct v7 *v7, v7_val_t exc, const char *msg) { /* * TOD(mkm) add some API to hal to fetch the current debug mode * and avoid logging to stdout if according no error messages should go * there (e.g. because it's used to implement a serial protocol). */ FILE *fs[] = {stdout, stderr}; size_t i; v7_val_t msg_v = V7_UNDEFINED; /* * own because the exception could be a string, * and if not owned here, print_stack_trace could get * an unrelocated argument an ASN violation. */ v7_own(v7, &exc); v7_own(v7, &msg_v); msg_v = v7_get(v7, exc, "message", ~0); for (i = 0; i < sizeof(fs) / sizeof(fs[0]); i++) { fprintf(fs[i], "%s: ", msg); if (!v7_is_undefined(msg_v)) { v7_fprintln(fs[i], v7, msg_v); } else { v7_fprintln(fs[i], v7, exc); } v7_fprint_stack_trace(fs[i], v7, exc); } v7_disown(v7, &msg_v); v7_disown(v7, &exc); }
void sj_init_uart(struct v7 *v7) { v7_val_t uart = v7_create_undefined(), uart_proto = v7_create_undefined(), uart_ctor = v7_create_undefined(); v7_own(v7, &uart); v7_own(v7, &uart_proto); v7_own(v7, &uart_ctor); uart = v7_create_object(v7); uart_proto = v7_create_object(v7); uart_ctor = v7_create_constructor(v7, uart_proto, UART_ctor); v7_set(v7, uart, "dev", ~0, V7_PROPERTY_HIDDEN, uart_ctor); v7_set_method(v7, uart_proto, "read", UART_read); v7_set_method(v7, uart_proto, "write", UART_write); v7_set_method(v7, uart_proto, "recv", UART_recv); v7_set(v7, v7_get_global(v7), "UART", ~0, 0, uart); { enum v7_err rcode = v7_exec( v7, "UART.open = function (d) { return new UART.dev(d); }", NULL); assert(rcode == V7_OK); #if defined(NDEBUG) (void) rcode; #endif } v7_disown(v7, &uart_ctor); v7_disown(v7, &uart_proto); v7_disown(v7, &uart); }
void sj_invoke_cb0_this(struct v7 *v7, v7_val_t cb, v7_val_t this_obj) { v7_val_t args; v7_own(v7, &cb); args = v7_mk_array(v7); v7_own(v7, &args); sj_invoke_cb(v7, cb, this_obj, args); v7_disown(v7, &args); v7_disown(v7, &cb); }
/* * Mongoose event handler. If JavaScript callback was provided, call it */ static void http_ev_handler(struct mg_connection *c, int ev, void *ev_data) { struct user_data *ud = (struct user_data *) c->user_data; if (ev == MG_EV_HTTP_REQUEST) { /* HTTP request has arrived */ if (v7_is_callable(ud->v7, ud->handler)) { /* call provided JavaScript callback with `request` and `response` */ v7_val_t request = v7_mk_object(ud->v7); v7_own(ud->v7, &request); v7_val_t response = v7_mk_object(ud->v7); v7_own(ud->v7, &response); setup_request_object(ud->v7, request, ev_data); setup_response_object(ud->v7, response, c, request); sj_invoke_cb2_this(ud->v7, ud->handler, ud->obj, request, response); v7_disown(ud->v7, &request); v7_disown(ud->v7, &response); } else { /* * no JavaScript callback provided; serve the request with the default * options by `mg_serve_http()` */ struct mg_serve_http_opts opts; memset(&opts, 0, sizeof(opts)); mg_serve_http(c, ev_data, opts); } } else if (ev == MG_EV_HTTP_REPLY) { /* HTTP response has arrived */ /* if JavaScript callback was provided, call it with `response` */ if (v7_is_callable(ud->v7, ud->handler)) { v7_val_t response = v7_mk_object(ud->v7); v7_own(ud->v7, &response); setup_request_object(ud->v7, response, ev_data); sj_invoke_cb1_this(ud->v7, ud->handler, ud->obj, response); v7_disown(ud->v7, &response); } if (c->flags & MG_F_CLOSE_CONNECTION_AFTER_RESPONSE) { c->flags |= MG_F_CLOSE_IMMEDIATELY; } } else if (ev == MG_EV_TIMER) { sj_invoke_cb0_this(ud->v7, ud->timeout_callback, ud->obj); } else if (ev == MG_EV_CLOSE) { if (c->listener == NULL && ud != NULL) { v7_set(ud->v7, ud->obj, "_c", ~0, v7_mk_undefined()); v7_disown(ud->v7, &ud->obj); v7_disown(ud->v7, &ud->timeout_callback); free(ud); c->user_data = NULL; } } }
void sj_invoke_cb(struct v7 *v7, v7_val_t func, v7_val_t this_obj, v7_val_t args) { struct prompt_event pe; struct v7_invoke_event_data *ied = calloc(1, sizeof(*ied)); ied->func = func; ied->this_obj = this_obj; ied->args = args; v7_own(v7, &ied->func); v7_own(v7, &ied->this_obj); v7_own(v7, &ied->args); pe.type = V7_INVOKE_EVENT; pe.data = ied; osi_MsgQWrite(&s_v7_q, &pe, OSI_WAIT_FOREVER); }
static enum v7_err isr_cb_proxy(struct v7 *v7, v7_val_t *res) { v7_val_t cb = v7_arg(v7, 0); v7_val_t args = v7_arg(v7, 1); v7_own(v7, &cb); v7_own(v7, &args); enum v7_err ret = v7_apply(v7, cb, v7_get_global(v7), args, res); sj_reenable_intr(v7_get_double(v7, v7_array_get(v7, args, 0))); v7_disown(v7, &args); v7_disown(v7, &cb); return ret; }
void sj_invoke_cb2(struct v7 *v7, v7_val_t cb, v7_val_t arg1, v7_val_t arg2) { v7_val_t args; v7_own(v7, &cb); v7_own(v7, &arg1); v7_own(v7, &arg2); args = v7_create_array(v7); v7_own(v7, &args); v7_array_push(v7, args, arg1); v7_array_push(v7, args, arg2); sj_invoke_cb(v7, cb, v7_get_global(v7), args); v7_disown(v7, &args); v7_disown(v7, &arg2); v7_disown(v7, &arg1); v7_disown(v7, &cb); }
SJ_PRIVATE enum v7_err Wifi_ready(struct v7 *v7, v7_val_t *res) { int ret = 0; v7_val_t cbv = v7_arg(v7, 0); if (!v7_is_callable(v7, cbv)) { LOG(LL_ERROR, ("Invalid arguments")); goto exit; } if (sj_wifi_get_status() == SJ_WIFI_IP_ACQUIRED) { sj_invoke_cb0(v7, cbv); ret = 1; } else { struct wifi_cb_arg *arg = (struct wifi_cb_arg *) calloc(1, sizeof(*arg)); if (arg != NULL) { arg->v7 = v7; arg->v = cbv; v7_own(v7, &arg->v); sj_wifi_add_on_change_cb(sj_wifi_ready_js, arg); } else { ret = 0; } } exit: *res = v7_mk_boolean(v7, ret); return V7_OK; }
static enum v7_err start_http_server(struct v7 *v7, const char *addr, v7_val_t obj, const char *ca_cert, const char *cert) { enum v7_err rcode = V7_OK; struct mg_connection *c; struct user_data *ud; struct mg_bind_opts opts; memset(&opts, 0, sizeof(opts)); #ifdef MG_ENABLE_SSL opts.ssl_ca_cert = ca_cert; opts.ssl_cert = cert; #else (void) ca_cert; (void) cert; #endif c = mg_bind_opt(&sj_mgr, addr, http_ev_handler, opts); if (c == NULL) { rcode = v7_throwf(v7, "Error", "Cannot bind"); goto clean; } mg_set_protocol_http_websocket(c); c->user_data = ud = (struct user_data *) malloc(sizeof(*ud)); ud->v7 = v7; ud->obj = obj; ud->handler = v7_get(v7, obj, "_cb", 3); v7_own(v7, &ud->obj); clean: return rcode; }
/* * 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); } }
/* * Usage: * * new UART("platform_specific_name") * */ static enum v7_err UART_ctor(struct v7 *v7, v7_val_t *res) { enum v7_err rcode = V7_OK; v7_val_t this_obj = v7_get_this(v7); v7_val_t dev = v7_arg(v7, 0); struct user_data *ud; void *uart; const char *name; size_t len; if (!v7_is_string(dev)) { rcode = v7_throwf(v7, "Error", "device must be string"); goto clean; } ud = (struct user_data *) calloc(1, sizeof(struct user_data)); ud->v7 = v7; ud->want = 0; ud->cb = v7_create_undefined(); v7_own(v7, &ud->cb); name = v7_get_string_data(v7, &dev, &len); uart = sj_hal_open_uart(name, (void *) ud); if (uart == NULL) { rcode = v7_throwf(v7, "Error", "cannot open uart"); goto clean; } v7_set(v7, this_obj, "_ud", ~0, V7_PROPERTY_HIDDEN, v7_create_foreign(ud)); v7_set(v7, this_obj, "_dev", ~0, V7_PROPERTY_HIDDEN, v7_create_foreign(uart)); clean: return rcode; }
static enum v7_err jsSetTimeout(struct v7* v7, v7_val_t* res) { v7_val_t* func = new v7_val_t; v7_own(v7, func); *func = v7_arg(v7, 0); v7_val_t inv = v7_arg(v7, 1); if (!v7_is_callable(v7, *func)) { //TODO: catch error if 1st argument not callable code return V7_OK; } if (!v7_is_number(inv)) { //TODO: catch error if 2nd argument not a number return V7_OK; } double ms = v7_to_number(inv); long lms = floor(ms); //v7_apply(v7, func, _activeBot->getV7Obj(), v7_mk_undefined(), NULL); TIMER* newTimer = new TIMER; newTimer->pToFunc = func; newTimer->delay = lms; newTimer->timeBegin = GetTickCount(); newTimer->id = (long)newTimer; _activeBot->_timers.Add(newTimer); double vOut = (double)newTimer->id; *res = v7_mk_number(vOut); return V7_OK; }
/* Allocate JSON parse frame */ static struct json_parse_frame *alloc_json_frame(struct json_parse_ctx *ctx, v7_val_t v) { struct json_parse_frame *frame = (struct json_parse_frame *) calloc(sizeof(struct json_parse_frame), 1); frame->val = v; v7_own(ctx->v7, &frame->val); return frame; }
void sj_invoke_cb2_this(struct v7 *v7, v7_val_t cb, v7_val_t this_obj, v7_val_t arg1, v7_val_t arg2) { v7_val_t args; v7_own(v7, &cb); v7_own(v7, &arg1); v7_own(v7, &arg2); args = v7_mk_array(v7); v7_own(v7, &args); v7_array_push(v7, args, arg1); v7_array_push(v7, args, arg2); sj_invoke_cb(v7, cb, this_obj, args); v7_disown(v7, &args); v7_disown(v7, &arg2); v7_disown(v7, &arg1); v7_disown(v7, &cb); }
void mg_dispatch_v7_callback(struct v7 *v7, v7_val_t func, v7_val_t this_obj, v7_val_t args) { struct v7_callback_args *cba = (struct v7_callback_args *) calloc(1, sizeof(*cba)); if (cba == NULL) { DBG(("OOM")); return; } cba->v7 = v7; cba->func = func; cba->this_obj = this_obj; cba->args = args; v7_own(v7, &cba->func); v7_own(v7, &cba->this_obj); v7_own(v7, &cba->args); system_os_post(MG_TASK_PRIORITY, MG_SIG_V7_CALLBACK, (uint32_t) cba); }
sj_timer_id sj_set_js_timer(int msecs, int repeat, struct v7 *v7, v7_val_t cb) { struct timer_info *ti = (struct timer_info *) calloc(1, sizeof(*ti)); if (ti == NULL) return SJ_INVALID_TIMER_ID; ti->v7 = v7; ti->js_cb = cb; if (!sj_set_timer(ti, msecs, repeat)) return SJ_INVALID_TIMER_ID; v7_own(v7, &ti->js_cb); return ti->id; }
void miot_console_api_setup(struct v7 *v7) { v7_val_t console_v = v7_mk_object(v7); v7_own(v7, &console_v); v7_set_method(v7, console_v, "log", Console_log); v7_set(v7, v7_get_global(v7), "console", ~0, console_v); v7_disown(v7, &console_v); }
void rtos_dispatch_callback(struct v7 *v7, v7_val_t func, v7_val_t this_obj, v7_val_t args) { struct rtos_event ev; ev.event_id = RTE_CALLBACK; ev.params.callback_params = malloc(sizeof(*ev.params.callback_params)); ev.params.callback_params->v7 = v7; ev.params.callback_params->func = func; v7_own(v7, &ev.params.callback_params->func); ev.params.callback_params->this_obj = this_obj; v7_own(v7, &ev.params.callback_params->this_obj); ev.params.callback_params->args = args; v7_own(v7, &ev.params.callback_params->args); xQueueSend(main_queue_handle, &ev, portMAX_DELAY); }
SJ_PRIVATE enum v7_err GPIO_setISR(struct v7 *v7, v7_val_t *res) { enum v7_err rcode = V7_OK; v7_val_t pinv = v7_arg(v7, 0); v7_val_t typev = v7_arg(v7, 1); v7_val_t cb = v7_arg(v7, 2); v7_val_t current_cb; char prop_name[15]; int pin, type, len, has_isr, new_isr_provided; if (!v7_is_number(pinv) || !v7_is_number(typev)) { printf("Invalid arguments\n"); *res = v7_mk_boolean(v7, 0); goto clean; } pin = v7_get_double(v7, pinv); type = v7_get_double(v7, typev); len = snprintf(prop_name, sizeof(prop_name), "_ih_%d", (int) pin); current_cb = v7_get(v7, v7_get_global(v7), prop_name, len); has_isr = v7_is_callable(v7, current_cb); new_isr_provided = v7_is_callable(v7, cb); if (!has_isr && !new_isr_provided) { printf("Missing callback\n"); *res = v7_mk_boolean(v7, 0); goto clean; }; if (has_isr && new_isr_provided && current_cb != cb) { printf("Only one interruption handler is allowed for pin\n"); *res = v7_mk_boolean(v7, 0); goto clean; } if (type == 0 && has_isr) { v7_set(v7, v7_get_global(v7), prop_name, len, V7_UNDEFINED); } else if (!has_isr && new_isr_provided) { v7_set(v7, v7_get_global(v7), prop_name, len, cb); } if (type != 0 && !s_gpio_intr_installed) { sj_gpio_intr_init(gpio_intr_handler_proxy, v7); s_isr_cb_proxy_v = v7_mk_cfunction(isr_cb_proxy); v7_own(v7, &s_isr_cb_proxy_v); s_gpio_intr_installed = 1; } *res = v7_mk_boolean(v7, sj_gpio_intr_set(pin, (enum gpio_int_mode) type) == 0); goto clean; clean: return rcode; }
void sj_mqtt_api_setup(struct v7 *v7) { v7_val_t mqtt_proto = v7_mk_object(v7); v7_val_t mqtt_connect = v7_mk_function_with_proto(v7, sj_mqtt_connect, mqtt_proto); v7_val_t mqtt; v7_own(v7, &mqtt_connect); mqtt = v7_mk_object(v7); v7_own(v7, &mqtt); v7_set(v7, mqtt, "connect", ~0, mqtt_connect); v7_def(v7, mqtt, "proto", ~0, V7_DESC_ENUMERABLE(0), mqtt_proto); v7_set_method(v7, mqtt_proto, "publish", MQTT_publish); v7_set_method(v7, mqtt_proto, "subscribe", MQTT_subscribe); v7_set_method(v7, mqtt_proto, "on", MQTT_on); v7_set(v7, v7_get_global(v7), "MQTT", ~0, mqtt); v7_disown(v7, &mqtt); v7_disown(v7, &mqtt_connect); }
/* * Construct a new WebSocket object: * * url: url where to connect to * protocol: websocket subprotocol * * Example: * ws = new WebSocket('wss://localhost:1234'); * ws.onopen = function(ev) { * print("ON OPEN", ev); * } * * ws.onclose = function(ev) { * print("ON CLOSE", ev); * } * * ws.onmessage = function(ev) { * print("ON MESSAGE", ev); * } * * ws.onerror = function(ev) { * print("ON ERROR", ev); * } * */ static v7_val_t sj_ws_ctor(struct v7 *v7, v7_val_t this_obj, v7_val_t args) { struct mg_connection *nc; struct user_data *ud; v7_val_t urlv = v7_array_get(v7, args, 0); v7_val_t subprotov = v7_array_get(v7, args, 1); (void) this_obj; (void) args; if (!v7_is_string(urlv)) { v7_throw(v7, "invalid ws url string"); } if (v7_is_object(this_obj) && this_obj != v7_get_global_object(v7)) { int use_ssl = 0; size_t len; const char *url = v7_to_string(v7, &urlv, &len); if (strncmp(url, "ws://", 5) == 0) { url += 5; } else if (strncmp(url, "wss://", 6) == 0) { url += 6; use_ssl = 1; } nc = mg_connect(&sj_mgr, url, ws_ev_handler); if (nc == NULL) v7_throw(v7, "error creating the connection"); #ifdef NS_ENABLE_SSL if (use_ssl) { mg_set_ssl(nc, NULL, NULL); } #endif (void) use_ssl; mg_set_protocol_http_websocket(nc); ud = calloc(1, sizeof(*ud)); ud->v7 = v7; ud->ws = this_obj; nc->user_data = ud; v7_own(v7, &ud->ws); if (v7_is_string(subprotov)) { size_t len; const char *proto = v7_to_string(v7, &subprotov, &len); ud->proto = strdup(proto); } } else { v7_throw(v7, "WebSocket ctor called without new"); } return v7_create_undefined(); }
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_http_init(struct v7 *v7) { v7_val_t Http = v7_mk_undefined(); sj_http_server_proto = v7_mk_undefined(); sj_http_response_proto = v7_mk_undefined(); sj_http_request_proto = v7_mk_undefined(); /* own temporary Http var */ v7_own(v7, &Http); /* other values are owned forever */ v7_own(v7, &sj_http_server_proto); v7_own(v7, &sj_http_response_proto); v7_own(v7, &sj_http_request_proto); Http = v7_get(v7, v7_get_global(v7), "Http", ~0); sj_http_server_proto = v7_get(v7, Http, "_serv", ~0); sj_http_response_proto = v7_get(v7, Http, "_resp", ~0); sj_http_request_proto = v7_get(v7, Http, "_req", ~0); v7_disown(v7, &Http); }
SJ_PRIVATE enum v7_err Http_request_set_timeout(struct v7 *v7, v7_val_t *res) { enum v7_err rcode = V7_OK; DECLARE_CONN(); struct user_data *ud = (struct user_data *) c->user_data; mg_set_timer(c, time(NULL) + v7_to_number(v7_arg(v7, 0)) / 1000.0); ud->timeout_callback = v7_arg(v7, 1); v7_own(v7, &ud->timeout_callback); *res = v7_get_this(v7); clean: return rcode; }
static v7_val_t OS_prof(struct v7 *v7, v7_val_t this_obj, v7_val_t args) { v7_val_t result = v7_create_object(v7); v7_own(v7, &result); v7_set(v7, result, "sysfree", 7, 0, v7_create_number(sj_get_free_heap_size())); v7_set(v7, result, "used_by_js", 10, 0, v7_create_number(v7_heap_stat(v7, V7_HEAP_STAT_HEAP_USED))); v7_set(v7, result, "used_by_fs", 10, 0, v7_create_number(sj_get_fs_memory_usage())); v7_disown(v7, &result); return result; }
/* * Regiter a callback to be invoked when there is at least N bytes available. * N defaults to maxint if undefined */ static enum v7_err UART_recv(struct v7 *v7, v7_val_t *res) { v7_val_t this_obj = v7_get_this(v7); v7_val_t cb = v7_arg(v7, 0); v7_val_t wantv = v7_arg(v7, 1); v7_val_t udv = v7_get(v7, this_obj, "_ud", ~0); size_t want = v7_is_number(wantv) ? (size_t) v7_to_number(wantv) : ~0; struct user_data *ud = (struct user_data *) v7_to_foreign(udv); ud->cb = cb; v7_own(v7, &ud->cb); ud->want = want; /* TODO(mkm): trigger cb if there is already something in the buffer */ return V7_OK; }
void sj_init_ws_client(struct v7 *v7) { v7_val_t ws_proto = v7_create_object(v7); v7_val_t ws = v7_create_constructor(v7, ws_proto, sj_ws_ctor, 1); v7_own(v7, &ws); v7_set_method(v7, ws_proto, "send", WebSocket_send); v7_set_method(v7, ws_proto, "close", WebSocket_close); v7_set(v7, ws_proto, "readyState", ~0, V7_PROPERTY_DONT_ENUM | V7_PROPERTY_GETTER, v7_create_function(v7, WebSocket_readyState, 0)); v7_set(v7, ws, "OPEN", ~0, 0, WEBSOCKET_OPEN); v7_set(v7, ws, "CLOSED", ~0, 0, WEBSOCKET_CLOSED); v7_set(v7, v7_get_global_object(v7), "WebSocket", ~0, 0, ws); v7_disown(v7, &ws); }