Esempio n. 1
0
/*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;
  }
}
Esempio n. 2
0
/*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 (!jsvIsObject(parent)) {
      jsWarn("Parent must be a proper object - not a String, Integer, etc.");
      return;
    }
  if (!jsvIsString(event)) {
    jsWarn("First argument to EventEmitter.emit(..) must be a string");
    return;
  }
  char eventName[16] = "#on";
  jsvGetString(event, &eventName[3], sizeof(eventName)-4);

  // extract data
  const int MAX_ARGS = 4;
  JsVar *args[MAX_ARGS];
  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);


  jsiQueueObjectCallbacks(parent, eventName, args, n);
  // unlock
  while (n--)
    jsvUnLock(args[n]);
}
Esempio n. 3
0
esp_err_t registerCallbacks(){
	esp_err_t ret;
	ret = esp_ble_gap_register_callback(gap_event_handler);if (ret){jsWarn("gap register error:%x\n", ret);return ret;}
	ret = esp_ble_gatts_register_callback(gatts_event_handler);if(ret){jsWarn("gatts register error:%x\n", ret);return ret;}	
	ret = esp_ble_gattc_register_callback(gattc_event_handler);if(ret){jsWarn("gattc regigister error:%x\n",ret);return ret;}
	return ret;
}
Esempio n. 4
0
/*JSON{
  "type" : "staticmethod",
  "class" : "Trig",
  "name" : "setTrigger",
  "generate" : "jswrap_trig_setTrigger",
  "params" : [
    ["num","int","The trigger number (0..7)"],
    ["pos","float","The position (in degrees) to fire the trigger at"],
    ["pins","JsVar","An array of pins to pulse (max 4)"],
    ["pulseLength","float","The time (in msec) to pulse for"]
  ]
}
Set a trigger for a certain point in the cycle
*/
void jswrap_trig_setTrigger(JsVarInt num, JsVarFloat position, JsVar *pins, JsVarFloat pulseLength) {
  TriggerStruct *trig = &mainTrigger;
  if (num<0 || num>=TRIGGER_TRIGGERS_COUNT) {
     jsWarn("Invalid trigger number\n");
     return;
   }
  if (!jsvIsArray(pins)) {
    jsWarn("Second argument must be an array of pins\n");
    return;
  }
  if (jsvGetArrayLength(pins) > TRIGGERPOINT_TRIGGERS_COUNT) {
    jsWarn("Too many pins in array\n");
    return;
  }

  // convert from degrees to teeth
  position = wrapAround(((position - trig->keyPosition) * trig->teethTotal / 360), trig->teethTotal);

  TriggerPointStruct *tp = &trig->triggers[num];
  tp->newTooth = (unsigned char)position;
  tp->newToothFraction = (unsigned char)((position - tp->tooth)*256);
  tp->pulseLength = jshGetTimeFromMilliseconds(pulseLength);
  int i, l=(int)jsvGetArrayLength(pins);
  for (i=0;i<TRIGGERPOINT_TRIGGERS_COUNT;i++) {
    tp->pins[i] = (Pin)((i<l) ? jshGetPinFromVarAndUnLock(jsvGetArrayItem(pins, i)) : PIN_UNDEFINED);
  }
  // now copy over data if we need to do it immediately
  if (tp->tooth==TRIGGERPOINT_TOOTH_DISABLE || tp->newTooth==TRIGGERPOINT_TOOTH_DISABLE) {
    tp->tooth = tp->newTooth;
    tp->toothFraction = tp->newToothFraction;
  }
  // all done!
}
Esempio n. 5
0
esp_err_t initController(){
	esp_err_t ret;  	
	esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
    ret = esp_bt_controller_init(&bt_cfg);if(ret) {jsWarn("init controller failed:%x\n",ret); return ret;}
	ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);if(ret) {jsWarn("enable controller failed:%x\n",ret); return ret;}
	return ret;
}
Esempio n. 6
0
/*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;
  }
  char eventName[16];
  if (!jswrap_object_get_event_name(eventName, event)) return;

  // 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);


  jsiQueueObjectCallbacks(parent, eventName, args, (int)n);
  // unlock
  jsvUnLockMany(n, args);
}
Esempio n. 7
0
/*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;
  }
}
Esempio n. 8
0
/*JSON{ "type":"function", "name" : "require",
         "description" : "Load the given module, and return the exported functions",
         "generate" : "jswrap_require",
         "params" : [ [ "moduleName", "JsVar", "A String containing the name of the given module"] ],
         "return" : ["JsVar", "The result of evaluating the string"]
}*/
JsVar *jswrap_require(JsVar *moduleName) {
  if (!jsvIsString(moduleName)) {
    jsWarn("Expecting a module name as a string, but got %t", moduleName);
    return 0;
  }
  // Search to see if we have already loaded this module

  JsVar *moduleList = jswrap_modules_getModuleList();
  if (!moduleList) return 0; // out of memory
  JsVar *moduleExportName = jsvFindChildFromVar(moduleList, moduleName, true);
  jsvUnLock(moduleList);
  if (!moduleExportName) return 0; // out of memory
  JsVar *moduleExport = jsvSkipName(moduleExportName);
  if (moduleExport) {
    // Found the module!
    jsvUnLock(moduleExportName);
    return moduleExport;
  }

  // Now check if it is built-in
  char moduleNameBuf[32];
  jsvGetString(moduleName, moduleNameBuf, sizeof(moduleNameBuf));
  if (jswIsBuiltInLibrary(moduleNameBuf)) {
    // create a 'fake' module that Espruino can use to map its built-in functions against
    moduleExport = jspNewBuiltin(moduleNameBuf);
  } else {
    // Now try and load it
    JsVar *fileContents = 0;
    //if (jsvIsStringEqual(moduleName,"http")) {}
    //if (jsvIsStringEqual(moduleName,"fs")) {}
  #ifdef USE_FILESYSTEM
    JsVar *modulePath = jsvNewFromString(
  #ifdef LINUX
        "node_modules/"
  #else
        "NODE_M~1/"
  #endif
        );
    if (!modulePath) { jsvUnLock(moduleExportName); return 0; } // out of memory
    jsvAppendStringVarComplete(modulePath, moduleName);
    jsvAppendString(modulePath,".js");
    fileContents = wrap_fat_readFile(modulePath);
    jsvUnLock(modulePath);
  #endif
    if (!fileContents || jsvIsStringEqual(fileContents,"")) {
      jsvUnLock(moduleExportName);
      jsvUnLock(fileContents);
      jsWarn("Module not found");
      return 0;
    }
    moduleExport = jspEvaluateModule(jsiGetParser(), fileContents);
    jsvUnLock(fileContents);
  }

  assert(moduleExport);
  jsvSetValueOfName(moduleExportName, moduleExport); // save in cache
  jsvUnLock(moduleExportName);
  return moduleExport;
}
Esempio n. 9
0
/*JSON{
  "type" : "staticmethod",
  "class" : "fs",
  "name" : "pipe",
  "ifndef" : "SAVE_ON_FLASH",
  "generate" : "jswrap_pipe",
  "params" : [
    ["source","JsVar","The source file/stream that will send content."],
    ["destination","JsVar","The destination file/stream that will receive content from the source."],
    ["options","JsVar",["An optional object `{ chunkSize : int=64, end : bool=true, complete : function }`","chunkSize : The amount of data to pipe from source to destination at a time","complete : a function to call when the pipe activity is complete","end : call the 'end' function on the destination when the source is finished"]]
  ]
}*/
void jswrap_pipe(JsVar* source, JsVar* dest, JsVar* options) {
  if (!source || !dest) return;
  JsVar *pipe = jspNewObject(0, "Pipe");
  JsVar *arr = pipeGetArray(true);
  JsVar* position = jsvNewFromInteger(0);
  if (pipe && arr && position) {// out of memory?
    JsVar *readFunc = jspGetNamedField(source, "read", false);
    JsVar *writeFunc = jspGetNamedField(dest, "write", false);
    if(jsvIsFunction(readFunc)) {
      if(jsvIsFunction(writeFunc)) {
        JsVarInt chunkSize = 64;
        bool callEnd = true;
        // parse Options Object
        if (jsvIsObject(options)) {
          JsVar *c;
          c = jsvObjectGetChild(options, "complete", false);
          if (c) {
            jsvObjectSetChild(pipe, "#oncomplete", c);
            jsvUnLock(c);
          }
          c = jsvObjectGetChild(options, "end", false);
          if (c) callEnd = jsvGetBoolAndUnLock(c);
          c = jsvObjectGetChild(options, "chunkSize", false);
          if (c) {
            if (jsvIsNumeric(c) && jsvGetInteger(c)>0)
              chunkSize = jsvGetInteger(c);
            else
              jsWarn("chunkSize must be an integer > 0");
            jsvUnLock(c);
          }
        } else if (!jsvIsUndefined(options)) {
          jsWarn("'options' must be an object, or undefined");
        }
        // set up our event listeners
        jswrap_object_addEventListener(source, "close", jswrap_pipe_src_close_listener, JSWAT_VOID | (JSWAT_JSVAR << (JSWAT_BITS*1)));
        jswrap_object_addEventListener(dest, "drain", jswrap_pipe_drain_listener, JSWAT_VOID | (JSWAT_JSVAR << (JSWAT_BITS*1)));
        jswrap_object_addEventListener(dest, "close", jswrap_pipe_dst_close_listener, JSWAT_VOID | (JSWAT_JSVAR << (JSWAT_BITS*1)));
        // set up the rest of the pipe
        jsvUnLock(jsvObjectSetChild(pipe, "chunkSize", jsvNewFromInteger(chunkSize)));
        jsvUnLock(jsvObjectSetChild(pipe, "end", jsvNewFromBool(callEnd)));
        jsvUnLock(jsvAddNamedChild(pipe, position, "position"));
        jsvUnLock(jsvAddNamedChild(pipe, source, "source"));
        jsvUnLock(jsvAddNamedChild(pipe, dest, "destination"));
        // add the pipe to our list
        jsvArrayPush(arr, pipe);
      } else {
        jsExceptionHere(JSET_ERROR, "Destination object does not implement the required write(buffer, length, position) method.");
      }
    } else {
      jsExceptionHere(JSET_ERROR, "Source object does not implement the required read(buffer, length, position) method.");
    }
    jsvUnLock(readFunc);
    jsvUnLock(writeFunc);
  }
  jsvUnLock(arr);
  jsvUnLock(pipe);
  jsvUnLock(position);
}
/*JSON{ "type":"method", "class": "Object", "name" : "emit",
         "description" : ["Call the event listeners for this object, for instance ```http.emit('data', 'Foo')```. See Node.js's EventEmitter."],
         "generate" : "jswrap_object_emit",
         "params" : [ [ "event", "JsVar", "The name of the event, for instance 'data'"],
                      [ "v1", "JsVar", "Optional argument 1"],
                      [ "v2", "JsVar", "Optional argument 2"]  ]
}*/
void jswrap_object_emit(JsVar *parent, JsVar *event, JsVar *v1, JsVar *v2) {
  if (!jsvIsObject(parent)) {
      jsWarn("Parent must be a proper object - not a String, Integer, etc.");
      return;
    }
  if (!jsvIsString(event)) {
    jsWarn("First argument to EventEmitter.emit(..) must be a string");
    return;
  }
  char eventName[16] = "#on";
  jsvGetString(event, &eventName[3], sizeof(eventName)-4);
  jsiQueueObjectCallbacks(parent, eventName, v1, v2);
}
Esempio n. 11
0
/*JSON{
  "type" : "staticmethod",
  "class" : "Object",
  "name" : "create",
  "generate" : "jswrap_object_create",
  "params" : [
    ["proto","JsVar","A prototype object"],
    ["propertiesObject","JsVar","An object containing properties. NOT IMPLEMENTED"]
  ],
  "return" : ["JsVar","A new object"]
}
Creates a new object with the specified prototype object and properties. properties are currently unsupported.
 */
