/*JSON{ "type" : "method", "class" : "Object", "name" : "removeListener", "generate" : "jswrap_object_removeListener", "params" : [ ["event","JsVar","The name of the event, for instance 'data'"], ["listener","JsVar","The listener to remove"] ] } Removes the specified event listener. ``` function foo(d) { console.log(d); } Serial1.on("data", foo); Serial1.removeListener("data", foo); ``` */ void jswrap_object_removeListener(JsVar *parent, JsVar *event, JsVar *callback) { if (!jsvHasChildren(parent)) { jsWarn("Parent must be an object - not a String, Integer, etc."); return; } if (jsvIsString(event)) { // remove the whole child containing listeners JsVar *eventName = jsvVarPrintf(JS_EVENT_PREFIX"%s",event); if (!eventName) return; // no memory JsVar *eventListName = jsvFindChildFromVar(parent, eventName, true); jsvUnLock(eventName); JsVar *eventList = jsvSkipName(eventListName); if (eventList) { if (eventList == callback) { // there's no array, it was a single item jsvRemoveChild(parent, eventListName); } else if (jsvIsArray(eventList)) { // it's an array, search for the index JsVar *idx = jsvGetArrayIndexOf(eventList, callback, true); if (idx) { jsvRemoveChild(eventList, idx); jsvUnLock(idx); } } jsvUnLock(eventList); } jsvUnLock(eventListName); } else { jsWarn("First argument to EventEmitter.removeListener(..) must be a string"); return; } }
void serverResponseWrite(JsVar *httpServerResponseVar, JsVar *data) { // Append data to sendData JsVar *sendData = jsvObjectGetChild(httpServerResponseVar, HTTP_NAME_SEND_DATA, 0); if (!sendData) { // no sendData, so no headers - add them! JsVar *sendHeaders = jsvObjectGetChild(httpServerResponseVar, HTTP_NAME_HEADERS, 0); if (sendHeaders) { sendData = jsvVarPrintf("HTTP/1.0 %d OK\r\nServer: Espruino "JS_VERSION"\r\n", jsvGetIntegerAndUnLock(jsvObjectGetChild(httpServerResponseVar, HTTP_NAME_CODE, 0))); httpAppendHeaders(sendData, sendHeaders); jsvObjectSetChild(httpServerResponseVar, HTTP_NAME_HEADERS, 0); jsvUnLock(sendHeaders); // finally add ending newline jsvAppendString(sendData, "\r\n"); } else if (!jsvIsUndefined(data)) { // we have already sent headers, but want to send more sendData = jsvNewFromEmptyString(); } jsvObjectSetChild(httpServerResponseVar, HTTP_NAME_SEND_DATA, sendData); } if (sendData && !jsvIsUndefined(data)) { JsVar *s = jsvAsString(data, false); if (s) jsvAppendStringVarComplete(sendData,s); jsvUnLock(s); } jsvUnLock(sendData); }
static void dash7Callback(JsVar *data){ blink(PIN_BLUE, 20); hasConnection = true; #ifdef GATEWAY wice_msg_start(&dash7Message); //start timer if not running if (wice_msg_isTimeout(&dash7Message)){ wice_msg_reset(&dash7Message); } else { char buffer[1024]; jsvGetString(data, buffer, sizeof(buffer)); int didAdd = wice_msg_add(&dash7Message, buffer); } if (wice_msg_isComplete(&dash7Message)){ char *msg = dash7Message.buffer; blink(PIN_GRN, 100); blink(PIN_GRN, 100); if (connected) { JsVar *str = jsvVarPrintf("%s", msg); JsVar *serial = jspGetNamedField(execInfo.root, SERIAL4_WIFI, false); jswrap_serial_print(serial, str); jsvUnLock(serial); jsvUnLock(str); } if (wice_msg_isFunction(&dash7Message)){ jspEvaluate(msg); //evalute in case server wants to say something } wice_msg_reset(&dash7Message); sendReplyToListeningNodes("function(){digitalWrite(A14, 1);}();"); } #else WDEBUGSTRVAR(data); #endif }
void sendReplyToListeningNodes(const char* msg) { jsvUnLock(messageVar); messageVar = jsvVarPrintf(msg); JsVar *serial = jspGetNamedField(execInfo.root, SERIAL1_DASH7, false); jswrap_serial_print(serial, messageVar); jsvUnLock(serial); }
/*JSON{ "type" : "method", "class" : "Object", "name" : "removeAllListeners", "generate" : "jswrap_object_removeAllListeners", "params" : [ ["event","JsVar","The name of the event, for instance 'data'"] ] } Removes all listeners, or those of the specified event. */ void jswrap_object_removeAllListeners(JsVar *parent, JsVar *event) { if (!jsvHasChildren(parent)) { jsWarn("Parent must be an object - not a String, Integer, etc."); return; } if (jsvIsString(event)) { // remove the whole child containing listeners JsVar *eventName = jsvVarPrintf(JS_EVENT_PREFIX"%s",event); if (!eventName) return; // no memory JsVar *eventList = jsvFindChildFromVar(parent, eventName, true); jsvUnLock(eventName); if (eventList) { jsvRemoveChild(parent, eventList); jsvUnLock(eventList); } } else if (jsvIsUndefined(event)) { // Eep. We must remove everything beginning with '#on' (JS_EVENT_PREFIX) JsvObjectIterator it; jsvObjectIteratorNew(&it, parent); while (jsvObjectIteratorHasValue(&it)) { JsVar *key = jsvObjectIteratorGetKey(&it); jsvObjectIteratorNext(&it); if (jsvIsStringEqualOrStartsWith(key, JS_EVENT_PREFIX, true)) { // begins with #on - we must kill it jsvRemoveChild(parent, key); } jsvUnLock(key); } jsvObjectIteratorFree(&it); } else { jsWarn("First argument to EventEmitter.removeAllListeners(..) must be a string, or undefined"); return; } }
void doMeasurement() { enableDASH(); JsVar *i2c1 = jspGetNamedField(execInfo.root, "I2C1", false); IOEventFlags device = jsiGetDeviceFromClass(i2c1); if (!DEVICE_IS_I2C(device)) { blink(PIN_RED, 100); return; } jsvUnLock(i2c1); unsigned char dataPtr[2]; dataPtr[0] = CMD_MEASURE_TEMPERATURE_HOLD; jshI2CWrite(device, (unsigned char)(CMD_TEMP_ADDR), 1, (unsigned char*)dataPtr, true); int i = 0; for (i=0; i<2; i++) { dataPtr[i] = 0; } jshI2CRead(device, (unsigned char)CMD_TEMP_ADDR, 2, (unsigned char*)dataPtr, true); int temp = ((dataPtr[0] * 256) + dataPtr[1]); /// http://www.silabs.com/Support%20Documents/TechnicalDocs/Si7050-1-3-4-5-A20.pdf#page=14 JsVarFloat realTemp = ((175.72f * temp) / 65536.0f) - 46.85f; char temperatureBuffer[6] = {0}; ftoa_bounded(realTemp, temperatureBuffer, 5); temperatureBuffer[5] = '\0'; char serialNumber[SERIAL_LEN] = {0}; getSerial(serialNumber, SERIAL_LEN); /// Generate the JSON that we send to gateway skyand then to API{\"nodeSerial\":\"%s\",\"channel\":\"temp\",\"value\":\"%s\",\"metric\":\"c\"}');", serialNumber + SERIAL_OFFSE jsvUnLock(messageVar); if (doTimeout) { //regular message messageVar = jsvVarPrintf("{\"ns\":\"%s\",\"ch\":\"t\",\"v\":\"%s\",\"m\":\"c\"}", serialNumber + SERIAL_OFFSET, temperatureBuffer); } else { //this only happens if we forced the read messageVar = jsvVarPrintf("{\"ns\":\"%s\",\"ch\":\"t\",\"v\":\"%s\",\"m\":\"c\",\"f\":\"y\"}", serialNumber + SERIAL_OFFSET, temperatureBuffer); } WDEBUG("sending on DASH: "); WDEBUGSTRVAR(messageVar); WDEBUGLN(""); JsVar *serial = jspGetNamedField(execInfo.root, SERIAL1_DASH7, false); jswrap_serial_print(serial, messageVar); jsvUnLock(serial); transmittingData = true; // see jswrap_wice_idle }
void restartWifi() { jsvUnLock(messageVar); messageVar = jsvVarPrintf("{\"restart\":\"true\"}"); JsVar *serial = jspGetNamedField(execInfo.root, SERIAL4_WIFI, false); jswrap_serial_print(serial, messageVar); jsvUnLock(serial); WDEBUGSTRVAR(messageVar); startTime = restartWifiAt; connected = false; blink(PIN_RED, 40); }
void doSendSerial() { char serialNumber[SERIAL_LEN] = {0}; getSerial(serialNumber, SERIAL_LEN); jsvUnLock(messageVar); messageVar = jsvVarPrintf("%s", serialNumber + SERIAL_OFFSET); WDEBUG("Serial: "); WDEBUGSTRVAR(messageVar); WDEBUGLN(""); JsVar *serial = jspGetNamedField(execInfo.root, SERIAL4_WIFI, false); jswrap_serial_print(serial, messageVar); jsvUnLock(serial); blink(PIN_RED, 20);blink(PIN_RED, 20);blink(PIN_RED, 20); }
/*JSON{ "type" : "method", "class" : "ReferenceError", "name" : "toString", "generate" : "jswrap_error_toString", "return" : ["JsVar","A String"] }*/ JsVar *jswrap_error_toString(JsVar *parent) { JsVar *str = jsvObjectGetChild(parent, "type", 0); if (!str) str = jsvNewFromString("Error"); if (!str) return 0; JsVar *msg = jsvObjectGetChild(parent, "msg", 0); if (msg) { JsVar *newStr = jsvVarPrintf("%v: %v", str, msg); jsvUnLock2(msg, str); str = newStr; } return str; }
void clientRequestWrite(JsVar *httpClientReqVar, JsVar *data) { SocketType socketType = socketGetType(httpClientReqVar); // Append data to sendData JsVar *sendData = jsvObjectGetChild(httpClientReqVar, HTTP_NAME_SEND_DATA, 0); if (!sendData) { JsVar *options = 0; // Only append a header if we're doing HTTP if (socketType == ST_HTTP) options = jsvObjectGetChild(httpClientReqVar, HTTP_NAME_OPTIONS_VAR, 0); if (options) { JsVar *method = jsvObjectGetChild(options, "method", 0); JsVar *path = jsvObjectGetChild(options, "path", 0); sendData = jsvVarPrintf("%v %v HTTP/1.0\r\nUser-Agent: Espruino "JS_VERSION"\r\nConnection: close\r\n", method, path); jsvUnLock(method); jsvUnLock(path); JsVar *headers = jsvObjectGetChild(options, "headers", 0); bool hasHostHeader = false; if (jsvIsObject(headers)) { JsVar *hostHeader = jsvObjectGetChild(headers, "Host", 0); hasHostHeader = hostHeader!=0; jsvUnLock(hostHeader); httpAppendHeaders(sendData, headers); } jsvUnLock(headers); if (!hasHostHeader) { JsVar *host = jsvObjectGetChild(options, "host", 0); int port = (int)jsvGetIntegerAndUnLock(jsvObjectGetChild(options, "port", 0)); if (port>0 && port!=80) jsvAppendPrintf(sendData, "Host: %v:%d\r\n", host, port); else jsvAppendPrintf(sendData, "Host: %v\r\n", host); jsvUnLock(host); } // finally add ending newline jsvAppendString(sendData, "\r\n"); } else { sendData = jsvNewFromString(""); } jsvObjectSetChild(httpClientReqVar, HTTP_NAME_SEND_DATA, sendData); jsvUnLock(options); } if (data && sendData) { JsVar *s = jsvAsString(data, false); if (s) jsvAppendStringVarComplete(sendData,s); jsvUnLock(s); } jsvUnLock(sendData); }
/*JSON{ "type" : "method", "class" : "Object", "name" : "on", "generate" : "jswrap_object_on", "params" : [ ["event","JsVar","The name of the event, for instance 'data'"], ["listener","JsVar","The listener to call when this event is received"] ] } Register an event listener for this object, for instance ```http.on('data', function(d) {...})```. See Node.js's EventEmitter. */ void jswrap_object_on(JsVar *parent, JsVar *event, JsVar *listener) { if (!jsvHasChildren(parent)) { jsWarn("Parent must be an object - not a String, Integer, etc."); return; } if (!jsvIsString(event)) { jsWarn("First argument to EventEmitter.on(..) must be a string"); return; } if (!jsvIsFunction(listener) && !jsvIsString(listener)) { jsWarn("Second argument to EventEmitter.on(..) must be a function or a String (containing code)"); return; } JsVar *eventName = jsvVarPrintf(JS_EVENT_PREFIX"%s",event); if (!eventName) return; // no memory JsVar *eventList = jsvFindChildFromVar(parent, eventName, true); jsvUnLock(eventName); JsVar *eventListeners = jsvSkipName(eventList); if (jsvIsUndefined(eventListeners)) { // just add jsvSetValueOfName(eventList, listener); } else { if (jsvIsArray(eventListeners)) { // we already have an array, just add to it jsvArrayPush(eventListeners, listener); } else { // not an array - we need to make it an array JsVar *arr = jsvNewEmptyArray(); jsvArrayPush(arr, eventListeners); jsvArrayPush(arr, listener); jsvSetValueOfName(eventList, arr); jsvUnLock(arr); } } jsvUnLock2(eventListeners, eventList); /* Special case if we're a data listener and data has already arrived then * we queue an event immediately. */ if (jsvIsStringEqual(event, "data")) { JsVar *buf = jsvObjectGetChild(parent, STREAM_BUFFER_NAME, 0); if (jsvIsString(buf)) { jsiQueueObjectCallbacks(parent, STREAM_CALLBACK_NAME, &buf, 1); jsvRemoveNamedChild(parent, STREAM_BUFFER_NAME); } jsvUnLock(buf); } }
/*JSON{ "type" : "method", "class" : "ESPWifi", "name" : "connect", "generate" : "jswrap_esp8266_connect", "params" : [ ["ap","JsVar","Access point name"], ["key","JsVar","WPA2 key (or undefined for unsecured connection)"], ["callback","JsVar","Function to call back with connection status. It has one argument which is one of 'connect'/'disconnect'/'dhcp'"] ], "return" : ["bool",""] } Connect to an access point */ bool jswrap_esp8266_connect(JsVar *wlanObj, JsVar *vAP, JsVar *vKey, JsVar *callback) { NOT_USED(wlanObj); JsNetwork net; if (!networkGetFromVar(&net)) return false; // 'AT+CWMODE=1\r' ? seems to be the default JsVar *msg = jsvVarPrintf("AT+CWJAP=%q,%q\r", vAP, vKey); esp8266_send(msg); jsvUnLock(msg); if (!esp8266_wait_for("OK",500, false)) return false; networkFree(&net); if (callback) jsiQueueEvents(callback, 0, 0); return true; }
void serverResponseWriteHead(JsVar *httpServerResponseVar, int statusCode, JsVar *headers) { if (!jsvIsUndefined(headers) && !jsvIsObject(headers)) { jsError("Headers sent to writeHead should be an object"); return; } JsVar *sendData = jsvObjectGetChild(httpServerResponseVar, HTTP_NAME_SEND_DATA, 0); if (sendData) { // If sendData!=0 then we were already called jsError("Headers have already been sent"); jsvUnLock(sendData); return; } sendData = jsvVarPrintf("HTTP/1.0 %d OK\r\nServer: Espruino "JS_VERSION"\r\n", statusCode); if (headers) httpAppendHeaders(sendData, headers); // finally add ending newline jsvAppendString(sendData, "\r\n"); jsvObjectSetChildAndUnLock(httpServerResponseVar, HTTP_NAME_SEND_DATA, sendData); }
/*JSON{ "type" : "method", "class" : "Object", "name" : "emit", "generate" : "jswrap_object_emit", "params" : [ ["event","JsVar","The name of the event, for instance 'data'"], ["args","JsVarArray","Optional arguments"] ] } Call the event listeners for this object, for instance ```http.emit('data', 'Foo')```. See Node.js's EventEmitter. */ void jswrap_object_emit(JsVar *parent, JsVar *event, JsVar *argArray) { if (!jsvHasChildren(parent)) { jsWarn("Parent must be an object - not a String, Integer, etc."); return; } if (!jsvIsString(event)) { jsWarn("First argument to EventEmitter.emit(..) must be a string"); return; } JsVar *eventName = jsvVarPrintf(JS_EVENT_PREFIX"%s",event); if (!eventName) return; // no memory // extract data const unsigned int MAX_ARGS = 4; JsVar *args[MAX_ARGS]; unsigned int n = 0; JsvObjectIterator it; jsvObjectIteratorNew(&it, argArray); while (jsvObjectIteratorHasValue(&it)) { if (n>=MAX_ARGS) { jsWarn("Too many arguments"); break; } args[n++] = jsvObjectIteratorGetValue(&it); jsvObjectIteratorNext(&it); } jsvObjectIteratorFree(&it); JsVar *callback = jsvSkipNameAndUnLock(jsvFindChildFromVar(parent, eventName, 0)); jsvUnLock(eventName); if (callback) jsiQueueEvents(parent, callback, args, (int)n); jsvUnLock(callback); // unlock jsvUnLockMany(n, args); }
JsVar *bda2JsVarString(esp_bd_addr_t bda){ JsVar *s = jsvVarPrintf("%02x:%02x:%02x:%02x:%02x:%02x",bda[0],bda[1],bda[2],bda[3],bda[4],bda[5]); return s; }
/*JSON{ "type" : "method", "class" : "Date", "name" : "toUTCString", "generate" : "jswrap_date_toUTCString", "return" : ["JsVar","A String"] } Converts to a String, eg: `Fri, 20 Jun 2014 14:52:20 GMT` **Note:** This always assumes a timezone of GMT */ JsVar *jswrap_date_toUTCString(JsVar *parent) { TimeInDay time = getTimeFromDateVar(parent); CalendarDate date = getCalendarDate(time.daysSinceEpoch); return jsvVarPrintf("%s, %d %s %d %02d:%02d:%02d GMT", &DAYNAMES[date.dow*4], date.day, &MONTHNAMES[date.month*4], date.year, time.hour, time.min, time.sec); }
void clientRequestWrite(JsNetwork *net, JsVar *httpClientReqVar, JsVar *data) { SocketType socketType = socketGetType(httpClientReqVar); // Append data to sendData JsVar *sendData = jsvObjectGetChild(httpClientReqVar, HTTP_NAME_SEND_DATA, 0); if (!sendData) { JsVar *options = 0; // Only append a header if we're doing HTTP AND we haven't already connected if ((socketType&ST_TYPE_MASK) == ST_HTTP) if (jsvGetIntegerAndUnLock(jsvObjectGetChild(httpClientReqVar, HTTP_NAME_SOCKET, 0))==0) options = jsvObjectGetChild(httpClientReqVar, HTTP_NAME_OPTIONS_VAR, 0); if (options) { // We're an HTTP client - make a header JsVar *method = jsvObjectGetChild(options, "method", 0); JsVar *path = jsvObjectGetChild(options, "path", 0); sendData = jsvVarPrintf("%v %v HTTP/1.0\r\nUser-Agent: Espruino "JS_VERSION"\r\nConnection: close\r\n", method, path); jsvUnLock2(method, path); JsVar *headers = jsvObjectGetChild(options, "headers", 0); bool hasHostHeader = false; if (jsvIsObject(headers)) { JsVar *hostHeader = jsvObjectGetChild(headers, "Host", 0); hasHostHeader = hostHeader!=0; jsvUnLock(hostHeader); httpAppendHeaders(sendData, headers); // if Transfer-Encoding:chunked was set, subsequent writes need to 'chunk' the data that is sent if (jsvIsStringEqualAndUnLock(jsvObjectGetChild(headers, "Transfer-Encoding", 0), "chunked")) { jsvObjectSetChildAndUnLock(httpClientReqVar, HTTP_NAME_CHUNKED, jsvNewFromBool(true)); } } jsvUnLock(headers); if (!hasHostHeader) { JsVar *host = jsvObjectGetChild(options, "host", 0); int port = (int)jsvGetIntegerAndUnLock(jsvObjectGetChild(options, "port", 0)); if (port>0 && port!=80) jsvAppendPrintf(sendData, "Host: %v:%d\r\n", host, port); else jsvAppendPrintf(sendData, "Host: %v\r\n", host); jsvUnLock(host); } // finally add ending newline jsvAppendString(sendData, "\r\n"); } else { // !options // We're not HTTP (or were already connected), so don't send any header sendData = jsvNewFromString(""); } jsvObjectSetChild(httpClientReqVar, HTTP_NAME_SEND_DATA, sendData); jsvUnLock(options); } // We have data and aren't out of memory... if (data && sendData) { // append the data to what we want to send JsVar *s = jsvAsString(data, false); if (s) { if ((socketType&ST_TYPE_MASK) == ST_HTTP && jsvGetBoolAndUnLock(jsvObjectGetChild(httpClientReqVar, HTTP_NAME_CHUNKED, 0))) { // If we asked to send 'chunked' data, we need to wrap it up, // prefixed with the length jsvAppendPrintf(sendData, "%x\r\n%v\r\n", jsvGetStringLength(s), s); } else { jsvAppendStringVarComplete(sendData,s); } jsvUnLock(s); } } jsvUnLock(sendData); if ((socketType&ST_TYPE_MASK) == ST_HTTP) { // on HTTP we connect after the first write clientRequestConnect(net, httpClientReqVar); } }
/**@brief Function for the application's SoftDevice event handler. * * @param[in] p_ble_evt SoftDevice event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_TIMEOUT: // the timeout for sd_ble_gap_adv_start expired - kick it off again jswrap_nrf_bluetooth_startAdvertise(); break; case BLE_GAP_EVT_CONNECTED: m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; bleStatus &= ~BLE_IS_SENDING; // reset state - just in case jsiSetConsoleDevice( EV_BLUETOOTH ); break; case BLE_GAP_EVT_DISCONNECTED: m_conn_handle = BLE_CONN_HANDLE_INVALID; jsiSetConsoleDevice( DEFAULT_CONSOLE_DEVICE ); // restart advertising after disconnection jswrap_nrf_bluetooth_startAdvertise(); break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: // Pairing not supported err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: // No system attributes have been stored. err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0); APP_ERROR_CHECK(err_code); break; case BLE_EVT_TX_COMPLETE: // UART Transmit finished - we can try and send more data bleStatus &= ~BLE_IS_SENDING; jswrap_nrf_transmit_string(); break; case BLE_GAP_EVT_ADV_REPORT: { // Advertising data received const ble_gap_evt_adv_report_t *p_adv = &p_ble_evt->evt.gap_evt.params.adv_report; JsVar *evt = jsvNewObject(); if (evt) { jsvObjectSetChildAndUnLock(evt, "rssi", jsvNewFromInteger(p_adv->rssi)); jsvObjectSetChildAndUnLock(evt, "addr", jsvVarPrintf("%02x:%02x:%02x:%02x:%02x:%02x", p_adv->peer_addr.addr[5], p_adv->peer_addr.addr[4], p_adv->peer_addr.addr[3], p_adv->peer_addr.addr[2], p_adv->peer_addr.addr[1], p_adv->peer_addr.addr[0])); JsVar *data = jsvNewStringOfLength(p_adv->dlen); if (data) { jsvSetString(data, p_adv->data, p_adv->dlen); JsVar *ab = jsvNewArrayBufferFromString(data, p_adv->dlen); jsvUnLock(data); jsvObjectSetChildAndUnLock(evt, "data", ab); } jsiQueueObjectCallbacks(execInfo.root, BLE_SCAN_EVENT, &evt, 1); jsvUnLock(evt); } break; } default: // No implementation needed. break; } }
JsVar *jswrap_crypto_error_to_jsvar(int err) { const char *e = jswrap_crypto_error_to_str(err); if (e) return jsvNewFromString(e); return jsvVarPrintf("-0x%x", -err); }