예제 #1
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);
}
예제 #2
0
static bool handlePipe(JsVar *arr, JsvObjectIterator *it, JsVar* pipe) {
  bool paused = jsvGetBoolAndUnLock(jsvObjectGetChild(pipe,"drainWait",0));
  if (paused) return false;

  JsVar *position = jsvObjectGetChild(pipe,"position",0);
  JsVar *chunkSize = jsvObjectGetChild(pipe,"chunkSize",0);
  JsVar *source = jsvObjectGetChild(pipe,"source",0);
  JsVar *destination = jsvObjectGetChild(pipe,"destination",0);

  bool dataTransferred = false;
  if(source && destination && chunkSize && position) {
    JsVar *readFunc = jspGetNamedField(source, "read", false);
    JsVar *writeFunc = jspGetNamedField(destination, "write", false);
    if (jsvIsFunction(readFunc) && jsvIsFunction(writeFunc)) { // do the objects have the necessary methods on them?
      JsVar *buffer = jspExecuteFunction(readFunc, source, 1, &chunkSize);
      if(buffer) {
        JsVarInt bufferSize = jsvGetLength(buffer);
        if (bufferSize>0) {
          JsVar *response = jspExecuteFunction(writeFunc, destination, 1, &buffer);
          if (jsvIsBoolean(response) && jsvGetBool(response)==false) {
            // If boolean false was returned, wait for drain event (http://nodejs.org/api/stream.html#stream_writable_write_chunk_encoding_callback)
            jsvUnLock(jsvObjectSetChild(pipe,"drainWait",jsvNewFromBool(true)));
          }
          jsvUnLock(response);
          jsvSetInteger(position, jsvGetInteger(position) + bufferSize);
        }
        jsvUnLock(buffer);
        dataTransferred = true; // so we don't close the pipe if we get an empty string
      }
    } else {
      if(!jsvIsFunction(readFunc))
        jsExceptionHere(JSET_ERROR, "Source Stream does not implement the required read(length) method.");
      if(!jsvIsFunction(writeFunc))
        jsExceptionHere(JSET_ERROR, "Destination Stream does not implement the required write(buffer) method.");
    }
    jsvUnLock(readFunc);
    jsvUnLock(writeFunc);
  }

  if(!dataTransferred) { // when no more chunks are possible, execute the callback
    handlePipeClose(arr, it, pipe);
  }
  jsvUnLock(source);
  jsvUnLock(destination);
  jsvUnLock(chunkSize);
  jsvUnLock(position);
  return dataTransferred;
}
예제 #3
0
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
}
예제 #4
0
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);
}
예제 #5
0
static void handlePipeClose(JsVar *arr, JsvObjectIterator *it, JsVar* pipe) {
  jsiQueueObjectCallbacks(pipe, "#oncomplete", &pipe, 1);
  // also call 'end' if 'end' was passed as an initialisation option
  if (jsvGetBoolAndUnLock(jsvObjectGetChild(pipe,"end",0))) {
    // call destination.end if available
    JsVar *destination = jsvObjectGetChild(pipe,"destination",0);
    if (destination) {
      // remove our drain and close listeners.
      // TODO: This removes ALL listeners. Maybe we should just remove ours?
      jswrap_object_removeAllListeners_cstr(destination, "drain");
      jswrap_object_removeAllListeners_cstr(destination, "close");
      // execute the 'end' function
      JsVar *endFunc = jspGetNamedField(destination, "end", false);
      if (endFunc) {
        jsvUnLock(jspExecuteFunction(endFunc, destination, 0, 0));
        jsvUnLock(endFunc);
      }
      // execute the 'close' function
      JsVar *closeFunc = jspGetNamedField(destination, "close", false);
      if (closeFunc) {
        jsvUnLock(jspExecuteFunction(closeFunc, destination, 0, 0));
        jsvUnLock(closeFunc);
      }
      jsvUnLock(destination);
    }
    /* call source.close if available - probably not what node does
    but seems very sensible in this case. If you don't want it,
    set end:false */
    JsVar *source = jsvObjectGetChild(pipe,"source",0);
    if (source) {
      // TODO: This removes ALL listeners. Maybe we should just remove ours?
      jswrap_object_removeAllListeners_cstr(source, "close");
      // execute the 'close' function
      JsVar *closeFunc = jspGetNamedField(source, "close", false);
      if (closeFunc) {
        jsvUnLock(jspExecuteFunction(closeFunc, source, 0, 0));
        jsvUnLock(closeFunc);
      }
    }
    jsvUnLock(source);
  }
  JsVar *idx = jsvObjectIteratorGetKey(it);
  jsvRemoveChild(arr,idx);
  jsvUnLock(idx);
}
예제 #6
0
/*JSON{
  "type" : "staticmethod",
  "class" : "Object",
  "name" : "setPrototypeOf",
  "generate" : "jswrap_object_setPrototypeOf",
  "params" : [
    ["object","JsVar","An object"],
    ["prototype","JsVar","The prototype to set on the object"]
  ],
  "return" : ["JsVar","The object passed in"]
}
Creates a new object with the specified prototype object and properties. properties are currently unsupported.
 */