JsVar *jswrap_object_create(JsVar *proto, JsVar *propertiesObject) {
  if (!jsvIsObject(proto) && !jsvIsNull(proto)) {
    jsWarn("Object prototype may only be an Object or null: %t", proto);
    return 0;
  }
  if (jsvIsObject(propertiesObject)) {
    jsWarn("propertiesObject is not supported yet");
  }
  JsVar *obj = jsvNewObject();
  if (!obj) return 0;
  if (jsvIsObject(proto))
    jsvObjectSetChild(obj, JSPARSE_INHERITS_VAR, proto);
  return obj;
}
Esempio n. 12
0
/*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);
  }
}
Esempio n. 13
0
/*JSON{
  "type" : "method",
  "class" : "OneWire",
  "name" : "select",
  "generate" : "jswrap_onewire_select",
  "params" : [
    ["rom","JsVar","The device to select (get this using `OneWire.search()`)"]
  ]
}
Select a ROM - reset needs to be done first
 */
void jswrap_onewire_select(JsVar *parent, JsVar *rom) {
  Pin pin = onewire_getpin(parent);
  if (!jshIsPinValid(pin)) return;
  if (!jsvIsString(rom) || jsvGetStringLength(rom)!=16) {
    jsWarn("Invalid OneWire device address");
    return;
  }

  // decode the address
  unsigned long long romdata = 0;
  JsvStringIterator it;
  jsvStringIteratorNew(&it, rom, 0);
  int i;
  for (i=0;i<8;i++) {
    char b[3];
    b[0] = jsvStringIteratorGetChar(&it);
    jsvStringIteratorNext(&it);
    b[1] = jsvStringIteratorGetChar(&it);
    jsvStringIteratorNext(&it);
    b[2] = 0;
    romdata = romdata | (((unsigned long long)stringToIntWithRadix(b,16,0)) << (i*8));

  }
  jsvStringIteratorFree(&it);

  // finally write data out
  OneWireWrite(pin, 8, 0x55);
  OneWireWrite(pin, 64, romdata);
}
Esempio n. 14
0
/*JSON{
  "type" : "constructor",
  "class" : "Date",
  "name" : "Date",
  "generate" : "jswrap_date_constructor",
  "params" : [
    ["args","JsVarArray","Either nothing (current time), one numeric argument (milliseconds since 1970), a date string (see `Date.parse`), or [year, month, day, hour, minute, second, millisecond] "]
  ],
  "return" : ["JsVar","A Date object"],
  "return_object" : "Date"
}
Creates a date object
*/
JsVar *jswrap_date_constructor(JsVar *args) {
  JsVarFloat time = 0;

  if (jsvGetArrayLength(args)==0) {
    time = jswrap_date_now();
  } else if (jsvGetArrayLength(args)==1) {
    JsVar *arg = jsvGetArrayItem(args, 0);
    if (jsvIsNumeric(arg))
      time = jsvGetFloat(arg);
    else if (jsvIsString(arg))
      time = jswrap_date_parse(arg);
    else
      jsWarn("Variables of type %t are not supported in date constructor", arg);
    jsvUnLock(arg);
  } else {
    CalendarDate date;
    date.year = (int)jsvGetIntegerAndUnLock(jsvGetArrayItem(args, 0));
    date.month = (int)jsvGetIntegerAndUnLock(jsvGetArrayItem(args, 1));
    date.day = (int)jsvGetIntegerAndUnLock(jsvGetArrayItem(args, 2));
    TimeInDay td;
    td.daysSinceEpoch = fromCalenderDate(&date);
    td.hour = (int)jsvGetIntegerAndUnLock(jsvGetArrayItem(args, 3));
    td.min = (int)jsvGetIntegerAndUnLock(jsvGetArrayItem(args, 4));
    td.sec = (int)jsvGetIntegerAndUnLock(jsvGetArrayItem(args, 5));
    td.ms = (int)jsvGetIntegerAndUnLock(jsvGetArrayItem(args, 6));
    td.zone = 0;
    time = fromTimeInDay(&td);
  }

  return jswrap_date_from_milliseconds(time);
}
Esempio n. 15
0
/*JSON{ "type":"method", "class": "Function", "name" : "apply",
         "description" : ["This executes the function with the supplied 'this' argument and parameters"],
         "generate" : "jswrap_function_apply",
         "params" : [ [ "this", "JsVar", "The value to use as the 'this' argument when executing the function"],
                      [ "args", "JsVar", "Optional Array of Aruments"]
                    ],
         "return" : [ "JsVar", "The return value of executing this function" ]
}*/
JsVar *jswrap_function_apply(JsVar *parent, JsVar *thisArg, JsVar *argsArray) {
  unsigned int i;
  JsVar **args = 0;
  size_t argC = 0;

  if (jsvIsArray(argsArray)) {
    argC = (size_t)jsvGetArrayLength(argsArray);
    if (argC>64) argC=64; // sanity
    args = (JsVar**)alloca((size_t)argC * sizeof(JsVar*));


    for (i=0;i<argC;i++) args[i] = 0;
    JsvArrayIterator it;
    jsvArrayIteratorNew(&it, argsArray);
    while (jsvArrayIteratorHasElement(&it)) {
      JsVarInt idx = jsvGetIntegerAndUnLock(jsvArrayIteratorGetIndex(&it));
      if (idx>=0 && idx<(int)argC) {
        assert(!args[idx]); // just in case there were dups
        args[idx] = jsvArrayIteratorGetElement(&it);
      }
      jsvArrayIteratorNext(&it);
    }
    jsvArrayIteratorFree(&it);
  } else if (!jsvIsUndefined(argsArray)) {
    jsWarn("Second argument to Function.apply must be an array");
  }

  JsVar *r = jspeFunctionCall(parent, 0, thisArg, false, (int)argC, args);
  for (i=0;i<argC;i++) jsvUnLock(args[i]);
  return r;
}
Esempio n. 16
0
/*JSON{ "type":"method",
         "class" : "Ethernet", "name" : "setIP",
         "generate" : "jswrap_ethernet_setIP",
         "description" : "Set the current IP address for get an IP from DHCP (if no options object is specified)",
         "params" : [ [ "options", "JsVar", "Object containing IP address options `{ ip : '1,2,3,4', subnet, gateway, dns  }`, or do not supply an object in otder to force DHCP."] ],
         "return" : ["bool", "True on success"]
}*/
bool jswrap_ethernet_setIP(JsVar *wlanObj, JsVar *options) {
  NOT_USED(wlanObj);

  if (networkState != NETWORKSTATE_ONLINE) {
    jsError("Not connected to the internet");
    return false;
  }

  bool success = false;
  wiz_NetInfo gWIZNETINFO;

  ctlnetwork(CN_GET_NETINFO, (void*)&gWIZNETINFO);

  if (jsvIsObject(options)) {
    _eth_getIP_set_address(options, "ip", &gWIZNETINFO.ip[0]);
    _eth_getIP_set_address(options, "subnet", &gWIZNETINFO.sn[0]);
    _eth_getIP_set_address(options, "gateway", &gWIZNETINFO.gw[0]);
    _eth_getIP_set_address(options, "dns", &gWIZNETINFO.dns[0]);
    gWIZNETINFO.dhcp = NETINFO_STATIC;
    success = true;
  } else {
    // DHCP
    uint8_t DHCPisSuccess = getIP_DHCPS(net_wiznet_getFreeSocket(), &gWIZNETINFO);
    if (DHCPisSuccess == 1) {
      // info in lease_time.lVal
      success = true;
    } else {
      jsWarn("DHCP failed");
      success = false;
    }
  }

  ctlnetwork(CN_SET_NETINFO, (void*)&gWIZNETINFO);
  return success;
}
Esempio n. 17
0
/*JSON{
  "type" : "staticmethod",
  "class" : "Trig",
  "name" : "getTrigger",
  "generate" : "jswrap_trig_getTrigger",
  "params" : [
    ["num","int","The trigger number (0..7)"]
  ],
  "return" : ["JsVar","A structure containing all information about the trigger"]
}
Get the current state of a trigger
*/
JsVar *jswrap_trig_getTrigger(JsVarInt num) {
  TriggerStruct *trig = &mainTrigger;
  if (num<0 || num>=TRIGGER_TRIGGERS_COUNT) {
     jsWarn("Invalid trigger number\n");
     return 0;
   }
  TriggerPointStruct *tp = &trig->triggers[num];

  // get offset in teeth
  JsVarFloat position = tp->tooth + (tp->toothFraction/256.0);
  // convert from teeth to degrees
  position = wrapAround((position * 360 / trig->teethTotal) + trig->keyPosition, 360);


  JsVar *obj = jsvNewWithFlags(JSV_OBJECT);
  if (!obj) return 0;
  JsVar *v;
  v = jsvNewFromFloat(position);
  jsvUnLock(jsvAddNamedChild(obj, v, "pos"));
  jsvUnLock(v);
  v = jsvNewFromFloat(jshGetMillisecondsFromTime(tp->pulseLength));
  jsvUnLock(jsvAddNamedChild(obj, v, "pulseLength"));
  jsvUnLock(v);
  v = jsvNewWithFlags(JSV_ARRAY);
  int i;
  if (v) {
    for (i=0;i<TRIGGERPOINT_TRIGGERS_COUNT;i++)
      if (tp->pins[i] != PIN_UNDEFINED) {
        jsvArrayPushAndUnLock(v, jsvNewFromPin(tp->pins[i]));
      }
  }
  jsvUnLock(jsvAddNamedChild(obj, v, "pins"));
  jsvUnLock(v);
  return obj;
}
Esempio n. 18
0
void jsWarnUUID(esp_bt_uuid_t char_uuid){
	if (char_uuid.len == ESP_UUID_LEN_16) {
		jsWarn("- - - Char UUID16: %x", char_uuid.uuid.uuid16);
	} else if (char_uuid.len == ESP_UUID_LEN_32) {
		jsWarn("- - - Char UUID32: %x", char_uuid.uuid.uuid32);
	} else if (char_uuid.len == ESP_UUID_LEN_128) {
		jsWarn("- - - Char UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", char_uuid.uuid.uuid128[0],
			char_uuid.uuid.uuid128[1], char_uuid.uuid.uuid128[2], char_uuid.uuid.uuid128[3],
			char_uuid.uuid.uuid128[4], char_uuid.uuid.uuid128[5], char_uuid.uuid.uuid128[6],
			char_uuid.uuid.uuid128[7], char_uuid.uuid.uuid128[8], char_uuid.uuid.uuid128[9],
			char_uuid.uuid.uuid128[10], char_uuid.uuid.uuid128[11], char_uuid.uuid.uuid128[12],
			char_uuid.uuid.uuid128[13], char_uuid.uuid.uuid128[14], char_uuid.uuid.uuid128[15]);
	} else {
		jsWarn("- - - Char UNKNOWN LEN %d\n", char_uuid.len);
	}
}
/*JSON{ "type":"staticmethod", "class": "Object", "name" : "keys",
         "description" : "Return all enumerable keys of the given object",
         "generate" : "jswrap_object_keys",
         "params" : [ [ "object", "JsVar", "The object to return keys for"] ],
         "return" : ["JsVar", "An array of strings - one for each key on the given object"]
}*/
JsVar *jswrap_object_keys(JsVar *obj) {
  if (jsvIsIterable(obj)) {
    bool (*checkerFunction)(JsVar*) = 0;
    if (jsvIsFunction(obj)) checkerFunction = jsvIsInternalFunctionKey;
    else if (jsvIsObject(obj)) checkerFunction = jsvIsInternalObjectKey;

    JsVar *arr = jsvNewWithFlags(JSV_ARRAY);
    if (!arr) return 0;
    JsvIterator it;
    jsvIteratorNew(&it, obj);
    while (jsvIteratorHasElement(&it)) {
      JsVar *key = jsvIteratorGetKey(&it);
      if (!(checkerFunction && checkerFunction(key))) {
        JsVar *name = jsvCopyNameOnly(key,false,false);
        if (name) {
          jsvArrayPushAndUnLock(arr, name);
        }
      }
      jsvUnLock(key);
      jsvIteratorNext(&it);
    }
    jsvIteratorFree(&it);
    return arr;
  } else {
    jsWarn("Object.keys called on non-object");
    return 0;
  }
}
/*JSON{ "type":"method", "class": "Function", "name" : "replaceWith",
         "description" : ["This replaces the function with the one in the argument - while keeping the old function's scope. This allows inner functions to be edited, and is used when edit() is called on an inner function."],
         "generate" : "jswrap_function_replaceWith",
         "params" : [ [ "newFunc", "JsVar", "The new function to replace this function with"] ]
}*/
void jswrap_function_replaceWith(JsVar *oldFunc, JsVar *newFunc) {
  if (!jsvIsFunction(newFunc)) {
    jsWarn("First argument of replaceWith should be a function - ignoring");
    return;
  }
  // Grab scope - the one thing we want to keep
  JsVar *scope = jsvFindChildFromString(oldFunc, JSPARSE_FUNCTION_SCOPE_NAME, false);
  // so now remove all existing entries
  jsvRemoveAllChildren(oldFunc);
  // now re-add scope
  jsvAddName(oldFunc, scope);
  jsvUnLock(scope);
  // now re-add other entries
  JsObjectIterator it;
  jsvObjectIteratorNew(&it, newFunc);
  while (jsvObjectIteratorHasElement(&it)) {
    JsVar *el = jsvObjectIteratorGetKey(&it);
    jsvObjectIteratorNext(&it);
    if (!jsvIsStringEqual(el, JSPARSE_FUNCTION_SCOPE_NAME)) {
      JsVar *copy = jsvCopy(el);
      if (copy) {
        jsvAddName(oldFunc, copy);
        jsvUnLock(copy);
      }
    }
  }
  jsvObjectIteratorFree(&it);

}
Esempio n. 21
0
/*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 (!jsvIsObject(parent)) {
      jsWarn("Parent must be a proper 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;
  }
  char eventName[16] = "#on";
  jsvGetString(event, &eventName[3], sizeof(eventName)-4);

  JsVar *eventList = jsvFindChildFromString(parent, eventName, true);
  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 = jsvNewWithFlags(JSV_ARRAY);
      jsvArrayPush(arr, eventListeners);
      jsvArrayPush(arr, listener);
      jsvSetValueOfName(eventList, arr);
      jsvUnLock(arr);
    }
  }
  jsvUnLock(eventListeners);
  jsvUnLock(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, "#ondata", &buf, 1);
      jsvRemoveNamedChild(parent, STREAM_BUFFER_NAME);
    }
    jsvUnLock(buf);
  }
}
Esempio n. 22
0
/*JSON{ "type":"function", "name" : "digitalPulse",
         "description" : ["Pulse the pin with the value for the given time in milliseconds",
                          "eg. ```pulse(A0,1,500);``` pulses A0 high for 500ms" ],
         "generate" : "jswrap_io_digitalPulse",
         "params" : [ [ "pin", "pin", "The pin to use"],
                      [ "value", "bool", "Whether to pulse high (true) or low (false)"],
                      [ "time", "float", "A time in milliseconds"] ]
}*/
void jswrap_io_digitalPulse(Pin pin, bool value, JsVarFloat time) {
  if (time<=0) {
    jsWarn("Pulse Time given for digitalPulse is less that or equal to 0");
  } else {
    //jsPrintInt((JsVarInt)(time*1000));
    jshPinPulse(pin, value, time);
  }
}
Esempio n. 23
0
/*JSON{ "type":"function", "name" : "digitalPulse",
         "description" : ["Pulse the pin with the value for the given time in milliseconds. It uses a hardware timer to produce accurate pulses, and returns immediately (before the pulse has finished). Use `digitalPulse(A0,1,0)` to wait until a previous pulse has finished.",
                          "eg. `digitalPulse(A0,1,5);` pulses A0 high for 5ms",
                          "digitalPulse is for SHORT pulses that need to be very accurate. If you're doing anything over a few milliseconds, use setTimeout instead." ],
         "generate" : "jswrap_io_digitalPulse",
         "params" : [ [ "pin", "pin", "The pin to use"],
                      [ "value", "bool", "Whether to pulse high (true) or low (false)"],
                      [ "time", "float", "A time in milliseconds"] ]
}*/
void jswrap_io_digitalPulse(Pin pin, bool value, JsVarFloat time) {
  if (time<0 || isnan(time)) {
    jsWarn("Pulse Time given for digitalPulse is less than 0, or not a number");
  } else {
    //jsPrintInt((JsVarInt)(time*1000));
    jshPinPulse(pin, value, time);
  }
}
Esempio n. 24
0
// This is for Object.keys and Object.
JsVar *jswrap_object_keys_or_property_names(JsVar *obj, bool includeNonEnumerable) {
  // strings are iterable, but we shouldn't try and show keys for them
  if (jsvIsIterable(obj) && !jsvIsString(obj)) {
    JsvIsInternalChecker checkerFunction = jsvGetInternalFunctionCheckerFor(obj);

    JsVar *arr = jsvNewWithFlags(JSV_ARRAY);
    if (!arr) return 0;
    JsvIterator it;
    jsvIteratorNew(&it, obj);
    while (jsvIteratorHasElement(&it)) {
      JsVar *key = jsvIteratorGetKey(&it);
      if (!(checkerFunction && checkerFunction(key)) || (jsvIsStringEqual(key, JSPARSE_CONSTRUCTOR_VAR))) {
        /* Not sure why constructor is included in getOwnPropertyNames, but
         * not in for (i in ...) but it is, so we must explicitly override the
         * check in jsvIsInternalObjectKey! */
        JsVar *name = jsvAsArrayIndexAndUnLock(jsvCopyNameOnly(key, false, false));
        if (name) {
          jsvArrayPushAndUnLock(arr, name);
        }
      }
      jsvUnLock(key);
      jsvIteratorNext(&it);
    }
    jsvIteratorFree(&it);

    /* Search our built-in symbol table
       Assume that ALL builtins are non-enumerable. This isn't great but
       seems to work quite well right now! */
    if (includeNonEnumerable) {
      const JswSymList *symbols = 0;

      JsVar *protoOwner = jspGetPrototypeOwner(obj);
      if (protoOwner) {
        symbols = jswGetSymbolListForObjectProto(protoOwner);
        jsvUnLock(protoOwner);
      } else if (!jsvIsObject(obj)) {
        // get symbols, but only if we're not doing it on a basic object
        symbols = jswGetSymbolListForObject(obj);
      }

      if (symbols) {
        unsigned int i;
        for (i=0;i<symbols->symbolCount;i++)
          jsvArrayAddString(arr, &symbols->symbolChars[symbols->symbols[i].strOffset]);
      }

      if (jsvIsArray(obj) || jsvIsString(obj)) {
        jsvArrayAddString(arr, "length");
      }
    }

    return arr;
  } else {
    jsWarn("Object.keys called on non-object");
    return 0;
  }
}
Esempio n. 25
0
/*JSON{
  "type"     : "constructor",
  "class"    : "Pin",
  "name"     : "Pin",
  "generate" : "jswrap_pin_constructor",
  "params"   : [
    ["value", "JsVar", "A value to be converted to a pin. Can be a number, pin, or String."]
  ],
  "return"   : ["JsVar","A Pin object"]
}
Creates a pin from the given argument (or returns undefined if no argument)
*/
JsVar *jswrap_pin_constructor(JsVar *val) {
    Pin pin = jshGetPinFromVar(val);
    if (!jshIsPinValid(pin)) return 0;
#ifdef ESP8266
    if (jsvIsInt(val) && !jsvIsPin(val))
        jsWarn("The Pin() constructor is deprecated. Please use `D%d`, or NodeMCU.Dx instead", pin);
#endif
    return jsvNewFromPin(pin);
}
Esempio n. 26
0
/** Iterate over the contents of var, calling callback for each. Contents may be:
 *   * numeric -> output
 *   * a string -> output each character
 *   * array/arraybuffer -> call itself on each element
 *   * object -> call itself object.count times, on object.data
 */
