static v7_val_t WebSocket_send(struct v7 *v7, v7_val_t this_obj, v7_val_t args) { v7_val_t datav = v7_array_get(v7, args, 0); v7_val_t ncv = v7_get(v7, this_obj, "_nc", ~0); struct mg_connection *nc; /* * TODO(alashkin): check why v7_is_instanceof throws exception * in case of string */ int is_blob = !v7_is_string(datav) && v7_is_instanceof(v7, datav, "Blob"); if (!v7_is_string(datav) && !is_blob) { v7_throw(v7, "arg should be string or Blob"); return v7_create_undefined(); } if (!v7_is_foreign(ncv) || (nc = (struct mg_connection *) v7_to_foreign(ncv)) == NULL) { v7_throw(v7, "ws not connected"); return v7_create_undefined(); } if (is_blob) { _WebSocket_send_blob(v7, nc, datav); } else { _WebSocket_send_string(v7, nc, datav); } return v7_create_undefined(); }
/* * 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(); }
static v7_val_t sj_http_call_helper(struct v7 *v7, v7_val_t urlv, v7_val_t bodyv, v7_val_t cb, const char *method) { const char *body = NULL; size_t url_len, body_len = 0; if (!v7_is_string(urlv)) { v7_throw(v7, "url should be a string"); } if (!v7_is_function(cb)) { v7_throw(v7, "cb must be a function"); } if (v7_is_string(bodyv)) { body = v7_to_string(v7, &bodyv, &body_len); } return v7_create_boolean(sj_http_call(v7, v7_to_string(v7, &urlv, &url_len), body, body_len, method, cb)); }
static v7_val_t WebSocket_send(struct v7 *v7, v7_val_t this_obj, v7_val_t args) { v7_val_t datav = v7_array_get(v7, args, 0); v7_val_t ncv = v7_get(v7, this_obj, "_nc", ~0); struct ns_connection *nc; const char *data; size_t len; if (!v7_is_string(datav)) { v7_throw(v7, "non string data not implemented"); return v7_create_undefined(); } if (!v7_is_foreign(ncv) || (nc = (struct ns_connection *) v7_to_foreign(ncv)) == NULL) { v7_throw(v7, "ws not connected"); return v7_create_undefined(); } data = v7_to_string(v7, &datav, &len); ns_send_websocket_frame(nc, WEBSOCKET_OP_TEXT, data, len); return v7_create_undefined(); }
/* HAL functions */ spi_connection sj_spi_create(struct v7 *v7, v7_val_t args) { struct lnx_spi_connection *conn; v7_val_t spi_no_val = v7_array_get(v7, args, 0); double spi_no = v7_to_number(spi_no_val); ; if (!v7_is_number(spi_no_val) || spi_no < 0) { v7_throw(v7, "Missing arguments for SPI number or wrong type."); } conn = malloc(sizeof(*conn)); conn->spi_no = v7_to_number(spi_no); return conn; }
/* * 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 v7_val_t Http_call(struct v7 *v7, v7_val_t urlv, v7_val_t body, v7_val_t cb, const char *method) { const char *url, *sep; char *psep; size_t url_len; struct espconn *client; struct http_ctx *ctx; if (!v7_is_string(urlv)) { v7_throw(v7, "url is not a string"); } client = (struct espconn *) malloc(sizeof(struct espconn)); if (client == NULL) { printf("malloc failed Http_get\n"); return v7_create_undefined(); } client->type = ESPCONN_TCP; client->state = ESPCONN_NONE; ctx = (struct http_ctx *) calloc(sizeof(struct http_ctx), 1); if (ctx == NULL) { printf("malloc failed Http_get\n"); free(client); return v7_create_undefined(); } client->proto.tcp = (esp_tcp *) ctx; url = v7_to_string(v7, &urlv, &url_len); if (memcmp(url, "http://", 7) == 0) { url += 7; } ctx->host[0] = ctx->path[0] = '\0'; if ((sep = strchr(url, '/')) == NULL) { sep = url + strlen(url); ctx->path[0] = '/'; ctx->path[1] = '\0'; } strncpy(ctx->host, url, sep - url); ctx->host[sep - url] = '\0'; strcpy(ctx->path, sep); if (strlen(sep) == 0) strcpy(ctx->path, "/"); ctx->port = 80; if ((psep = strchr(ctx->host, ':')) != NULL) { *psep++ = '\0'; /* chop off port from host */ ctx->port = atoi(psep); } ctx->method = method; ctx->cb = cb; /* to be disowned after invoking the callback */ v7_own(v7, &ctx->cb); ctx->body = body; /* to be disowned after sending the request */ v7_own(v7, &ctx->body); espconn_gethostbyname(client, ctx->host, &probably_dns_ip, http_get_dns_cb); return v7_create_undefined(); }