JsVar *jswrap_object_setPrototypeOf(JsVar *object, JsVar *proto) {
  JsVar *v = jspGetNamedField(object, "__proto__", true);
  if (!jsvIsName(v)) {
    jsExceptionHere(JSET_TYPEERROR, "Can't extend this object\n");
  } else {
    jsvSetValueOfName(v, proto);
  }
  jsvUnLock(v);
  return jsvLockAgain(object);
}
예제 #7
0
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
}
예제 #8
0
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);
}
예제 #9
0
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);
}
예제 #10
0
/*JSON{
  "type" : "staticmethod",
  "class" : "Object",
  "name" : "getPrototypeOf",
  "generate" : "jswrap_object_getPrototypeOf",
  "params" : [
    ["object","JsVar","An object"]
  ],
  "return" : ["JsVar","The prototype"]
}
Get the prototype of the give object - this is like writing `object.__proto__`
but is the expected ES6
 */
JsVar *jswrap_object_getPrototypeOf(JsVar *object) {
  return jspGetNamedField(object, "__proto__", false);
}
예제 #11
0
void jsfGetJSONWithCallback(JsVar *var, JSONFlags flags, const char *whitespace, vcbprintf_callback user_callback, void *user_data) {
  JSONFlags nflags = flags + JSON_INDENT; // if we add a newline, make sure we indent any subsequent JSON more
  if (!whitespace) whitespace="  ";

  if (jsvIsUndefined(var)) {
    cbprintf(user_callback, user_data, "undefined");
  } else {
    // Use IS_RECURSING  flag to stop recursion
    if (var->flags & JSV_IS_RECURSING) {
      cbprintf(user_callback, user_data, " ... ");
      return;
    }
    var->flags |= JSV_IS_RECURSING;

    if (jsvIsArray(var)) {
      JsVarInt length = jsvGetArrayLength(var);
      bool limited = (flags&JSON_LIMIT) && (length>(JsVarInt)JSON_LIMIT_AMOUNT);
      bool needNewLine = false;
      cbprintf(user_callback, user_data, (flags&JSON_PRETTY)?"[ ":"[");
      JsVarInt lastIndex = -1;
      bool numeric = true;
      bool first = true;
      JsvObjectIterator it;
      jsvObjectIteratorNew(&it, var);
      while (lastIndex+1<length && numeric && !jspIsInterrupted()) {
        JsVar *key = jsvObjectIteratorGetKey(&it);
        if (!jsvObjectIteratorHasValue(&it) || jsvIsNumeric(key)) {
          JsVarInt index = jsvObjectIteratorHasValue(&it) ? jsvGetInteger(key) : length-1;
          JsVar *item = jsvObjectIteratorGetValue(&it);
          while (lastIndex < index) {
            lastIndex++;
            if (!limited || lastIndex<(JsVarInt)JSON_LIMITED_AMOUNT || lastIndex>=length-(JsVarInt)JSON_LIMITED_AMOUNT) {
              if (!first) cbprintf(user_callback, user_data, (flags&JSON_PRETTY)?", ":",");
              first = false;
              if (limited && lastIndex==length-(JsVarInt)JSON_LIMITED_AMOUNT) cbprintf(user_callback, user_data, JSON_LIMIT_TEXT);
              bool newNeedsNewLine = ((flags&JSON_SOME_NEWLINES) && jsonNeedsNewLine(item));
              if (flags&JSON_ALL_NEWLINES) {
                needNewLine = true;
                newNeedsNewLine = true;
              }
              if (needNewLine || newNeedsNewLine) {
                jsonNewLine(nflags, whitespace, user_callback, user_data);
                needNewLine = false;
              }
              if (lastIndex == index)
                jsfGetJSONWithCallback(item, nflags, whitespace, user_callback, user_data);
              else
                cbprintf(user_callback, user_data, (flags&JSON_NO_UNDEFINED)?"null":"undefined");
              needNewLine = newNeedsNewLine;
            }
          }
          jsvUnLock(item);
          jsvObjectIteratorNext(&it);
        } else {
          numeric = false;
        }
        jsvUnLock(key);
      }

      // non-numeric  - but NOT for standard JSON
      if ((flags&JSON_PRETTY))
        jsfGetJSONForObjectItWithCallback(&it, flags, whitespace, nflags, user_callback, user_data, first);
      jsvObjectIteratorFree(&it);
      if (needNewLine) jsonNewLine(flags, whitespace, user_callback, user_data);
      cbprintf(user_callback, user_data, (flags&JSON_PRETTY)?" ]":"]");
    } else if (jsvIsArrayBuffer(var)) {
      JsvArrayBufferIterator it;
      bool allZero = true;
      jsvArrayBufferIteratorNew(&it, var, 0);
      while (jsvArrayBufferIteratorHasElement(&it)) {
        if (jsvArrayBufferIteratorGetFloatValue(&it)!=0)
          allZero = false;
        jsvArrayBufferIteratorNext(&it);
      }
      jsvArrayBufferIteratorFree(&it);
      bool asArray = flags&JSON_ARRAYBUFFER_AS_ARRAY;

      if (allZero && !asArray) {
        cbprintf(user_callback, user_data, "new %s(%d)", jswGetBasicObjectName(var), jsvGetArrayBufferLength(var));
      } else {
        const char *aname = jswGetBasicObjectName(var);
        /* You can't do `new ArrayBuffer([1,2,3])` so we have to output
         * `new Uint8Array([1,2,3]).buffer`! */
        bool isBasicArrayBuffer = strcmp(aname,"ArrayBuffer")==0;
        if (isBasicArrayBuffer) {
          aname="Uint8Array";
        }
        cbprintf(user_callback, user_data, asArray?"[":"new %s([", aname);
        if (flags&JSON_ALL_NEWLINES) jsonNewLine(nflags, whitespace, user_callback, user_data);
        size_t length = jsvGetArrayBufferLength(var);
        bool limited = (flags&JSON_LIMIT) && (length>JSON_LIMIT_AMOUNT);
        // no newlines needed for array buffers as they only contain simple stuff

        jsvArrayBufferIteratorNew(&it, var, 0);
        while (jsvArrayBufferIteratorHasElement(&it) && !jspIsInterrupted()) {
          if (!limited || it.index<JSON_LIMITED_AMOUNT || it.index>=length-JSON_LIMITED_AMOUNT) {
            if (it.index>0) cbprintf(user_callback, user_data, (flags&JSON_PRETTY)?", ":",");
            if (flags&JSON_ALL_NEWLINES) jsonNewLine(nflags, whitespace, user_callback, user_data);
            if (limited && it.index==length-JSON_LIMITED_AMOUNT) cbprintf(user_callback, user_data, JSON_LIMIT_TEXT);
            JsVar *item = jsvArrayBufferIteratorGetValue(&it);
            jsfGetJSONWithCallback(item, nflags, whitespace, user_callback, user_data);
            jsvUnLock(item);
          }
          jsvArrayBufferIteratorNext(&it);
        }
        if (flags&JSON_ALL_NEWLINES) jsonNewLine(flags, whitespace, user_callback, user_data);
        jsvArrayBufferIteratorFree(&it);
        cbprintf(user_callback, user_data, asArray?"]":"])");
        if (isBasicArrayBuffer && !asArray) cbprintf(user_callback, user_data, ".buffer");
      }
    } else if (jsvIsObject(var)) {
      IOEventFlags device = (flags & JSON_SHOW_DEVICES) ? jsiGetDeviceFromClass(var) : EV_NONE;
      if (device!=EV_NONE) {
        cbprintf(user_callback, user_data, "%s", jshGetDeviceString(device));
      } else {
        bool showContents = true;
        if (flags & JSON_SHOW_OBJECT_NAMES) {
          JsVar *proto = jsvObjectGetChild(var, JSPARSE_INHERITS_VAR, 0);
          if (jsvHasChildren(proto)) {
            JsVar *constr = jsvObjectGetChild(proto, JSPARSE_CONSTRUCTOR_VAR, 0);
            if (constr) {
              JsVar *p = jsvGetIndexOf(execInfo.root, constr, true);
              if (p) cbprintf(user_callback, user_data, "%v: ", p);
              jsvUnLock2(p,constr);
              /* We had the constructor - now if there was a non-default toString function
               * we'll execute it and print the result */
              JsVar *toStringFn = jspGetNamedField(var, "toString", false);
              if (toStringFn && toStringFn->varData.native.ptr != (void (*)(void))jswrap_object_toString) {
                // Function found and it's not the default one - execute it
                JsVar *result = jspExecuteFunction(toStringFn,var,0,0);
                cbprintf(user_callback, user_data, "%v", result);
                jsvUnLock(result);
                showContents = false; // we already printed something
              }
              jsvUnLock(toStringFn);
            }
          }
          jsvUnLock(proto);
        }
        if (showContents) {
          JsvObjectIterator it;
          jsvObjectIteratorNew(&it, var);
          cbprintf(user_callback, user_data, (flags&JSON_PRETTY)?"{ ":"{");
          bool needNewLine = jsfGetJSONForObjectItWithCallback(&it, flags, whitespace, nflags, user_callback, user_data, true);
          jsvObjectIteratorFree(&it);
          if (needNewLine) jsonNewLine(flags, whitespace, user_callback, user_data);
          cbprintf(user_callback, user_data, (flags&JSON_PRETTY)?" }":"}");
        }
      }
    } else if (jsvIsFunction(var)) {
      if (flags & JSON_IGNORE_FUNCTIONS) {
        cbprintf(user_callback, user_data, "undefined");
      } else {
        cbprintf(user_callback, user_data, "function ");
        jsfGetJSONForFunctionWithCallback(var, nflags, user_callback, user_data);
      }
    } else if (jsvIsString(var) && !jsvIsName(var)) {
      if ((flags&JSON_LIMIT) && jsvGetStringLength(var)>JSON_LIMIT_STRING_AMOUNT) {
        // if the string is too big, split it and put dots in the middle
        JsVar *var1 = jsvNewFromStringVar(var, 0, JSON_LIMITED_STRING_AMOUNT);
        JsVar *var2 = jsvNewFromStringVar(var, jsvGetStringLength(var)-JSON_LIMITED_STRING_AMOUNT, JSON_LIMITED_STRING_AMOUNT);
        cbprintf(user_callback, user_data, "%q%s%q", var1, JSON_LIMIT_TEXT, var2);
        jsvUnLock2(var1, var2);
      } else {
        cbprintf(user_callback, user_data, "%q", var);
      }
    } else {
      cbprintf(user_callback, user_data, "%v", var);
    }

    var->flags &= ~JSV_IS_RECURSING;
  }
}
예제 #12
0
static void handlePipeClose(JsVar *arr, JsvObjectIterator *it, JsVar* pipe) {
  jsiQueueObjectCallbacks(pipe, "#oncomplete", &pipe, 1);
  // Check the source to see if there was more data... It may not be a stream,
  // but if it is and it has data it should have a a STREAM_BUFFER_NAME field
  JsVar *source = jsvObjectGetChild(pipe,"source",0);
  JsVar *destination = jsvObjectGetChild(pipe,"destination",0);
  if (source && destination) {
    JsVar *buffer = jsvObjectGetChild(source, STREAM_BUFFER_NAME, 0);
    if (buffer && jsvGetStringLength(buffer)) {
      jsvObjectSetChild(source, STREAM_BUFFER_NAME, 0); // remove outstanding data
      /* call write fn - we ignore drain/etc here because the source has
      just closed and we want to get this sorted quickly */
      JsVar *writeFunc = jspGetNamedField(destination, "write", false);
      if (jsvIsFunction(writeFunc)) // do the objects have the necessary methods on them?
        jsvUnLock(jspExecuteFunction(writeFunc, destination, 1, &buffer));
      jsvUnLock(writeFunc);
      // update position
      JsVar *position = jsvObjectGetChild(pipe,"position",0);
      jsvSetInteger(position, jsvGetInteger(position) + (JsVarInt)jsvGetStringLength(buffer));
      jsvUnLock(position);
    }
    jsvUnLock(buffer);
  }
  // also call 'end' if 'end' was passed as an initialisation option
  if (jsvGetBoolAndUnLock(jsvObjectGetChild(pipe,"end",0))) {
    // call destination.end if available
    if (destination) {
      // remove our drain and close listeners.
      // TODO: This removes ALL listeners. Maybe we should just remove ours?
      jswrap_object_removeAllListeners_cstr(destination, "drain");
      jswrap_object_removeAllListeners_cstr(destination, "close");
      // execute the 'end' function
      JsVar *endFunc = jspGetNamedField(destination, "end", false);
      if (endFunc) {
        jsvUnLock(jspExecuteFunction(endFunc, destination, 0, 0));
        jsvUnLock(endFunc);
      }
      // execute the 'close' function
      JsVar *closeFunc = jspGetNamedField(destination, "close", false);
      if (closeFunc) {
        jsvUnLock(jspExecuteFunction(closeFunc, destination, 0, 0));
        jsvUnLock(closeFunc);
      }
    }
    /* call source.close if available - probably not what node does
    but seems very sensible in this case. If you don't want it,
    set end:false */
    if (source) {
      // TODO: This removes ALL listeners. Maybe we should just remove ours?
      jswrap_object_removeAllListeners_cstr(source, "close");
      // execute the 'close' function
      JsVar *closeFunc = jspGetNamedField(source, "close", false);
      if (closeFunc) {
        jsvUnLock(jspExecuteFunction(closeFunc, source, 0, 0));
        jsvUnLock(closeFunc);
      }
    }
  }
  jsvUnLock(source);
  jsvUnLock(destination);
  JsVar *idx = jsvObjectIteratorGetKey(it);
  jsvRemoveChild(arr,idx);
  jsvUnLock(idx);
}
예제 #13
0
/*JSON{
  "type" : "init",
  "generate" : "jswrap_wice_init"
}*/
void jswrap_wice_init() {
  jspCallNamedFunction(execInfo.root, "USB.setConsole", 0, 0);
  jspEvaluate("USB.setConsole();");
#ifdef WICE_DEBUG
  WDEBUGLN("USB is console");
#endif
  /*JsVar *mode = jsvNewFromString("output");
  jswrap_io_pinMode(jshGetPinFromString(PIN_DASH7_XTAL_EN), mode);
  jswrap_io_pinMode(jshGetPinFromString(PIN_DASH7_RST), mode);
  jsvUnLock(mode);*/

  enableDASH();

  // Set up the DASH7 USART how we want it
  JshUSARTInfo inf;
  jshUSARTInitInfo(&inf);
  inf.baudRate = 115200;
  inf.pinRX = jshGetPinFromString(PIN_DASH7_RX);
  inf.pinTX = jshGetPinFromString(PIN_DASH7_TX);
  jshUSARTSetup(EV_SERIAL1, &inf);

  JsVar *serial = jspGetNamedField(execInfo.root, SERIAL1_DASH7, false);
  jswrap_object_addEventListener(serial, "data", dash7Callback, JSWAT_VOID | (JSWAT_JSVAR<<(JSWAT_BITS)));
  jsvUnLock(serial);

  startTime = jshGetSystemTime();

  wice_msg_init(&wifiMessage, wifiMessageBuffer, 2048);
  wice_msg_init(&dash7Message, dash7MessageBuffer, 256);


  options = jspEvaluate("x = {\"repeat\": \"true\", \"edge\": \"rising\", \"debounce\":\"50\"}");
  Pin btn = jshGetPinFromString("B10");
  JsVar *btnmode = jsvNewFromString("input");
  jswrap_io_pinMode(btn, btnmode);
  jsvUnLock(btnmode);

#ifdef GATEWAY
  WDEBUGLN("GATEWAY");
  blink(PIN_GRN, 50);
  /// opendrain and digitalwrite 1 will 'opencircuit it'
  /// http://www.espruino.com/Reference#l__global_pinMode
  JsVar *opendrain = jsvNewFromString("opendrain");
  WDEBUGSTRVAR(opendrain);
  jswrap_io_pinMode(jshGetPinFromString(PIN_ESP_GPIO_0), opendrain);
  jswrap_io_pinMode(jshGetPinFromString(PIN_ESP_GPIO_2), opendrain);
  jshPinOutput(jshGetPinFromString(PIN_ESP_GPIO_0), 1);
  jshPinOutput(jshGetPinFromString(PIN_ESP_GPIO_2), 1);
  jsvUnLock(opendrain);
  /// must opendrain gpio0/2 because of boot modes
  /// https://github.com/esp8266/esp8266-wiki/wiki/Boot-Process
  enableWifi();

  // Set up the Wifi USART how we want it
  JshUSARTInfo inf4;
  jshUSARTInitInfo(&inf4);
  inf4.baudRate = 115200;
  inf4.pinRX = jshGetPinFromString(PIN_ESP_RX);
  inf4.pinTX = jshGetPinFromString(PIN_ESP_TX);
  jshUSARTSetup(EV_SERIAL4, &inf4);

  /// make button restart wifi for gateway
  JsVar *restartWifi_fn = jsvNewNativeFunction(restartWifi, JSWAT_VOID);
  btnEvent = jswrap_interface_setWatch(restartWifi_fn,
                            btn, 
                            options);
  jsvUnLock(restartWifi_fn);
  /// configure wifi usart callback
  JsVar *wifiSerial = jspGetNamedField(execInfo.root, SERIAL4_WIFI, false);
  jswrap_object_addEventListener(wifiSerial, "data", wifiCallback, JSWAT_VOID | (JSWAT_JSVAR<<(JSWAT_BITS)));
  jsvUnLock(wifiSerial);
  doSendSerial();
#else 
  WDEBUGLN("NODE");
  blink(PIN_BLUE, 50);
  /// make button a forced measurement for nodes
  JsVar *doMeasurementAndWaitForResponse_fn = jsvNewNativeFunction(doMeasurementAndWaitForResponse, JSWAT_VOID);
  btnEvent = jswrap_interface_setWatch(doMeasurementAndWaitForResponse_fn,
                            btn, 
                            options);
  jsvUnLock(doMeasurementAndWaitForResponse_fn);

  /// set up main interval callback for nodes
  JsVar *doMeasurement_fn = jsvNewNativeFunction(doMeasurement, JSWAT_VOID);
  currentInterval = jswrap_interface_setInterval(doMeasurement_fn, INTERVAL, 0);
  jsvUnLock(doMeasurement_fn);

  /// prepare the I2C bus for talking with the Si7050 temp sensor
  JsVar *s = jspEvaluate("I2C1.setup({scl:B8, sda:B9, bitrate:50000});"); jsvUnLock(s);
  disableDASH();
  jswrap_interface_setDeepSleep(true); //do deep sleep [TODO can we wake on press?]
#endif
}