bool jsvIterateCallback(JsVar *data, void (*callback)(int item, void *callbackData), void *callbackData) {
  bool ok = true;
  if (jsvIsNumeric(data)) {
    callback((int)jsvGetInteger(data), callbackData);
  } else if (jsvIsObject(data)) {
    JsVar *countVar = jsvObjectGetChild(data, "count", 0);
    JsVar *dataVar = jsvObjectGetChild(data, "data", 0);
    if (countVar && dataVar && jsvIsNumeric(countVar)) {
      int n = (int)jsvGetInteger(countVar);
      while (ok && n-- > 0) {
        ok = jsvIterateCallback(dataVar, callback, callbackData);
      }
    } else {
      jsWarn("If specifying an object, it must be of the form {data : ..., count : N}");
    }
    jsvUnLock(countVar);
    jsvUnLock(dataVar);
  } else if (jsvIsString(data)) {
    JsvStringIterator it;
    jsvStringIteratorNew(&it, data, 0);
    while (jsvStringIteratorHasChar(&it) && ok) {
      char ch = jsvStringIteratorGetChar(&it);
      callback(ch, callbackData);
      jsvStringIteratorNext(&it);
    }
    jsvStringIteratorFree(&it);
  } else if (jsvIsIterable(data)) {
    JsvIterator it;
    jsvIteratorNew(&it, data);
    while (jsvIteratorHasElement(&it) && ok) {
      JsVar *el = jsvIteratorGetValue(&it);
      ok = jsvIterateCallback(el, callback, callbackData);
      jsvUnLock(el);
      jsvIteratorNext(&it);
    }
    jsvIteratorFree(&it);
  } else {
    jsWarn("Expecting a number or something iterable, got %t", data);
    ok = false;
  }
  return ok;
}
Esempio n. 27
0
/*JSON{
  "type" : "staticmethod",
  "class" : "Trig",
  "name" : "killTrigger",
  "generate" : "jswrap_trig_killTrigger",
  "params" : [
    ["num","int","The trigger number (0..7)"]
  ]
}
Disable a trigger
*/
void jswrap_trig_killTrigger(JsVarInt num) {
  TriggerStruct *trig = &mainTrigger;
  if (num<0 || num>=TRIGGER_TRIGGERS_COUNT) {
     jsWarn("Invalid trigger number\n");
     return;
   }

  TriggerPointStruct *tp = &trig->triggers[num];
  tp->tooth = TRIGGERPOINT_TOOTH_DISABLE;
  tp->newTooth = TRIGGERPOINT_TOOTH_DISABLE;
}
Esempio n. 28
0
static void jswrap_waveform_start(JsVar *waveform, Pin pin, JsVarFloat freq, JsVar *options, bool isWriting) {
  bool running = jsvGetBoolAndUnLock(jsvObjectGetChild(waveform, "running", 0));
  if (running) {
    jsExceptionHere(JSET_ERROR, "Waveform is already running");
    return;
  }
  if (!jshIsPinValid(pin)) {
    jsExceptionHere(JSET_ERROR, "Invalid pin");
    return;
  }
  if (!isfinite(freq) || freq<0.001) {
    jsExceptionHere(JSET_ERROR, "Frequency must be above 0.001Hz");
    return;
  }

  JsSysTime startTime = jshGetSystemTime();
  bool repeat = false;
  if (jsvIsObject(options)) {
    JsVarFloat t = jsvGetFloatAndUnLock(jsvObjectGetChild(options, "time", 0));
    if (isfinite(t) && t>0)
       startTime = jshGetTimeFromMilliseconds(t*1000);
    repeat = jsvGetBoolAndUnLock(jsvObjectGetChild(options, "repeat", 0));
  } else if (!jsvIsUndefined(options)) {
    jsExceptionHere(JSET_ERROR, "Expecting options to be undefined or an Object, not %t", options);
  }

  bool is16Bit = false;
  JsVar *buffer = jswrap_waveform_getBuffer(waveform,0, &is16Bit);
  JsVar *buffer2 = jswrap_waveform_getBuffer(waveform,1,0);

  UtilTimerEventType eventType;

  if (is16Bit) {
    eventType = isWriting ? UET_WRITE_SHORT : UET_READ_SHORT;
  } else {
    eventType = isWriting ? UET_WRITE_BYTE : UET_READ_BYTE;
  }


  // And finally set it up
  if (!jstStartSignal(startTime, jshGetTimeFromMilliseconds(1000.0 / freq), pin, buffer, repeat?(buffer2?buffer2:buffer):0, eventType))
    jsWarn("Unable to schedule a timer");
  jsvUnLock(buffer);
  jsvUnLock(buffer2);

  jsvUnLock(jsvObjectSetChild(waveform, "running", jsvNewFromBool(true)));
  jsvUnLock(jsvObjectSetChild(waveform, "freq", jsvNewFromFloat(freq)));
  // Add to our list of active waveforms
  JsVar *waveforms = jsvObjectGetChild(execInfo.hiddenRoot, JSI_WAVEFORM_NAME, JSV_ARRAY);
  if (waveforms) {
    jsvArrayPush(waveforms, waveform);
    jsvUnLock(waveforms);
  }
}
Esempio n. 29
0
/*JSON{
  "type" : "method",
  "class" : "File",
  "name" : "seek",
  "generate_full" : "jswrap_file_skip_or_seek(parent,nBytes,false)",
  "params" : [
    ["nBytes","int32","is an integer specifying the number of bytes to skip forwards."]
  ]
}
Seek to a certain position in the file
*/
void jswrap_file_skip_or_seek(JsVar* parent, int nBytes, bool is_skip) {
  if (nBytes<0) {
    if ( is_skip ) 
	  jsWarn("Bytes to skip must be >=0");
    else 
	  jsWarn("Position to seek to must be >=0");
    return;
  }
  FRESULT res = 0;
  if (jsfsInit()) {
    JsFile file;
    if (fileGetFromVar(&file, parent)) {
      if(file.data->mode == FM_READ || file.data->mode == FM_WRITE || file.data->mode == FM_READ_WRITE) {
  #ifndef LINUX
        res = (FRESULT)f_lseek(&file.data->handle, (DWORD)(is_skip ? f_tell(&file.data->handle) : 0) + (DWORD)nBytes);
  #else
        fseek(file.data->handle, nBytes, is_skip ? SEEK_CUR : SEEK_SET);
  #endif
      }
    }
  }
  if (res) jsfsReportError(is_skip?"Unable to skip":"Unable to seek", res);
}
/*JSON{ "type":"method", "class": "Object", "name" : "on",
         "description" : ["Register an event listener for this object, for instance ```http.on('data', function(d) {...})```. See Node.js's EventEmitter."],
         "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"] ]
}*/
void jswrap_object_on(JsVar *parent, JsVar *event, JsVar *listener) {
  if (!jsvIsObject(parent)) {
      jsWarn("Parent must be a proper 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;
  }
  char eventName[16] = "#on";
  jsvGetString(event, &eventName[3], sizeof(eventName)-4);

  JsVar *eventList = jsvFindChildFromString(parent, eventName, true);
  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 = jsvNewWithFlags(JSV_ARRAY);
      jsvArrayPush(arr, eventListeners);
      jsvArrayPush(arr, listener);
      jsvSetValueOfName(eventList, arr);
      jsvUnLock(arr);
    }
  }
  jsvUnLock(eventListeners);
  jsvUnLock(eventList);
}