Beispiel #1
0
/** Set up a UART, if pins are -1 they will be guessed */
void jshUSARTSetup(IOEventFlags device, JshUSARTInfo *inf) {
  if (device != EV_SERIAL1)
    return;

  int baud = getNRFBaud(inf->baudRate);
  if (baud==0)
    return jsError("Invalid baud rate %d", inf->baudRate);
  if (!jshIsPinValid(inf->pinRX) || !jshIsPinValid(inf->pinTX))
    return jsError("Invalid RX or TX pins");

  uint32_t err_code;
  const app_uart_comm_params_t comm_params = {
      pinInfo[inf->pinRX].pin,
      pinInfo[inf->pinTX].pin,
      (uint8_t)UART_PIN_DISCONNECTED,
      (uint8_t)UART_PIN_DISCONNECTED,
      APP_UART_FLOW_CONTROL_DISABLED,
      inf->parity!=0, // TODO: ODD or EVEN parity?
      baud
  };

  APP_UART_INIT(&comm_params,
                uart0_event_handle,
                APP_IRQ_PRIORITY_HIGH,
                err_code);
  APP_ERROR_CHECK(err_code);
}
Beispiel #2
0
IOEventFlags jshPinWatch(Pin pin, bool shouldWatch) {
  if (jshIsPinValid(pin)) {
    IOEventFlags exti = getNewEVEXTI();
    if (shouldWatch) {
      if (exti) {
        gpioEventFlags[pin] = exti;
        jshPinSetState(pin, JSHPINSTATE_GPIO_IN);
#ifdef SYSFS_GPIO_DIR
        gpioShouldWatch[pin] = true;
        gpioLastState[pin] = jshPinGetValue(pin);
#endif
#ifdef USE_WIRINGPI
        wiringPiISR(pin, INT_EDGE_BOTH, irqEXTIs[exti-EV_EXTI0]);
#endif
      } else 
        jsError("You can only have a maximum of 16 watches!");
    }
    if (!shouldWatch || !exti) {
      gpioEventFlags[pin] = 0;
#ifdef SYSFS_GPIO_DIR
      gpioShouldWatch[pin] = false;
#endif
#ifdef USE_WIRINGPI
      wiringPiISR(pin, INT_EDGE_BOTH, irqEXTIDoNothing);
#endif

    }
    return shouldWatch ? exti : EV_NONE;
  } else jsError("Invalid pin!");
  return EV_NONE;
}
Beispiel #3
0
/*JSON{ "type":"method", "class": "Array", "name" : "reduce",
         "description" : "Execute `previousValue=initialValue` and then `previousValue = callback(previousValue, currentValue, index, array)` for each element in the array, and finally return previousValue.",
         "generate" : "jswrap_array_reduce",
         "params" : [ [ "callback", "JsVar", "Function used to reduce the array"] ,
                      [ "initialValue", "JsVar", "if specified, the initial value to pass to the function"] ],
         "return" : ["JsVar", "The value returned by the last function called"]
}*/
JsVar *jswrap_array_reduce(JsVar *parent, JsVar *funcVar, JsVar *initialValue) {
  const char *name = "reduce";
  if (!jsvIsIterable(parent)) {
    jsError("Array.%s can only be called on something iterable", name);
    return 0;
  }
  if (!jsvIsFunction(funcVar)) {
    jsError("Array.%s's first argument should be a function", name);
    return 0;
  }
  JsVar *previousValue = initialValue ? jsvLockAgain(initialValue) : 0;
  JsvIterator it;
  jsvIteratorNew(&it, parent);
  while (jsvIteratorHasElement(&it)) {
    JsVar *index = jsvIteratorGetKey(&it);
    if (jsvIsInt(index)) {
      JsVarInt idxValue = jsvGetInteger(index);

      JsVar *args[4];
      args[0] = previousValue;
      args[1] = jsvIteratorGetValue(&it);
      args[2] = jsvNewFromInteger(idxValue); // child is a variable name, create a new variable for the index
      args[3] = parent;
      previousValue = jspeFunctionCall(funcVar, 0, 0, false, 4, args);
      jsvUnLock(args[0]);
      jsvUnLock(args[1]);
      jsvUnLock(args[2]);
    }
    jsvUnLock(index);
    jsvIteratorNext(&it);
  }
  jsvIteratorFree(&it);

  return previousValue;
}
/*JSON{
  "type" : "staticmethod",
  "class" : "crypto",
  "name" : "PBKDF2",
  "generate" : "jswrap_crypto_PBKDF2",
  "params" : [
    ["passphrase","JsVar","Passphrase"],
    ["salt","JsVar","Salt for turning passphrase into a key"],
    ["options","JsVar","Object of Options, `{ keySize: 8 (in 32 bit words), iterations: 10, hasher: 'SHA1'/'SHA224'/'SHA256'/'SHA384'/'SHA512' }`"]
  ],
  "return" : ["JsVar","Returns an ArrayBuffer"],
  "return_object" : "ArrayBuffer",
  "ifdef" : "USE_TLS"
}

Password-Based Key Derivation Function 2 algorithm, using SHA512
*/
JsVar *jswrap_crypto_PBKDF2(JsVar *passphrase, JsVar *salt, JsVar *options) {
  int iterations = 1;
  int keySize = 128/32;
  mbedtls_md_type_t hasher = MBEDTLS_MD_SHA1;


  if (jsvIsObject(options)) {
    keySize = jsvGetIntegerAndUnLock(jsvObjectGetChild(options, "keySize", 0));
    if (keySize<=0) keySize=128/32;
    iterations = jsvGetIntegerAndUnLock(jsvObjectGetChild(options, "iterations", 0));
    if (iterations<1) iterations = 1;

    JsVar *hashVar = jsvObjectGetChild(options, "hasher", 0);
    if (!jsvIsUndefined(hashVar))
      hasher = jswrap_crypto_getHasher(hashVar);
    jsvUnLock(hashVar);

  } else if (!jsvIsUndefined(options))
    jsError("Options should be an object or undefined, got %t", options);

  if (hasher == MBEDTLS_MD_NONE)
    return 0; // already shown an error

  JSV_GET_AS_CHAR_ARRAY(passPtr, passLen, passphrase);
  if (!passPtr) return 0;
  JSV_GET_AS_CHAR_ARRAY(saltPtr, saltLen, salt);
  if (!saltPtr) return 0;

  int err;
  mbedtls_md_context_t ctx;

  mbedtls_md_init( &ctx );
  err = mbedtls_md_setup( &ctx, mbedtls_md_info_from_type( hasher ), 1 );
  assert(err==0);

  char *keyPtr = 0;
  JsVar *keyArr = jsvNewArrayBufferWithPtr((unsigned)keySize*4, &keyPtr);
  if (!keyPtr) {
    jsError("Not enough memory for result");
    return 0;
  }

  err = mbedtls_pkcs5_pbkdf2_hmac( &ctx,
        (unsigned char*)passPtr, passLen,
        (unsigned char*)saltPtr, saltLen,
        (unsigned)iterations,
        (unsigned)keySize*4, (unsigned char*)keyPtr );
  mbedtls_md_free( &ctx );
  if (!err) {
    return keyArr;
  } else {
    jswrap_crypto_error(err);
    jsvUnLock(keyArr);
    return 0;
  }
}
void jswrap_crypto_error(int err) {
  const char *e = 0;
  switch(err) {
    case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE: e="Feature unavailable"; break;
    case MBEDTLS_ERR_MD_BAD_INPUT_DATA: e="Bad Input Data"; break;
    case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH: e="Invalid input length"; break;
  }
  if (e) jsError(e);
  else jsError("Unknown error: -0x%x", -err);
}
Beispiel #6
0
/*JSON{ "type":"function", "name" : "edit",
        "description" : ["Fill the console with the contents of the given function, so you can edit it.",
                         "NOTE: This is a convenience function - it will not edit 'inner functions'. For that, you must edit the 'outer function' and re-execute it."],
        "generate" : "jswrap_interface_edit",
        "params" : [ [ "funcName", "JsVar", "The name of the function to edit (either a string or just the unquoted name)"] ]
}*/
void jswrap_interface_edit(JsVar *funcName) {
  JsVar *func = 0;
  if (jsvIsString(funcName)) {
    funcName = jsvLockAgain(funcName);
    func = jsvSkipNameAndUnLock(jsvFindChildFromVar(execInfo.root, funcName, 0));
  } else {
    func = funcName;
    funcName = jsvGetPathTo(execInfo.root, func, 2);
  }

  if (jsvIsString(funcName)) {
    if (jsvIsFunction(func)) {
      JsVar *scopeVar = jsvFindChildFromString(func, JSPARSE_FUNCTION_SCOPE_NAME, false);
      JsVar *inRoot = jsvGetArrayIndexOf(execInfo.root, func, true);
      bool normalDecl = scopeVar==0 && inRoot!=0;
      jsvUnLock(inRoot);
      jsvUnLock(scopeVar);
      JsVar *newLine = jsvNewFromEmptyString();
      if (newLine) { // could be out of memory
        /* normalDecl:
         *
         * function foo() { ... }
         *
         * NOT normalDecl:
         *
         * foo.replaceWith(function() { ... });
         *
         */
        JsVar *funcData = jsvAsString(func, false);

        if (normalDecl) {
          jsvAppendString(newLine, "function ");
          jsvAppendStringVarComplete(newLine, funcName);
          jsvAppendStringVar(newLine, funcData, 9, JSVAPPENDSTRINGVAR_MAXLENGTH);

        } else {
          jsvAppendStringVarComplete(newLine, funcName);
          jsvAppendString(newLine, ".replaceWith(");
          jsvAppendStringVarComplete(newLine, funcData);
          jsvAppendString(newLine, ");");
        }
        jsvUnLock(funcData);
        jsiReplaceInputLine(newLine);
        jsvUnLock(newLine);
      }
    } else {
      jsError("Edit should be called with the name of a function");
    }
  } else {
    jsError("Edit should be called with edit(funcName) or edit('funcName')");
  }
  jsvUnLock(func);
  jsvUnLock(funcName);
}
Beispiel #7
0
// Connect this connection/socket
void clientRequestConnect(JsNetwork *net, JsVar *httpClientReqVar) {
    // Have we already connected? If so, don't go further
    if (jsvGetIntegerAndUnLock(jsvObjectGetChild(httpClientReqVar, HTTP_NAME_SOCKET, 0))>0)
        return;

    SocketType socketType = socketGetType(httpClientReqVar);

    JsVar *options = jsvObjectGetChild(httpClientReqVar, HTTP_NAME_OPTIONS_VAR, false);
    unsigned short port = (unsigned short)jsvGetIntegerAndUnLock(jsvObjectGetChild(options, "port", 0));

    char hostName[128];
    JsVar *hostNameVar = jsvObjectGetChild(options, "host", 0);
    if (jsvIsUndefined(hostNameVar))
        strncpy(hostName, "localhost", sizeof(hostName));
    else
        jsvGetString(hostNameVar, hostName, sizeof(hostName));
    jsvUnLock(hostNameVar);

    uint32_t host_addr = 0;
    networkGetHostByName(net, hostName, &host_addr);

    if(!host_addr) {
        jsError("Unable to locate host\n");
        // As this is already in the list of connections, an error will be thrown on idle anyway
        jsvObjectSetChildAndUnLock(httpClientReqVar, HTTP_NAME_CLOSENOW, jsvNewFromBool(true));
        jsvUnLock(options);
        netCheckError(net);
        return;
    }

    NetCreateFlags flags = NCF_NORMAL;
#ifdef USE_TLS
    if (socketType & ST_TLS) {
        flags |= NCF_TLS;
        if (port==0) port = 443;
    }
#endif

    if (port==0) port = 80;

    int sckt =  netCreateSocket(net, host_addr, port, flags, options);
    if (sckt<0) {
        jsError("Unable to create socket\n");
        // As this is already in the list of connections, an error will be thrown on idle anyway
        jsvObjectSetChildAndUnLock(httpClientReqVar, HTTP_NAME_CLOSENOW, jsvNewFromBool(true));
    } else {
        jsvObjectSetChildAndUnLock(httpClientReqVar, HTTP_NAME_SOCKET, jsvNewFromInteger(sckt+1));
    }

    jsvUnLock(options);

    netCheckError(net);
}
Beispiel #8
0
void lcdInit_SDL(JsGraphics *gfx) {
  if (SDL_Init(SDL_INIT_VIDEO) < 0 ) {
    jsError("SDL_Init failed\n");
    exit(1);
  }
  if (!(screen = SDL_SetVideoMode(gfx->data.width, gfx->data.height, gfx->data.bpp, SDL_SWSURFACE)))
  {
    jsError("SDL_SetVideoMode failed\n");
    SDL_Quit();
    exit(1);
  }
}
Beispiel #9
0
/*JSON{ "type":"method", "class": "ArrayBufferView", "name" : "map",
         "description" : ["Return an array which is made from the following: ```A.map(function) = [function(A[0]), function(A[1]), ...]```",
                          "**Note:** This returns an ArrayBuffer of the same type it was called on. To get an Array, use `Array.prototype.map`" ],
         "generate" : "jswrap_arraybufferview_map",
         "params" : [ [ "function", "JsVar", "Function used to map one item to another"] ,
                      [ "thisArg", "JsVar", "if specified, the function is called with 'this' set to thisArg (optional)"] ],
         "return" : ["JsVar", "An array containing the results"]
}*/
JsVar *jswrap_arraybufferview_map(JsVar *parent, JsVar *funcVar, JsVar *thisVar) {
  if (!jsvIsArrayBuffer(parent)) {
    jsError("ArrayBufferView.map can only be called on an ArrayBufferView");
    return 0;
  }
  if (!jsvIsFunction(funcVar)) {
    jsError("ArrayBufferView.map's first argument should be a function");
    return 0;
  }
  if (!jsvIsUndefined(thisVar) && !jsvIsObject(thisVar)) {
    jsError("ArrayBufferView.map's second argument should be undefined, or an object");
    return 0;
  }

  // create ArrayBuffer result
  JsVarDataArrayBufferViewType arrayBufferType = parent->varData.arraybuffer.type;
  JsVar *arrayBufferLength = jsvNewFromInteger((JsVarInt)jsvGetArrayBufferLength(parent));
  JsVar *array = jswrap_typedarray_constructor(arrayBufferType, arrayBufferLength, 0, 0);
  jsvUnLock(arrayBufferLength);
  if (!array) return 0;

  // now iterate
  JsvIterator it; // TODO: if we really are limited to ArrayBuffers, this could be an ArrayBufferIterator.
  jsvIteratorNew(&it, parent);
  JsvArrayBufferIterator itdst;
  jsvArrayBufferIteratorNew(&itdst, array, 0);

  while (jsvIteratorHasElement(&it)) {
    JsVar *index = jsvIteratorGetKey(&it);
    if (jsvIsInt(index)) {
      JsVarInt idxValue = jsvGetInteger(index);

      JsVar *args[3], *mapped;
      args[0] = jsvIteratorGetValue(&it);
      args[1] = jsvNewFromInteger(idxValue); // child is a variable name, create a new variable for the index
      args[2] = parent;
      mapped = jspeFunctionCall(funcVar, 0, thisVar, false, 3, args);
      jsvUnLock(args[0]);
      jsvUnLock(args[1]);
      if (mapped) {
        jsvArrayBufferIteratorSetValue(&itdst, mapped);
        jsvUnLock(mapped);
      }
    }
    jsvUnLock(index);
    jsvIteratorNext(&it);
    jsvArrayBufferIteratorNext(&itdst);
  }
  jsvIteratorFree(&it);
  jsvArrayBufferIteratorFree(&itdst);

  return array;
}
Beispiel #10
0
JsVar *_jswrap_array_map_or_forEach(JsVar *parent, JsVar *funcVar, JsVar *thisVar, bool isMap) {
  const char *name = isMap ? "map":"forEach";
  if (!jsvIsIterable(parent)) {
    jsError("Array.%s can only be called on something iterable", name);
    return 0;
  }
  if (!jsvIsFunction(funcVar)) {
    jsError("Array.%s's first argument should be a function", name);
    return 0;
  }
  if (!jsvIsUndefined(thisVar) && !jsvIsObject(thisVar)) {
    jsError("Array.%s's second argument should be undefined, or an object", name);
    return 0;
  }
  JsVar *array = 0;
  if (isMap)
    array = jsvNewWithFlags(JSV_ARRAY);
  if (array || !isMap) {
    JsvIterator it;
    jsvIteratorNew(&it, parent);
    while (jsvIteratorHasElement(&it)) {
      JsVar *index = jsvIteratorGetKey(&it);
      if (jsvIsInt(index)) {
        JsVarInt idxValue = jsvGetInteger(index);

        JsVar *args[3], *mapped;
        args[0] = jsvIteratorGetValue(&it);
        args[1] = jsvNewFromInteger(idxValue); // child is a variable name, create a new variable for the index
        args[2] = parent;
        mapped = jspeFunctionCall(funcVar, 0, thisVar, false, 3, args);
        jsvUnLock(args[0]);
        jsvUnLock(args[1]);
        if (mapped) {
          if (isMap) {
            JsVar *name = jsvNewFromInteger(idxValue);
            if (name) { // out of memory?
              jsvMakeIntoVariableName(name, mapped);
              jsvAddName(array, name);
              jsvUnLock(name);
            }
          }
          jsvUnLock(mapped);
        }
      }
      jsvUnLock(index);
      jsvIteratorNext(&it);
    }
    jsvIteratorFree(&it);
  }
  return array;
}
Beispiel #11
0
void jshSPISetup(IOEventFlags device, JshSPIInfo *inf) {
  assert(DEVICE_IS_SPI(device));
   if (ioDevices[device]) close(ioDevices[device]);
   ioDevices[device] = 0;
   char path[256];
   if (jshGetDevicePath(device, path, sizeof(path))) {
     ioDevices[device] = open(path, O_RDWR | O_NOCTTY | O_NONBLOCK);
     if (!ioDevices[device]) {
       jsError("Open of path %s failed", path);
     } else {
     }
   } else {
     jsError("No path defined for device");
   }
}
Beispiel #12
0
/*JSON{ "type":"constructor", "class": "ArrayBuffer",  "name": "ArrayBuffer",
         "description" : "Create an Array Buffer object",
         "generate" : "jswrap_arraybuffer_constructor",
         "params" : [ [ "byteLength", "int", "The length in Bytes" ] ],
         "return" : [ "JsVar", "An ArrayBuffer object" ]

}*/
JsVar *jswrap_arraybuffer_constructor(JsVarInt byteLength) {
  if (byteLength <= 0 || byteLength>65535) {
    jsError("Invalid length for ArrayBuffer\n");
    return 0;
  }
  if (byteLength > JSV_ARRAYBUFFER_MAX_LENGTH) {
    jsError("ArrayBuffer too long\n");
    return 0;
  }
  JsVar *arrData = jsvNewStringOfLength((unsigned int)byteLength);
  if (!arrData) return 0;
  JsVar *v = jsvNewArrayBufferFromString(arrData, (int)byteLength);
  jsvUnLock(arrData);
  return v;
}
Beispiel #13
0
bool jsfsInit() {
#ifndef LINUX
    if (!fat_initialised) {
#ifdef SD_CARD_ANYWHERE
        if (!isSdSPISetup()) {
#ifdef SD_SPI
            const char *deviceStr = jshGetDeviceString(SD_SPI);
            JsVar *spi = jsvSkipNameAndUnLock(jspGetNamedVariable(deviceStr));
            JshSPIInfo inf;
            jshSPIInitInfo(&inf);
            inf.pinMISO = SD_DO_PIN;
            inf.pinMOSI = SD_DI_PIN;
            inf.pinSCK = SD_CLK_PIN;
            jshSPISetup(SD_SPI, &inf);
            sdSPISetup(spi, SD_CS_PIN);
            jsvUnLock(spi);
#else
            jsError("SD card must be setup with E.connectSDCard first");
            return false;
#endif
        }
#endif

        FRESULT res;
        if ((res = f_mount(&jsfsFAT, "", 1/*immediate*/)) != FR_OK) {
            jsfsReportError("Unable to mount SD card", res);
            return false;
        }
        fat_initialised = true;
    }
#endif
    return true;
}
Beispiel #14
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;
}
Beispiel #15
0
/*JSON{
  "type" : "method",
  "class" : "Ethernet",
  "name" : "getIP",
  "generate" : "jswrap_ethernet_getIP",
  "return" : ["JsVar",""]
}
Get the current IP address, subnet, gateway and mac address.
*/
JsVar *jswrap_ethernet_getIP(JsVar *wlanObj) {
  NOT_USED(wlanObj);

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

  JsNetwork net;
  if (!networkGetFromVar(&net)) return 0;

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

  /* If byte 1 is 0 we don't have a valid address */
  JsVar *data = jsvNewWithFlags(JSV_OBJECT);
  networkPutAddressAsString(data, "ip", &gWIZNETINFO.ip[0], 4, 10, '.');
  networkPutAddressAsString(data, "subnet", &gWIZNETINFO.sn[0], 4, 10, '.');
  networkPutAddressAsString(data, "gateway", &gWIZNETINFO.gw[0], 4, 10, '.');
  networkPutAddressAsString(data, "dns", &gWIZNETINFO.dns[0], 4, 10, '.');
  networkPutAddressAsString(data, "mac", &gWIZNETINFO.mac[0], 6, 16, ':');

  networkFree(&net);

  return data;
}
Beispiel #16
0
/*JSON{ "type":"method", "class": "ArrayBufferView",  "name": "set",
         "description" : "Copy the contents of `array` into this one, mapping `this[x+offset]=array[x];`",
         "generate" : "jswrap_arraybufferview_set",
         "params" : [ [ "arr", "JsVar", "Floating point index to access" ], ["offset","int32","The offset in this array at which to write the values (optional)"] ]
}*/
void jswrap_arraybufferview_set(JsVar *parent, JsVar *arr, int offset) {
  if (!(jsvIsString(arr) || jsvIsArray(arr) || jsvIsArrayBuffer(arr))) {
    jsError("Expecting first argument to be an array, not %t", arr);
    return;
  }
  JsvIterator itsrc;
  jsvIteratorNew(&itsrc, arr);
  JsvArrayBufferIterator itdst;
  jsvArrayBufferIteratorNew(&itdst, parent, (size_t)offset);

  bool useInts = JSV_ARRAYBUFFER_IS_FLOAT(itdst.type) || jsvIsString(arr);

  while (jsvIteratorHasElement(&itsrc) && jsvArrayBufferIteratorHasElement(&itdst)) {
    if (useInts) {
      jsvArrayBufferIteratorSetIntegerValue(&itdst, jsvIteratorGetIntegerValue(&itsrc));
    } else {
      JsVar *value = jsvIteratorGetValue(&itsrc);
      jsvArrayBufferIteratorSetValue(&itdst, value);
      jsvUnLock(value);
    }
    jsvArrayBufferIteratorNext(&itdst);
    jsvIteratorNext(&itsrc);
  }
  jsvArrayBufferIteratorFree(&itdst);
  jsvIteratorFree(&itsrc);
}
Beispiel #17
0
/// if host=0, creates a server otherwise creates a client (and automatically connects). Returns >=0 on success
int net_cc3000_createsocket(JsNetwork *net, unsigned long host, unsigned short port) {
  int sckt = -1;
  if (host!=0) { // ------------------------------------------------- host (=client)
    sockaddr       sin;
    sin.sa_family = AF_INET;
    sin.sa_data[0] = (unsigned char)((port & 0xFF00) >> 8);
    sin.sa_data[1] = (unsigned char)(port & 0x00FF);

    sckt = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sckt<0) return sckt; // error

    int param;
    param = SOCK_ON;
    setsockopt(sckt, SOL_SOCKET, SOCKOPT_RECV_NONBLOCK, &param, sizeof(param)); // enable nonblock
    param = 5; // ms
    setsockopt(sckt, SOL_SOCKET, SOCKOPT_RECV_TIMEOUT, &param, sizeof(param)); // set a timeout

    sin.sa_data[5] = (unsigned char)((host) & 0xFF);  // First octet of destination IP
    sin.sa_data[4] = (unsigned char)((host>>8) & 0xFF);   // Second Octet of destination IP
    sin.sa_data[3] = (unsigned char)((host>>16) & 0xFF);  // Third Octet of destination IP
    sin.sa_data[2] = (unsigned char)((host>>24) & 0xFF);  // Fourth Octet of destination IP

    int res = connect(sckt,(struct sockaddr *)&sin, sizeof(sockaddr_in) );

    if (res == SOCKET_ERROR) {
     int err = errno;
     if (err != EINPROGRESS &&
         err != EWOULDBLOCK) {
       jsError("Connect failed (err %d)\n", err );
     }
    }

 } else { // ------------------------------------------------- no host (=server)
Beispiel #18
0
bool socketSendData(JsNetwork *net, JsVar *connection, int sckt, JsVar **sendData) {
    char buf[64];

    int a=1;
    if (!jsvIsEmptyString(*sendData)) {
        size_t bufLen = httpStringGet(*sendData, buf, sizeof(buf));
        a = net->send(net, sckt, buf, bufLen);
        // Now cut what we managed to send off the beginning of sendData
        if (a>0) {
            JsVar *newSendData = 0;
            if (a < (int)jsvGetStringLength(*sendData)) {
                // we didn't send all of it... cut out what we did send
                newSendData = jsvNewFromStringVar(*sendData, (size_t)a, JSVAPPENDSTRINGVAR_MAXLENGTH);
            } else {
                // we sent all of it! Issue a drain event
                jsiQueueObjectCallbacks(connection, "#ondrain", &connection, 1);
            }
            jsvUnLock(*sendData);
            *sendData = newSendData;
        }
    }
    if (a<0) { // could just be busy which is ok
        jsError("Socket error %d while sending", a);
        return false;
    }
    return true;
}
Beispiel #19
0
/// if host=0, creates a server otherwise creates a client (and automatically connects). Returns >=0 on success
int net_wiznet_createsocket(JsNetwork *net, unsigned long host, unsigned short port) {
  NOT_USED(net);
  int sckt = -1;
  if (host!=0) { // ------------------------------------------------- host (=client)

    //mgg1010 - added random source port - seems to solve problem of repeated GET failing
    
    sckt = socket(net_wiznet_getFreeSocket(), Sn_MR_TCP, (uint16_t)((rand() & 32767) + 2000), 0); // we set nonblocking later
     
    if (sckt<0) return sckt; // error

    int res = connect((uint8_t)sckt,(uint8_t*)&host, port);
    // now we set nonblocking - so that connect waited for the connection
    uint8_t ctl = SOCK_IO_NONBLOCK;
    ctlsocket((uint8_t)sckt, CS_SET_IOMODE, &ctl);

    if (res == SOCKET_ERROR) {
     jsError("Connect failed (err %d)\n", res );
    }
  } else { // ------------------------------------------------- no host (=server)
    sckt = socket(net_wiznet_getFreeSocket(), Sn_MR_TCP, port, SF_IO_NONBLOCK);
    listen((uint8_t)sckt);
  }
  wiznetSocketPorts[sckt&7] = port;
  //jsiConsolePrintf("Created socket %d\n", sckt);
  return sckt;
}
Beispiel #20
0
/*JSON{
  "type" : "method",
  "class" : "WLAN",
  "name" : "getIP",
  "generate" : "jswrap_wlan_getIP",
  "return" : ["JsVar",""]
}
Get the current IP address
*/
JsVar *jswrap_wlan_getIP(JsVar *wlanObj) {
  NOT_USED(wlanObj);

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

  JsNetwork net;
  if (!networkGetFromVar(&net)) return 0;

  tNetappIpconfigRetArgs ipconfig;
  netapp_ipconfig(&ipconfig);

  networkFree(&net);
  /* If byte 1 is 0 we don't have a valid address */
  if (ipconfig.aucIP[3] == 0) return 0;
  JsVar *data = jsvNewWithFlags(JSV_OBJECT);
  networkPutAddressAsString(data, "ip", &ipconfig.aucIP[0], -4, 10, '.');
  networkPutAddressAsString(data, "subnet", &ipconfig.aucSubnetMask[0], -4, 10, '.');
  networkPutAddressAsString(data, "gateway", &ipconfig.aucDefaultGateway[0], -4, 10, '.');
  networkPutAddressAsString(data, "dhcp", &ipconfig.aucDHCPServer[0], -4, 10, '.');
  networkPutAddressAsString(data, "dns", &ipconfig.aucDNSServer[0], -4, 10, '.');
  networkPutAddressAsString(data, "mac", &ipconfig.uaMacAddr[0], -6, 16, 0);

  return data;
}
Beispiel #21
0
JsVar *jswrap_arguments() {
  JsVar *scope = 0;
  if (execInfo.scopeCount>0)
    scope = jsvLock(execInfo.scopes[execInfo.scopeCount-1]);
  if (!jsvIsFunction(scope)) {
    jsvUnLock(scope);
    jsError("Can only use 'arguments' variable inside a function");
    return 0;
  }

  JsVar *args = jsvNewWithFlags(JSV_ARRAY);
  if (!args) return 0; // out of memory

  JsvObjectIterator it;
  jsvObjectIteratorNew(&it, scope);
  while (jsvObjectIteratorHasElement(&it)) {
    JsVar *idx = jsvObjectIteratorGetKey(&it);
    if (jsvIsFunctionParameter(idx)) {
      JsVar *val = jsvSkipOneName(idx);
      jsvArrayPushAndUnLock(args, val);
    }
    jsvUnLock(idx);
    jsvObjectIteratorNext(&it);
  }
  jsvObjectIteratorFree(&it);
  jsvUnLock(scope);

  return args;
}
Beispiel #22
0
/*JSON{ "type":"method",
         "class" : "WLAN", "name" : "setIP",
         "generate" : "jswrap_wlan_setIP",
         "description" : ["Set the current IP address for get an IP from DHCP (if no options object is specified).",
                          "**Note:** Changes are written to non-volatile memory, but will only take effect after calling `wlan.reconnect()`" ],
         "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_wlan_setIP(JsVar *wlanObj, JsVar *options) {
  NOT_USED(wlanObj);

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

  tNetappIpconfigRetArgs ipconfig;
  netapp_ipconfig(&ipconfig);

  if (jsvIsObject(options)) {
    _wlan_getIP_set_address(options, "ip", &ipconfig.aucIP[0]);
    _wlan_getIP_set_address(options, "subnet", &ipconfig.aucSubnetMask[0]);
    _wlan_getIP_set_address(options, "gateway", &ipconfig.aucDefaultGateway[0]);
    _wlan_getIP_set_address(options, "dns", &ipconfig.aucDNSServer[0]);
  } else {
    // DHCP - just set all values to 0
    *((unsigned long*)&ipconfig.aucIP[0]) = 0;
    *((unsigned long*)&ipconfig.aucSubnetMask) = 0;
    *((unsigned long*)&ipconfig.aucDefaultGateway) = 0;
  }

  return netapp_dhcp(
      (unsigned long *)&ipconfig.aucIP[0],
      (unsigned long *)&ipconfig.aucSubnetMask[0],
      (unsigned long *)&ipconfig.aucDefaultGateway[0],
      (unsigned long *)&ipconfig.aucDNSServer[0]) == 0;
}
/*JSON{
  "type" : "function",
  "name" : "show",
  "generate" : "jswrap_microbit_show",
  "params" : [
     ["image","JsVar","The image to show"]
  ]
}
Show an image on the in-built 5x5 LED screen.

Image can be:

* A number where each bit represents a pixel (so 25 bits)

*/
void jswrap_microbit_show(JsVar *image) {
  if (!jsvIsInt(image)) {
    jsError("Expecting a number, got %t\n", image);
    return;
  }
  uint32_t newState = jsvGetInteger(image);

  if ((newState!=0) && (microbitLEDState==0)) {
    // we want to display something but we don't have an interval
    jstExecuteFn(jswrap_microbit_display_callback, jshGetTimeFromMilliseconds(5));
    // and also set pins to outputs
    nrf_gpio_cfg_output(MB_LED_COL1);
    nrf_gpio_cfg_output(MB_LED_COL2);
    nrf_gpio_cfg_output(MB_LED_COL3);
    nrf_gpio_cfg_output(MB_LED_COL4);
    nrf_gpio_cfg_output(MB_LED_COL5);
    nrf_gpio_cfg_output(MB_LED_COL6);
    nrf_gpio_cfg_output(MB_LED_COL7);
    nrf_gpio_cfg_output(MB_LED_COL8);
    nrf_gpio_cfg_output(MB_LED_COL9);
    nrf_gpio_cfg_output(MB_LED_ROW1);
    nrf_gpio_cfg_output(MB_LED_ROW2);
    nrf_gpio_cfg_output(MB_LED_ROW3);
  } else  if ((newState==0) && (microbitLEDState!=0)) {
    jswrap_microbit_stopDisplay();
  }
  microbitLEDState = newState;
}
Beispiel #24
0
/** Push data into a stream. To be used by Espruino (not a user).
 * This either calls the on('data') handler if it exists, or it
 * puts the data in a buffer. This MAY CLAIM the string that is
 * passed in.
 *
 * This will return true on success, or false if the buffer is
 * full. Setting force=true will attempt to fill the buffer as
 * full as possible, and will raise an error flag if data is lost.
 */
bool jswrap_stream_pushData(JsVar *parent, JsVar *dataString, bool force) {
  assert(jsvIsObject(parent));
  assert(jsvIsString(dataString));
  bool ok = true;

  JsVar *callback = jsvFindChildFromString(parent, STREAM_CALLBACK_NAME, false);
  if (callback) {
    if (!jsiExecuteEventCallback(parent, callback, dataString, 0)) {
      jsError("Error processing Serial data handler - removing it.");
      jsErrorFlags |= JSERR_CALLBACK;
      jsvRemoveNamedChild(parent, STREAM_CALLBACK_NAME);
    }
    jsvUnLock(callback);
  } else {
    // No callback - try and add buffer
    JsVar *buf = jsvObjectGetChild(parent, STREAM_BUFFER_NAME, 0);
    if (!jsvIsString(buf)) {
      // no buffer, just set this one up
      jsvObjectSetChild(parent, STREAM_BUFFER_NAME, dataString);
    } else {
      // append (if there is room!)
      size_t bufLen = jsvGetStringLength(buf);
      size_t dataLen = jsvGetStringLength(dataString);
      if (bufLen + dataLen > STREAM_MAX_BUFFER_SIZE) {
        if (force) jsErrorFlags |= JSERR_BUFFER_FULL;
        // jsWarn("String buffer overflowed maximum size (%d)", STREAM_MAX_BUFFER_SIZE);
        ok = false;
      }
      if ((ok || force) && (bufLen < STREAM_MAX_BUFFER_SIZE))
        jsvAppendStringVar(buf, dataString, 0, STREAM_MAX_BUFFER_SIZE-bufLen);
      jsvUnLock(buf);
    }
  }
  return ok;
}
Beispiel #25
0
/**
 * Append new data to the end of the existing memory buffer.
 */
static uint8 *memoryBuffer_append(
		struct memoryBuffer *pMemoryBuffer, //!<
		uint8 *pNewData,                    //!<
		size_t length                       //!<
	) {
	assert(pMemoryBuffer != NULL);

	if (length == 0) {
		return pMemoryBuffer->buf;
	}

	assert(pNewData != NULL);

	// Handle the memory buffer being empty.
	if (pMemoryBuffer->length == 0) {
		pMemoryBuffer->buf = (uint8 *)os_malloc(length);
		if (pMemoryBuffer->buf == NULL) { // Out of memory
			jsError("malloc failed at memoryBuffer_append trying to allocate %d", length);
		} else {
			memcpy(pMemoryBuffer->buf, pNewData, length);
			pMemoryBuffer->length = length;
		}
	} else {
		// The memory buffer was not empty, so we append data.
		int newSize = pMemoryBuffer->length + length;
		uint8 *resizedStorage = (uint8 *)os_realloc(pMemoryBuffer->buf, newSize);
		if (resizedStorage != NULL) {
			pMemoryBuffer->buf = resizedStorage;
			memcpy(pMemoryBuffer->buf + length, pNewData, length);
			pMemoryBuffer->length = newSize;
		}
	}
	return pMemoryBuffer->buf;
}
Beispiel #26
0
void jshPinPulse(Pin pin, bool value, JsVarFloat time) {
  if (jshIsPinValid(pin)) {
    jshPinSetState(pin, JSHPINSTATE_GPIO_OUT);
    jshPinSetValue(pin, value);
    usleep(time*1000000);
    jshPinSetValue(pin, !value);
  } else jsError("Invalid pin!");
}
Beispiel #27
0
/*JSON{
  "type" : "staticmethod",
  "class" : "net",
  "name" : "connect",
  "generate_full" : "jswrap_net_connect(options, callback, ST_NORMAL)",
  "params" : [
    ["options","JsVar","An object containing host,port fields"],
    ["callback","JsVar","A function(res) that will be called when a connection is made. You can then call `res.on('data', function(data) { ... })` and `res.on('close', function() { ... })` to deal with the response."]
  ],
  "return" : ["JsVar","Returns a new net.Socket object"],
  "return_object" : "Socket"
}
Create a socket connection
*/
JsVar *jswrap_net_connect(JsVar *options, JsVar *callback, SocketType socketType) {
  bool unlockOptions = false;
  if (jsvIsString(options)) {
    options = jswrap_url_parse(options, false);
    unlockOptions = true;
  }
  if (!jsvIsObject(options)) {
    jsError("Expecting Options to be an Object but it was %t", options);
    return 0;
  }
#ifdef USE_TLS
  if ((socketType&ST_TYPE_MASK) == ST_HTTP) {
    JsVar *protocol = jsvObjectGetChild(options, "protocol", 0);
    if (protocol && jsvIsStringEqual(protocol, "https:")) {
      socketType |= ST_TLS;
    }
    jsvUnLock(protocol);
  }
#endif

  // Make sure we have a function as callback, or nothing (which is OK too)
  JsVar *skippedCallback = jsvSkipName(callback);
  if (!jsvIsUndefined(skippedCallback)) {
    if (!jsvIsFunction(skippedCallback)) {
      jsError("Expecting Callback Function but got %t", skippedCallback);
      jsvUnLock(skippedCallback);
      return 0;
    }
    jsvUnLock(skippedCallback);
  } else {
    callback = NULL;
  }
  JsVar *rq = clientRequestNew(socketType, options, callback);
  if (unlockOptions) jsvUnLock(options);

  if ((socketType&ST_TYPE_MASK) != ST_HTTP) {
    JsNetwork net;
    if (networkGetFromVarIfOnline(&net)) {
      clientRequestConnect(&net, rq);
    }
    networkFree(&net);
  }

  return rq;
}
Beispiel #28
0
// Connect this connection/socket
void clientRequestConnect(JsNetwork *net, JsVar *httpClientReqVar) {
    SocketType socketType = socketGetType(httpClientReqVar);
    clientRequestWrite(httpClientReqVar, 0); // force sendData to be made

    JsVar *options = jsvObjectGetChild(httpClientReqVar, HTTP_NAME_OPTIONS_VAR, false);
    unsigned short port = (unsigned short)jsvGetIntegerAndUnLock(jsvObjectGetChild(options, "port", 0));
    if (port==0) port=80;

    char hostName[128];
    JsVar *hostNameVar = jsvObjectGetChild(options, "host", 0);
    if (jsvIsUndefined(hostNameVar))
        strncpy(hostName, "localhost", sizeof(hostName));
    else
        jsvGetString(hostNameVar, hostName, sizeof(hostName));
    jsvUnLock(hostNameVar);

    uint32_t host_addr = 0;
    networkGetHostByName(net, hostName, &host_addr);

    if(!host_addr) {
        jsError("Unable to locate host");
        jsvUnLock(jsvObjectSetChild(httpClientReqVar, HTTP_NAME_CLOSENOW, jsvNewFromBool(true)));
        jsvUnLock(options);
        net->checkError(net);
        return;
    }

    int sckt =  net->createsocket(net, host_addr, port);
    if (sckt<0) {
        jsError("Unable to create socket\n");
        jsvUnLock(jsvObjectSetChild(httpClientReqVar, HTTP_NAME_CLOSENOW, jsvNewFromBool(true)));
    } else {
        jsvUnLock(jsvObjectSetChild(httpClientReqVar, HTTP_NAME_SOCKET, jsvNewFromInteger(sckt+1)));

        // For HTTP we get the connection callback when we've got a header back
        // Otherwise we just call back on success
        if (socketType != ST_HTTP) {
            jsiQueueObjectCallbacks(httpClientReqVar, HTTP_NAME_ON_CONNECT, &httpClientReqVar, 1);
        }
    }

    jsvUnLock(options);

    net->checkError(net);
}
Beispiel #29
0
IOEventFlags jshPinWatch(
		Pin pin,         //!< Unknown
		bool shouldWatch //!< Unknown
	) {
	if (jshIsPinValid(pin)) {
	} else
		jsError("Invalid pin!");
	return EV_NONE;
}
Beispiel #30
0
bool jshPinInput(Pin pin) {
  bool value = false;
  if (jshIsPinValid(pin)) {
    jshPinSetState(pin, JSHPINSTATE_GPIO_IN);

    value = jshPinGetValue(pin);
  } else jsError("Invalid pin!");
  return value;
}