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); }
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); }
/* * 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; } } }
/* * Returns an object describing the free memory. * * sysfree: free system heap bytes * jssize: size of JS heap in bytes * jsfree: free JS heap bytes * strres: size of reserved string heap in bytes * struse: portion of string heap with used data * objnfree: number of free object slots in js heap * propnfree: number of free property slots in js heap * funcnfree: number of free function slots in js heap */ SJ_PRIVATE enum v7_err GC_stat(struct v7 *v7, v7_val_t *res) { /* take a snapshot of the stats that would change as we populate the result */ size_t sysfree = sj_get_free_heap_size(); size_t jssize = v7_heap_stat(v7, V7_HEAP_STAT_HEAP_SIZE); size_t jsfree = jssize - v7_heap_stat(v7, V7_HEAP_STAT_HEAP_USED); size_t strres = v7_heap_stat(v7, V7_HEAP_STAT_STRING_HEAP_RESERVED); size_t struse = v7_heap_stat(v7, V7_HEAP_STAT_STRING_HEAP_USED); size_t objfree = v7_heap_stat(v7, V7_HEAP_STAT_OBJ_HEAP_FREE); size_t propnfree = v7_heap_stat(v7, V7_HEAP_STAT_PROP_HEAP_FREE); *res = v7_mk_object(v7); v7_set(v7, *res, "sysfree", ~0, v7_mk_number(sysfree)); v7_set(v7, *res, "jssize", ~0, v7_mk_number(jssize)); v7_set(v7, *res, "jsfree", ~0, v7_mk_number(jsfree)); v7_set(v7, *res, "strres", ~0, v7_mk_number(strres)); v7_set(v7, *res, "struse", ~0, v7_mk_number(struse)); v7_set(v7, *res, "objfree", ~0, v7_mk_number(objfree)); v7_set(v7, *res, "objncell", ~0, v7_mk_number(v7_heap_stat(v7, V7_HEAP_STAT_OBJ_HEAP_CELL_SIZE))); v7_set(v7, *res, "propnfree", ~0, v7_mk_number(propnfree)); v7_set(v7, *res, "propncell", ~0, v7_mk_number(v7_heap_stat(v7, V7_HEAP_STAT_PROP_HEAP_CELL_SIZE))); v7_set(v7, *res, "funcnfree", ~0, v7_mk_number(v7_heap_stat(v7, V7_HEAP_STAT_FUNC_HEAP_FREE))); v7_set(v7, *res, "funcncell", ~0, v7_mk_number(v7_heap_stat(v7, V7_HEAP_STAT_FUNC_HEAP_CELL_SIZE))); v7_set(v7, *res, "astsize", ~0, v7_mk_number(v7_heap_stat(v7, V7_HEAP_STAT_FUNC_AST_SIZE))); v7_set(v7, *res, "owned", ~0, v7_mk_number(v7_heap_stat(v7, V7_HEAP_STAT_FUNC_OWNED))); v7_set(v7, *res, "owned_max", ~0, v7_mk_number(v7_heap_stat(v7, V7_HEAP_STAT_FUNC_OWNED_MAX))); return V7_OK; }
void Bot::onJoin(bot_exchange_format& f) { long l = _onJoin.GetLength(); if (l == 0) return; v7_val_t user = v7_mk_object(v7); v7_val_t userName = v7_mk_string(v7, std::string(f[1]).c_str(), ~0, 1); v7_set(v7, user, "name", ~0, userName); v7_val_t flags = v7_mk_number((u_long)f[2]); v7_set(v7, user, "flags", ~0, flags); v7_val_t age = v7_mk_number((u_char)f[3]); v7_set(v7, user, "age", ~0, age); v7_val_t count = v7_mk_number((int)f[4]); v7_set(v7, user, "count", ~0, count); v7_val_t gifts = v7_mk_number((u_long)f[5]); v7_set(v7, user, "gifts", ~0, gifts); long i; v7_val_t* func; v7_val_t args; for (i = 0; i < l; i++) { func = (v7_val_t*)_onJoin.GetAt(i); args = v7_mk_array(v7); v7_array_push(v7, args, user); v7_apply(v7, *func, *v7Obj, args, NULL); } }
int main(void) { enum v7_err rcode = V7_OK; struct v7 *v7 = v7_create(); v7_val_t ctor_func, proto, eval_result; proto = v7_mk_object(v7); ctor_func = v7_mk_function_with_proto(v7, MyThing_ctor, proto); v7_def(v7, ctor_func, "MY_CONST", ~0, (V7_DESC_WRITABLE(0) | V7_DESC_CONFIGURABLE(0)), v7_mk_number(123)); v7_set_method(v7, proto, "myMethod", &MyThing_myMethod); v7_set(v7, v7_get_global(v7), "MyThing", ~0, ctor_func); rcode = v7_exec(v7, "\ print('MyThing.MY_CONST = ', MyThing.MY_CONST); \ var t = new MyThing(456); \ print('t.MY_CONST = ', t.MY_CONST); \ print('t.myMethod = ', t.myMethod); \ print('t.myMethod() = ', t.myMethod());", &eval_result); if (rcode != V7_OK) { fprintf(stderr, "exec error: %d\n", (int) rcode); } v7_destroy(v7); return (int) rcode; }
void sj_gpio_api_setup(struct v7 *v7) { v7_val_t gpio = v7_mk_object(v7); v7_set(v7, v7_get_global(v7), "GPIO", ~0, gpio); v7_set_method(v7, gpio, "setMode", GPIO_setMode); v7_set_method(v7, gpio, "read", GPIO_read); v7_set_method(v7, gpio, "write", GPIO_write); v7_set_method(v7, gpio, "setISR", GPIO_setISR); v7_set(v7, gpio, "INOUT", ~0, v7_mk_number(v7, GPIO_MODE_INOUT)); v7_set(v7, gpio, "IN", ~0, v7_mk_number(v7, GPIO_MODE_INPUT)); v7_set(v7, gpio, "OUT", ~0, v7_mk_number(v7, GPIO_MODE_OUTPUT)); v7_set(v7, gpio, "FLOAT", ~0, v7_mk_number(v7, GPIO_PULL_FLOAT)); v7_set(v7, gpio, "PULLUP", ~0, v7_mk_number(v7, GPIO_PULL_PULLUP)); v7_set(v7, gpio, "PULLDOWN", ~0, v7_mk_number(v7, GPIO_PULL_PULLDOWN)); v7_set(v7, gpio, "OFF", ~0, v7_mk_number(v7, GPIO_INTR_OFF)); v7_set(v7, gpio, "POSEDGE", ~0, v7_mk_number(v7, GPIO_INTR_POSEDGE)); v7_set(v7, gpio, "NEGEDGE", ~0, v7_mk_number(v7, GPIO_INTR_NEGEDGE)); v7_set(v7, gpio, "ANYEDGE", ~0, v7_mk_number(v7, GPIO_INTR_ANYEDGE)); v7_set(v7, gpio, "LOLEVEL", ~0, v7_mk_number(v7, GPIO_INTR_LOLEVEL)); v7_set(v7, gpio, "HILEVEL", ~0, v7_mk_number(v7, GPIO_INTR_HILEVEL)); /* * TODO(mkm): figure out what to do with this "esp specific" mode. * It's not really ESP specific, but the soft debouncer is currently * implemented in esp8266 platform code. */ v7_set(v7, gpio, "CLICK", ~0, v7_mk_number(v7, 6 /* GPIO_INTR_TYPE_ONCLICK */)); if (v7_exec_file(v7, "gpio.js", NULL) != V7_OK) { /* TODO(mkm): make setup functions return an error code */ abort(); } }
void sj_sys_js_init(struct v7 *v7) { v7_val_t sys, fs; sys = v7_mk_object(v7); v7_set(v7, v7_get_global(v7), "Sys", ~0, sys); v7_set_method(v7, sys, "prof", Sys_prof); v7_set_method(v7, sys, "reboot", Sys_reboot); v7_set_method(v7, sys, "setLogLevel", Sys_setLogLevel); v7_set_method(v7, sys, "time", Sys_time); v7_set_method(v7, sys, "wdtFeed", Sys_wdtFeed); v7_set_method(v7, sys, "wdtSetTimeout", Sys_wdtSetTimeout); v7_set_method(v7, sys, "wdtEnable", Sys_wdtEnable); v7_set_method(v7, sys, "wdtDisable", Sys_wdtDisable); fs = v7_mk_object(v7); v7_set(v7, sys, "fs", ~0, fs); v7_set_method(v7, fs, "free", Sys_fs_getFreeSpace); }
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 sj_gpio_api_setup(struct v7 *v7) { s_v7 = v7; v7_val_t gpio = v7_mk_object(v7); v7_set(v7, v7_get_global(v7), "GPIO", ~0, gpio); v7_set_method(v7, gpio, "setmode", GPIO_setmode); v7_set_method(v7, gpio, "read", GPIO_read); v7_set_method(v7, gpio, "write", GPIO_write); v7_set_method(v7, gpio, "setisr", GPIO_setisr); }
void sj_init_sys(struct v7 *v7) { v7_val_t sys; sys = v7_mk_object(v7); v7_set(v7, v7_get_global(v7), "Sys", ~0, sys); v7_set_method(v7, sys, "prof", Sys_prof); v7_set_method(v7, sys, "wdtFeed", Sys_wdtFeed); v7_set_method(v7, sys, "reboot", Sys_reboot); v7_set_method(v7, sys, "setLogLevel", Sys_setLogLevel); }
static void export_read_only_vars_to_v7(struct v7 *v7) { struct ro_var *rv; if (v7 == NULL) return; v7_val_t obj = v7_mk_object(v7); for (rv = g_ro_vars; rv != NULL; rv = rv->next) { v7_set(v7, obj, rv->name, ~0, v7_mk_string(v7, *rv->ptr, ~0, 1)); } v7_val_t Sys = v7_get(v7, v7_get_global(v7), "Sys", ~0); v7_set(v7, Sys, "ro_vars", ~0, obj); }
static enum v7_err Sys_prof(struct v7 *v7, v7_val_t *res) { *res = v7_mk_object(v7); v7_set(v7, *res, "sysfree", 7, v7_mk_number(sj_get_free_heap_size())); v7_set(v7, *res, "used_by_js", 10, v7_mk_number(v7_heap_stat(v7, V7_HEAP_STAT_HEAP_USED))); v7_set(v7, *res, "used_by_fs", 10, v7_mk_number(sj_get_fs_memory_usage())); return V7_OK; }
void sj_v7_ext_api_setup(struct v7 *v7) { v7_val_t gc; v7_set_method(v7, v7_get_global(v7), "usleep", global_usleep); gc = v7_mk_object(v7); v7_set(v7, v7_get_global(v7), "GC", ~0, gc); v7_set_method(v7, gc, "stat", GC_stat); v7_set_method(v7, gc, "gc", GC_gc); }
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); }
void Bot::onText(bot_exchange_format& f) { long i, l; l = _onTexts.GetLength(); std::string nick = std::string(f[1]); std::string text = std::string(f[2]); v7_val_t attr; if ((u_char)f[3] == 0) { attr = v7_mk_undefined(); } else { attr = v7_mk_object(v7); v7_val_t size = v7_mk_number((u_char)f[4]); v7_set(v7, attr, "size", ~0, size); COLORREF col = (u_long)f[5]; int r = GetRValue(col); int g = GetGValue(col); int b = GetBValue(col); char strCol[8]; sprintf(strCol, "#%02X%02X%02X", r, g, b); v7_val_t color = v7_mk_string(v7, strCol, ~0, 1); v7_set(v7, attr, "color", ~0, color); v7_val_t effects = v7_mk_number((u_long)f[6]); v7_set(v7, attr, "effects", ~0, effects); v7_val_t charset = v7_mk_number((u_char)f[7]); v7_set(v7, attr, "charset", ~0, charset); v7_val_t pitch = v7_mk_number((u_char)f[8]); v7_set(v7, attr, "pitch", ~0, pitch); std::string font = std::string(f[9]); v7_val_t fontName = v7_mk_string(v7, font.c_str(), ~0, 1); v7_set(v7, attr, "font", ~0, fontName); } v7_val_t nickName = v7_mk_string(v7, nick.c_str(), ~0, 0); v7_val_t fullText = v7_mk_string(v7, text.c_str(), ~0, 0); for (i = 0; i < l; i++) { v7_val_t* func = (v7_val_t*)_onTexts.GetAt(i); v7_val_t args; args = v7_mk_array(v7); v7_array_push(v7, args, nickName); v7_array_push(v7, args, fullText); v7_array_push(v7, args, attr); v7_apply(v7, *func, *v7Obj, args, NULL); } }
SJ_PRIVATE enum v7_err Http_createServer(struct v7 *v7, v7_val_t *res) { enum v7_err rcode = V7_OK; v7_val_t cb = v7_arg(v7, 0); if (!v7_is_callable(v7, cb)) { rcode = v7_throwf(v7, "Error", "Invalid argument"); goto clean; } *res = v7_mk_object(v7); v7_set_proto(v7, *res, sj_http_server_proto); v7_set(v7, *res, "_cb", ~0, cb); clean: return rcode; }
void init_updater_clubby(struct v7 *v7) { (void) v7; #ifndef DISABLE_C_CLUBBY #ifndef CS_DISABLE_JS s_v7 = v7; v7_val_t updater = v7_mk_object(v7); v7_val_t sys = v7_get(v7, v7_get_global(v7), "Sys", ~0); s_updater_notify_cb = V7_UNDEFINED; v7_own(v7, &s_updater_notify_cb); v7_def(v7, sys, "updater", ~0, V7_DESC_ENUMERABLE(0), updater); v7_set_method(v7, updater, "notify", Updater_notify); v7_set_method(v7, updater, "start", Updater_startupdate); v7_def(s_v7, updater, "GOT_REQUEST", ~0, (V7_DESC_WRITABLE(0) | V7_DESC_CONFIGURABLE(0)), v7_mk_number(v7, UJS_GOT_REQUEST)); v7_def(s_v7, updater, "COMPLETED", ~0, (V7_DESC_WRITABLE(0) | V7_DESC_CONFIGURABLE(0)), v7_mk_number(v7, UJS_COMPLETED)); v7_def(s_v7, updater, "NOTHING_TODO", ~0, (V7_DESC_WRITABLE(0) | V7_DESC_CONFIGURABLE(0)), v7_mk_number(v7, UJS_NOTHING_TODO)); v7_def(s_v7, updater, "FAILED", ~0, (V7_DESC_WRITABLE(0) | V7_DESC_CONFIGURABLE(0)), v7_mk_number(v7, UJS_ERROR)); #endif sj_clubby_register_global_command("/v1/SWUpdate.Update", handle_update_req, NULL); sj_clubby_register_global_command(clubby_cmd_ready, handle_clubby_ready, NULL); #endif }
static void setup_request_object(struct v7 *v7, v7_val_t request, struct http_message *hm) { int i, qslen = hm->query_string.len; v7_val_t headers = v7_mk_object(v7); /* TODO(lsm): implement as getters to save memory */ v7_set(v7, request, "headers", ~0, headers); v7_set(v7, request, "method", ~0, v7_mk_string(v7, hm->method.p, hm->method.len, 1)); v7_set(v7, request, "url", ~0, v7_mk_string(v7, hm->uri.p, hm->uri.len + (qslen == 0 ? 0 : qslen + 1), 1)); v7_set(v7, request, "body", ~0, v7_mk_string(v7, hm->body.p, hm->body.len, 1)); for (i = 0; hm->header_names[i].len > 0; i++) { const struct mg_str *name = &hm->header_names[i]; const struct mg_str *value = &hm->header_values[i]; v7_set(v7, headers, name->p, name->len, v7_mk_string(v7, value->p, value->len, 1)); } }
void sj_wifi_api_setup(struct v7 *v7) { v7_val_t s_wifi = v7_mk_object(v7); v7_own(v7, &s_wifi); v7_set_method(v7, s_wifi, "setup", sj_Wifi_setup); v7_set_method(v7, s_wifi, "connect", Wifi_connect); v7_set_method(v7, s_wifi, "disconnect", Wifi_disconnect); v7_set_method(v7, s_wifi, "status", Wifi_status); v7_set_method(v7, s_wifi, "show", Wifi_show); v7_set_method(v7, s_wifi, "ip", Wifi_ip); v7_set_method(v7, s_wifi, "changed", Wifi_changed); v7_set_method(v7, s_wifi, "scan", Wifi_scan); v7_set_method(v7, s_wifi, "ready", Wifi_ready); v7_set(v7, v7_get_global(v7), "Wifi", ~0, s_wifi); v7_set(v7, s_wifi, "CONNECTED", ~0, v7_mk_number(v7, SJ_WIFI_CONNECTED)); v7_set(v7, s_wifi, "DISCONNECTED", ~0, v7_mk_number(v7, SJ_WIFI_DISCONNECTED)); v7_set(v7, s_wifi, "GOTIP", ~0, v7_mk_number(v7, SJ_WIFI_IP_ACQUIRED)); v7_disown(v7, &s_wifi); }
void init_adcjs(struct v7 *v7) { v7_val_t adc = v7_mk_object(v7); v7_set(v7, v7_get_global(v7), "ADC", ~0, adc); v7_set_method(v7, adc, "read", ADC_read); v7_set_method(v7, adc, "readVoltage", ADC_readVoltage); }
/* * Create request object, used by `Http.request()` and `Http.get()` */ WARN_UNUSED_RESULT static enum v7_err sj_http_request_common(struct v7 *v7, v7_val_t opts, v7_val_t cb, v7_val_t *res) { enum v7_err rcode = V7_OK; char addr[200]; struct mg_connection *c; struct user_data *ud; struct mg_connect_opts copts; #ifdef MG_ENABLE_SSL int force_ssl; #endif memset(&copts, 0, sizeof(copts)); /* * Determine type of provided `opts`, and if it's a string, then parse * it to object */ if (v7_is_string(opts)) { rcode = sj_url_parse(v7, opts, &opts); if (rcode != V7_OK) { goto clean; } } else if (!v7_is_object(opts)) { rcode = v7_throwf(v7, "Error", "opts must be an object or a string URL"); goto clean; } /* * Now, `opts` is guaranteed to be an object. * Let's retrieve needed properties */ v7_val_t v_h = v7_get(v7, opts, "hostname", ~0); if (v7_is_undefined(v_h)) { v_h = v7_get(v7, opts, "host", ~0); } v7_val_t v_p = v7_get(v7, opts, "port", ~0); v7_val_t v_uri = v7_get(v7, opts, "path", ~0); v7_val_t v_m = v7_get(v7, opts, "method", ~0); v7_val_t v_hdrs = v7_get(v7, opts, "headers", ~0); /* Perform options validation and set defaults if needed */ int port = v7_is_number(v_p) ? v7_to_number(v_p) : 80; const char *host = v7_is_string(v_h) ? v7_to_cstring(v7, &v_h) : ""; const char *uri = v7_is_string(v_uri) ? v7_to_cstring(v7, &v_uri) : "/"; const char *method = v7_is_string(v_m) ? v7_to_cstring(v7, &v_m) : "GET"; #ifdef MG_ENABLE_SSL v7_val_t v_pr = v7_get(v7, opts, "protocol", ~0); const char *protocol = v7_is_string(v_pr) ? v7_to_cstring(v7, &v_pr) : ""; force_ssl = (strcasecmp(protocol, "https") == 0); if ((rcode = fill_ssl_connect_opts(v7, opts, force_ssl, &copts)) != V7_OK) { goto clean; } #endif /* Compose address like host:port */ snprintf(addr, sizeof(addr), "%s:%d", host, port); /* * Try to connect, passing `http_ev_handler` as the callback, which will * call provided JavaScript function (we'll set it in user data below). * TODO(alashkin): change mg_connect_opt to mg_connect_http_opt */ if ((c = mg_connect_opt(&sj_mgr, addr, http_ev_handler, copts)) == NULL) { rcode = v7_throwf(v7, "Error", "Cannot connect"); goto clean; } /* * Attach mongoose's built-in HTTP event handler to the connection, and send * necessary headers */ mg_set_protocol_http_websocket(c); mg_printf(c, "%s %s HTTP/1.1\r\n", method, uri); mg_printf(c, "Host: %s\r\n", host); http_write_headers(v7, v_hdrs, c); http_write_chunked_encoding_header(c); mg_printf(c, "%s", "\r\n"); /* * Allocate and initialize user data structure that is used by the JS HTTP * interface. Create the request object (which will have the request * prototype `sj_http_request_proto`), and set provided callback function. */ c->user_data = ud = (struct user_data *) calloc(1, sizeof(*ud)); ud->v7 = v7; ud->obj = v7_mk_object(v7); ud->handler = cb; v7_own(v7, &ud->obj); v7_set_proto(v7, ud->obj, sj_http_request_proto); /* internal property: mongoose connection */ v7_set(v7, ud->obj, "_c", ~0, v7_mk_foreign(c)); /* internal property: callback function that was passed as an argument */ v7_set(v7, ud->obj, "_cb", ~0, ud->handler); *res = ud->obj; clean: return rcode; }
/* * Make a new MQTT client. * * Arguments: * url: url where to connect to * opts: option object * * Recognized option object properties: * * - clientId: string; mqtt client id. defaults to * Math.random().toString(16).substr(2, 10) * * Example: * * var client = MQTT.connect('mqtt://test.mosquitto.org'); * * client.on('connect', function () { * client.subscribe('presence'); * client.publish('presence', 'Hello mqtt'); * }); * * client.on('message', function (topic, message) { * console.log(message); * }); * * TLS can be enabled by choosing the `mqtts://` protocol. In that * case the default port is 8883 as defined by IANA. * * The API is modeled after https://www.npmjs.com/package/mqtt. * */ enum v7_err sj_mqtt_connect(struct v7 *v7, v7_val_t *res) { enum v7_err rcode = V7_OK; const char *url; size_t len; struct mg_str host, scheme; unsigned int port; struct mg_connection *nc; struct user_data *ud; char *url_with_port = NULL; int use_ssl = 0; v7_val_t urlv = v7_arg(v7, 0), opts = v7_arg(v7, 1); v7_val_t client_id; v7_val_t proto = v7_get(v7, v7_get(v7, v7_get_global(v7), "MQTT", ~0), "proto", ~0); if (!v7_is_string(urlv)) { rcode = v7_throwf(v7, "Error", "invalid url string"); goto clean; } url = v7_get_string(v7, &urlv, &len); if (mg_parse_uri(mg_mk_str(url), &scheme, NULL, &host, &port, NULL, NULL, NULL) < 0) { rcode = v7_throwf(v7, "Error", "invalid url string"); goto clean; } if (mg_vcmp(&scheme, "mqtt") == 0) { url += sizeof("mqtt://") - 1; } else if (mg_vcmp(&scheme, "mqtts") == 0) { url += sizeof("mqtts://") - 1; use_ssl = 1; } else { rcode = v7_throwf(v7, "Error", "unsupported protocol"); goto clean; } client_id = v7_get(v7, opts, "clientId", ~0); if (v7_is_undefined(client_id)) { rcode = v7_exec(v7, "Math.random().toString(16).substr(2,8)", &client_id); if (rcode != V7_OK) { goto clean; } } if (port == 0) { if (asprintf(&url_with_port, "%.*s%s", (int) host.len, host.p, (use_ssl ? ":8883" : ":1883")) < 0) { rcode = v7_throwf(v7, "Error", "Out of memory"); goto clean; } } nc = mg_connect(&sj_mgr, url_with_port ? url_with_port : url, mqtt_ev_handler); if (nc == NULL) { rcode = v7_throwf(v7, "Error", "cannot create connection"); goto clean; } if (use_ssl) { #ifdef MG_ENABLE_SSL mg_set_ssl(nc, NULL, NULL); #else rcode = v7_throwf(v7, "Error", "SSL not enabled"); goto clean; #endif } mg_set_protocol_mqtt(nc); *res = v7_mk_object(v7); v7_set_proto(v7, *res, proto); ud = calloc(1, sizeof(*ud)); if (ud == NULL) { rcode = v7_throwf(v7, "Error", "Out of memory"); goto clean; } ud->v7 = v7; ud->client = *res; ud->client_id = strdup(v7_get_cstring(v7, &client_id)); if (ud->client_id == NULL) { free(ud); rcode = v7_throwf(v7, "Error", "Out of memory"); goto clean; } nc->user_data = ud; v7_own(v7, &ud->client); v7_def(v7, *res, "_nc", ~0, _V7_DESC_HIDDEN(1), v7_mk_foreign(v7, nc)); clean: free(url_with_port); return rcode; }
/* * Parse URL; used for: * * - `URL.parse()` * - `Http.request()` and `Http.get()`, when provided `opts` is a string. */ static enum v7_err sj_url_parse(struct v7 *v7, v7_val_t url_v, v7_val_t *res) { enum v7_err rcode = V7_OK; v7_val_t opts, protocol_v; size_t i, j, len; int state = 0; const char *url; if (!v7_is_string(url_v)) { rcode = v7_throwf(v7, "TypeError", "URL must be a string"); goto clean; } url = v7_get_string_data(v7, &url_v, &len); opts = v7_mk_object(v7); for (i = j = 0; j < len; j++) { switch (state) { case 0: if (url[j] == '/') { protocol_v = v7_mk_string(v7, url + i, j - i - 1, 1); v7_set(v7, opts, "protocol", ~0, protocol_v); j += 1; i = j + 1; state = 1; } break; case 1: if (url[j] == '/' || (j > i && url[j] == ':') || j == len - 1) { int hl = j - i; if (j == len - 1 && url[j] != '/' && url[j] != ':') hl++; v7_set(v7, opts, "hostname", ~0, v7_mk_string(v7, url + i, hl, 1)); if (url[j] == '/' || j == len - 1) { const char *protocol = v7_to_cstring(v7, &protocol_v); int port = strcasecmp(protocol, "https") == 0 ? 443 : 80; v7_set(v7, opts, "port", ~0, v7_mk_number(port)); i = j; if (j == len - 1) j--; state = 3; } else { i = j + 1; state = 2; } } break; case 2: if (url[j] == '/' || j == len - 1) { char ps[6]; size_t l = j - i; if (j == len - 1) l++; if (l > sizeof(ps) - 1) l = sizeof(ps) - 1; memcpy(ps, url + i, l); ps[l] = '\0'; v7_set(v7, opts, "port", ~0, v7_mk_number(atoi(ps))); i = j; if (j == len - 1) j--; state = 3; } break; case 3: if (j == len - 1) { v7_val_t path_v = j - i > 0 ? v7_mk_string(v7, url + i, j - i + 1, 1) : v7_mk_string(v7, "/", 1, 1); v7_set(v7, opts, "path", ~0, path_v); } break; } } *res = opts; clean: return rcode; }
Bot::Bot(bot_manager* mgr, const char* name, const char* workDir) { _mgr = mgr; _name = name; /*_workDir = std::string(ExePath()).c_str(); _workDir += L"\\plugins\\BMP\\"; TString botNamee = name; botNamee.ToUpper(); _workDir += botNamee.GetAsWChar(); MessageBox(NULL, _workDir.GetAsChar(), "Work Dir", 0);*/ setActive(); _workDir = workDir; _workDir += L"bmp\\"; bool isScriptOk = true; if (!EnsureDirExists(_workDir.GetAsWChar())) { isScriptOk = false; } _charset.color = RGB(0xff, 0x99, 0x00); _activeBot = this; _scriptFile = _workDir.GetAsWChar(); _scriptFile += L"main.js"; if (isScriptOk && !FileExists(std::string(_scriptFile.GetAsChar()))) { TString strSay = L"BMP Plugin will not work, please put file 'main.js' into work dir. ("; strSay += _scriptFile.GetAsWChar(); strSay += L")"; //say(strSay); MessageBox(NULL, strSay.GetAsChar(), "BMP Bot Alert", 0); isScriptOk = false; } v7 = v7_create(); enum v7_err rcode = V7_OK; v7_val_t result; //events function define v7_set_method(v7, v7_get_global(v7), "on", (v7_cfunction_t*)&jsBotEvent); //utilities functions v7_set_method(v7, v7_get_global(v7), "say", (v7_cfunction_t*)&jsBotSay); v7_set_method(v7, v7_get_global(v7), "setTimeout", (v7_cfunction_t*)&jsSetTimeout); v7_set_method(v7, v7_get_global(v7), "setInterval", (v7_cfunction_t*)&jsSetInterval); v7_set_method(v7, v7_get_global(v7), "clearTimeout", (v7_cfunction_t*)&jsClearTimeout); v7_set_method(v7, v7_get_global(v7), "clearInterval", (v7_cfunction_t*)&jsClearInterval); botObj = new v7_val_t; v7_own(v7, botObj); *botObj = v7_mk_object(v7); v7_val_t botName = v7_mk_string(v7, name, ~0, 1); v7_set(v7, *botObj, "name", ~0, botName); v7_set(v7, v7_get_global(v7), "BOT", ~0, *botObj); v7_set_method(v7, *botObj, "setFontStyle", (v7_cfunction_t*)&jsBotFontStyle); v7_set_method(v7, *botObj, "load", (v7_cfunction_t*)&jsBotLoadFile); //rcode = v7_exec(v7, "var a = \"aaa\"; say(a); print(\"Yeah\");", &result); if (isScriptOk) { rcode = v7_exec_file(v7, _scriptFile.GetAsChar(), &result); if (rcode != V7_OK) { if (result == V7_SYNTAX_ERROR) MessageBox(NULL, "script fail syntax error", "Nooo", 0); else if (result == V7_EXEC_EXCEPTION) MessageBox(NULL, "script fail, exception", "Nooo", 0); else if (result == V7_EXEC_EXCEPTION) MessageBox(NULL, "script fail, exception", "Nooo", 0); else if (result == V7_AST_TOO_LARGE) MessageBox(NULL, "script fail, ast too large", "Nooo", 0); } else { v7_val_t vObj; v7_own(v7, &vObj); vObj = v7_mk_object(v7); v7Obj = &vObj; } } }
/* Callback for json_walk() */ static void frozen_cb(void *data, const char *name, size_t name_len, const char *path, const struct json_token *token) { struct json_parse_ctx *ctx = (struct json_parse_ctx *) data; v7_val_t v = V7_UNDEFINED; (void) path; v7_own(ctx->v7, &v); switch (token->type) { case JSON_TYPE_STRING: v = v7_mk_string(ctx->v7, token->ptr, token->len, 1 /* copy */); break; case JSON_TYPE_NUMBER: v = v7_mk_number(ctx->v7, cs_strtod(token->ptr, NULL)); break; case JSON_TYPE_TRUE: v = v7_mk_boolean(ctx->v7, 1); break; case JSON_TYPE_FALSE: v = v7_mk_boolean(ctx->v7, 0); break; case JSON_TYPE_NULL: v = V7_NULL; break; case JSON_TYPE_OBJECT_START: v = v7_mk_object(ctx->v7); break; case JSON_TYPE_ARRAY_START: v = v7_mk_array(ctx->v7); break; case JSON_TYPE_OBJECT_END: case JSON_TYPE_ARRAY_END: { /* Object or array has finished: deallocate its frame */ ctx->frame = free_json_frame(ctx, ctx->frame); } break; default: LOG(LL_ERROR, ("Wrong token type %d\n", token->type)); break; } if (!v7_is_undefined(v)) { if (name != NULL && name_len != 0) { /* Need to define a property on the current object/array */ if (v7_is_object(ctx->frame->val)) { v7_set(ctx->v7, ctx->frame->val, name, name_len, v); } else if (v7_is_array(ctx->v7, ctx->frame->val)) { /* * TODO(dfrank): consult name_len. Currently it's not a problem due to * the implementation details of frozen, but it might change */ int idx = (int) cs_strtod(name, NULL); v7_array_set(ctx->v7, ctx->frame->val, idx, v); } else { LOG(LL_ERROR, ("Current value is neither object nor array\n")); } } else { /* This is a root value */ assert(ctx->frame == NULL); /* * This value will also be the overall result of JSON parsing * (it's already owned by the `v7_alt_json_parse()`) */ ctx->result = v; } if (token->type == JSON_TYPE_OBJECT_START || token->type == JSON_TYPE_ARRAY_START) { /* New object or array has just started, so we need to allocate a frame * for it */ struct json_parse_frame *new_frame = alloc_json_frame(ctx, v); new_frame->up = ctx->frame; ctx->frame = new_frame; } } v7_disown(ctx->v7, &v); }
void sj_http_api_setup(struct v7 *v7) { v7_val_t Http = v7_mk_undefined(); v7_val_t URL = v7_mk_undefined(); sj_http_server_proto = v7_mk_undefined(); sj_http_response_proto = v7_mk_undefined(); sj_http_request_proto = v7_mk_undefined(); /* * All values are owned temporarily: static values like * `sj_http_server_proto` will be owned later forever, in `sj_http_init()`. * * This is needed to support freezing */ v7_own(v7, &Http); v7_own(v7, &URL); v7_own(v7, &sj_http_server_proto); v7_own(v7, &sj_http_response_proto); v7_own(v7, &sj_http_request_proto); sj_http_server_proto = v7_mk_object(v7); sj_http_response_proto = v7_mk_object(v7); sj_http_request_proto = v7_mk_object(v7); /* NOTE(lsm): setting Http to globals immediately to avoid gc-ing it */ Http = v7_mk_object(v7); v7_set(v7, v7_get_global(v7), "Http", ~0, Http); v7_set(v7, Http, "_serv", ~0, sj_http_server_proto); v7_set(v7, Http, "_resp", ~0, sj_http_response_proto); v7_set(v7, Http, "_req", ~0, sj_http_request_proto); v7_set_method(v7, Http, "createServer", Http_createServer); v7_set_method(v7, Http, "get", Http_get); v7_set_method(v7, Http, "request", Http_createClient); v7_set_method(v7, sj_http_server_proto, "listen", Http_Server_listen); /* Initialize response prototype */ v7_set_method(v7, sj_http_response_proto, "writeHead", Http_response_writeHead); v7_set_method(v7, sj_http_response_proto, "write", Http_response_write); v7_set_method(v7, sj_http_response_proto, "end", Http_response_end); v7_set_method(v7, sj_http_response_proto, "serve", Http_response_serve); /* Initialize request prototype */ v7_set_method(v7, sj_http_request_proto, "write", Http_request_write); v7_set_method(v7, sj_http_request_proto, "end", Http_request_end); v7_set_method(v7, sj_http_request_proto, "abort", Http_request_abort); v7_set_method(v7, sj_http_request_proto, "setTimeout", Http_request_set_timeout); URL = v7_mk_object(v7); v7_set(v7, v7_get_global(v7), "URL", ~0, URL); v7_set_method(v7, URL, "parse", URL_parse); v7_disown(v7, &sj_http_request_proto); v7_disown(v7, &sj_http_response_proto); v7_disown(v7, &sj_http_server_proto); v7_disown(v7, &URL); v7_disown(v7, &Http); }