Ejemplo n.º 1
0
SJ_PRIVATE enum v7_err GPIO_setISR(struct v7 *v7, v7_val_t *res) {
  enum v7_err rcode = V7_OK;
  v7_val_t pinv = v7_arg(v7, 0);
  v7_val_t typev = v7_arg(v7, 1);
  v7_val_t cb = v7_arg(v7, 2);
  v7_val_t current_cb;

  char prop_name[15];
  int pin, type, len, has_isr, new_isr_provided;

  if (!v7_is_number(pinv) || !v7_is_number(typev)) {
    printf("Invalid arguments\n");
    *res = v7_mk_boolean(v7, 0);
    goto clean;
  }

  pin = v7_get_double(v7, pinv);
  type = v7_get_double(v7, typev);

  len = snprintf(prop_name, sizeof(prop_name), "_ih_%d", (int) pin);
  current_cb = v7_get(v7, v7_get_global(v7), prop_name, len);
  has_isr = v7_is_callable(v7, current_cb);
  new_isr_provided = v7_is_callable(v7, cb);

  if (!has_isr && !new_isr_provided) {
    printf("Missing callback\n");
    *res = v7_mk_boolean(v7, 0);
    goto clean;
  };

  if (has_isr && new_isr_provided && current_cb != cb) {
    printf("Only one interruption handler is allowed for pin\n");
    *res = v7_mk_boolean(v7, 0);
    goto clean;
  }

  if (type == 0 && has_isr) {
    v7_set(v7, v7_get_global(v7), prop_name, len, V7_UNDEFINED);
  } else if (!has_isr && new_isr_provided) {
    v7_set(v7, v7_get_global(v7), prop_name, len, cb);
  }

  if (type != 0 && !s_gpio_intr_installed) {
    sj_gpio_intr_init(gpio_intr_handler_proxy, v7);
    s_isr_cb_proxy_v = v7_mk_cfunction(isr_cb_proxy);
    v7_own(v7, &s_isr_cb_proxy_v);
    s_gpio_intr_installed = 1;
  }
  *res =
      v7_mk_boolean(v7, sj_gpio_intr_set(pin, (enum gpio_int_mode) type) == 0);
  goto clean;

clean:
  return rcode;
}
Ejemplo n.º 2
0
/*
 * Mongoose event handler. If JavaScript callback was provided, call it
 */
static void http_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
  struct user_data *ud = (struct user_data *) c->user_data;

  if (ev == MG_EV_HTTP_REQUEST) {
    /* HTTP request has arrived */

    if (v7_is_callable(ud->v7, ud->handler)) {
      /* call provided JavaScript callback with `request` and `response` */
      v7_val_t request = v7_mk_object(ud->v7);
      v7_own(ud->v7, &request);
      v7_val_t response = v7_mk_object(ud->v7);
      v7_own(ud->v7, &response);
      setup_request_object(ud->v7, request, ev_data);
      setup_response_object(ud->v7, response, c, request);
      sj_invoke_cb2_this(ud->v7, ud->handler, ud->obj, request, response);
      v7_disown(ud->v7, &request);
      v7_disown(ud->v7, &response);
    } else {
      /*
       * no JavaScript callback provided; serve the request with the default
       * options by `mg_serve_http()`
       */
      struct mg_serve_http_opts opts;
      memset(&opts, 0, sizeof(opts));
      mg_serve_http(c, ev_data, opts);
    }
  } else if (ev == MG_EV_HTTP_REPLY) {
    /* HTTP response has arrived */

    /* if JavaScript callback was provided, call it with `response` */
    if (v7_is_callable(ud->v7, ud->handler)) {
      v7_val_t response = v7_mk_object(ud->v7);
      v7_own(ud->v7, &response);
      setup_request_object(ud->v7, response, ev_data);
      sj_invoke_cb1_this(ud->v7, ud->handler, ud->obj, response);
      v7_disown(ud->v7, &response);
    }

    if (c->flags & MG_F_CLOSE_CONNECTION_AFTER_RESPONSE) {
      c->flags |= MG_F_CLOSE_IMMEDIATELY;
    }
  } else if (ev == MG_EV_TIMER) {
    sj_invoke_cb0_this(ud->v7, ud->timeout_callback, ud->obj);
  } else if (ev == MG_EV_CLOSE) {
    if (c->listener == NULL && ud != NULL) {
      v7_set(ud->v7, ud->obj, "_c", ~0, v7_mk_undefined());
      v7_disown(ud->v7, &ud->obj);
      v7_disown(ud->v7, &ud->timeout_callback);
      free(ud);
      c->user_data = NULL;
    }
  }
}
Ejemplo n.º 3
0
SJ_PRIVATE enum v7_err Wifi_ready(struct v7 *v7, v7_val_t *res) {
  int ret = 0;
  v7_val_t cbv = v7_arg(v7, 0);

  if (!v7_is_callable(v7, cbv)) {
    LOG(LL_ERROR, ("Invalid arguments"));
    goto exit;
  }

  if (sj_wifi_get_status() == SJ_WIFI_IP_ACQUIRED) {
    sj_invoke_cb0(v7, cbv);
    ret = 1;
  } else {
    struct wifi_cb_arg *arg = (struct wifi_cb_arg *) calloc(1, sizeof(*arg));
    if (arg != NULL) {
      arg->v7 = v7;
      arg->v = cbv;
      v7_own(v7, &arg->v);
      sj_wifi_add_on_change_cb(sj_wifi_ready_js, arg);
    } else {
      ret = 0;
    }
  }

exit:
  *res = v7_mk_boolean(v7, ret);
  return V7_OK;
}
Ejemplo n.º 4
0
static enum v7_err jsSetTimeout(struct v7* v7, v7_val_t* res) {
	v7_val_t* func = new v7_val_t;
	v7_own(v7, func);
	*func = v7_arg(v7, 0);
	v7_val_t inv = v7_arg(v7, 1);

	if (!v7_is_callable(v7, *func)) {
		//TODO: catch error if 1st argument not callable code
		return V7_OK;
	}

	if (!v7_is_number(inv)) {
		//TODO: catch error if 2nd argument not a number
		return V7_OK;
	}

	double ms = v7_to_number(inv);
	long lms = floor(ms);

	//v7_apply(v7, func, _activeBot->getV7Obj(), v7_mk_undefined(), NULL);

	TIMER* newTimer = new TIMER;
	newTimer->pToFunc = func;
	newTimer->delay = lms;
	newTimer->timeBegin = GetTickCount();
	newTimer->id = (long)newTimer;

	_activeBot->_timers.Add(newTimer);

	double vOut = (double)newTimer->id;

	*res = v7_mk_number(vOut);

	return V7_OK;
}
Ejemplo n.º 5
0
void esp_sj_uart_dispatcher(void *arg) {
  int uart_no = (int) arg;
  struct esp_sj_uart_state *us = &sj_us[uart_no];
  cs_rbuf_t *txb = esp_uart_tx_buf(uart_no);
  us->dispatch_pending = 0;
  esp_uart_dispatch_rx_top(uart_no);
  uint16_t tx_used_before = txb->used;

  /* ignore unused because of CS_DISABLE_JS below */
  (void) tx_used_before;

  esp_uart_dispatch_tx_top(uart_no);
#ifndef CS_DISABLE_JS
  cs_rbuf_t *rxb = esp_uart_rx_buf(uart_no);

  if (us->v7 != NULL) {
    /* Detect the edge of TX buffer becoming empty. */
    if (tx_used_before > 0 && txb->used == 0) {
      v7_val_t txcb = v7_get(us->v7, us->obj, "_txcb", 5);
      if (v7_is_callable(us->v7, txcb)) {
        sj_invoke_cb(us->v7, txcb, us->obj, V7_UNDEFINED);
      }
    }
    if (rxb->used > 0) {
      /* Check for JS recv handler. */
      v7_val_t rxcb = esp_sj_uart_get_recv_handler(uart_no);
      if (v7_is_callable(us->v7, rxcb)) {
        if (!us->recv_pending) {
          us->recv_pending = 1;
          sj_invoke_cb(us->v7, rxcb, us->obj, V7_UNDEFINED);
          /* Note: Callback has not run yet, it has been scheduled. */
        }
      } else if (us->prompt) {
        uint8_t *cp;
        while (rxb != NULL && cs_rbuf_get(rxb, 1, &cp) == 1) {
          char c = (char) *cp;
          cs_rbuf_consume(rxb, 1);
          sj_prompt_process_char(c);
          /* UART could've been re-initialized by the command from prompt. */
          rxb = esp_uart_rx_buf(uart_no);
        }
      }
    }
  }
#endif
  esp_uart_dispatch_bottom(uart_no);
}
Ejemplo n.º 6
0
static enum v7_err UART_onTXEmpty(struct v7 *v7, v7_val_t *res) {
  struct esp_sj_uart_state *us;
  enum v7_err ret = esp_sj_uart_get_state(v7, &us);
  if (ret != V7_OK) return ret;
  v7_set(v7, us->obj, "_txcb", 5, v7_arg(v7, 0));
  if (v7_is_callable(v7, v7_arg(v7, 0))) {
    esp_sj_uart_schedule_dispatcher(us->uart_no);
  }
  *res = v7_mk_undefined();
  return V7_OK;
}
Ejemplo n.º 7
0
/* Args: callable, disable_rx */
static enum v7_err UART_onRecv(struct v7 *v7, v7_val_t *res) {
  struct esp_sj_uart_state *us;
  enum v7_err ret = esp_sj_uart_get_state(v7, &us);
  if (ret != V7_OK) return ret;
  v7_set(v7, us->obj, "_rxcb", 5, v7_arg(v7, 0));
  esp_uart_set_rx_enabled(us->uart_no, !v7_is_truthy(v7, v7_arg(v7, 1)));
  if (v7_is_callable(v7, v7_arg(v7, 0))) {
    esp_sj_uart_schedule_dispatcher(us->uart_no);
  }
  *res = V7_UNDEFINED;
  return V7_OK;
}
Ejemplo n.º 8
0
static enum v7_err Updater_notify(struct v7 *v7, v7_val_t *res) {
  v7_val_t cb = v7_arg(v7, 0);
  if (!v7_is_callable(v7, cb)) {
    printf("Invalid arguments\n");
    *res = v7_mk_boolean(v7, 0);
    return V7_OK;
  }

  s_updater_notify_cb = cb;

  *res = v7_mk_boolean(v7, 1);
  return V7_OK;
}
Ejemplo n.º 9
0
SJ_PRIVATE enum v7_err Http_createServer(struct v7 *v7, v7_val_t *res) {
  enum v7_err rcode = V7_OK;
  v7_val_t cb = v7_arg(v7, 0);

  if (!v7_is_callable(v7, cb)) {
    rcode = v7_throwf(v7, "Error", "Invalid argument");
    goto clean;
  }
  *res = v7_mk_object(v7);
  v7_set_proto(v7, *res, sj_http_server_proto);
  v7_set(v7, *res, "_cb", ~0, cb);

clean:
  return rcode;
}
Ejemplo n.º 10
0
SJ_PRIVATE enum v7_err Wifi_changed(struct v7 *v7, v7_val_t *res) {
  enum v7_err rcode = V7_OK;
  v7_val_t cb = v7_arg(v7, 0);
  if (!v7_is_callable(v7, cb) && !v7_is_null(cb)) {
    *res = v7_mk_boolean(v7, 0);
    goto clean;
  }
  v7_disown(s_wifi_changed_cb.v7, &s_wifi_changed_cb.v);
  s_wifi_changed_cb.v7 = v7;
  s_wifi_changed_cb.v = cb;
  v7_own(s_wifi_changed_cb.v7, &s_wifi_changed_cb.v);
  *res = v7_mk_boolean(v7, 1);
  goto clean;

clean:
  return rcode;
}
Ejemplo n.º 11
0
SJ_PRIVATE enum v7_err sj_set_interval_or_timeout(struct v7 *v7, v7_val_t *res,
                                                  int repeat) {
  v7_val_t msecsv = v7_arg(v7, 1);
  int msecs;
  (void) res;

  if (!v7_is_callable(v7, v7_arg(v7, 0))) {
    printf("cb is not a function\n");
  } else if (!v7_is_number(msecsv)) {
    printf("msecs is not a number\n");
  } else {
    v7_val_t cb = v7_arg(v7, 0);
    msecs = v7_get_double(v7, msecsv);
    *res = v7_mk_number(v7, sj_set_js_timer(msecs, repeat, v7, cb));
  }

  return V7_OK;
}
Ejemplo n.º 12
0
static void gpio_intr_handler_proxy(int pin, enum gpio_level level, void *arg) {
  struct v7 *v7 = (struct v7 *) arg;
  char prop_name[15];
  int len;

  len = snprintf(prop_name, sizeof(prop_name), "_ih_%d", (int) pin);

  v7_val_t cb = v7_get(v7, v7_get_global(v7), prop_name, len);

  if (!v7_is_callable(v7, cb)) {
    return;
  }

  /* Forwarding call to common cbs queue */
  v7_val_t args = v7_mk_array(v7);
  v7_array_push(v7, args, v7_mk_number(v7, pin));
  v7_array_push(v7, args, v7_mk_number(v7, level));
  sj_invoke_cb2(v7, s_isr_cb_proxy_v, cb, args);
}
Ejemplo n.º 13
0
/* Call the callback with a list of ssids found in the air. */
SJ_PRIVATE enum v7_err Wifi_scan(struct v7 *v7, v7_val_t *res) {
  v7_val_t cb;

  if (s_wifi_scan_cb.v7 != NULL) {
    return v7_throwf(v7, "Error", "scan in progress");
  }

  cb = v7_arg(v7, 0);
  if (!v7_is_callable(v7, cb)) {
    return v7_throwf(v7, "Error", "Invalid argument");
  }

  s_wifi_scan_cb.v7 = v7;
  s_wifi_scan_cb.v = cb;
  v7_own(v7, &s_wifi_scan_cb.v);

  sj_wifi_scan(sj_wifi_scan_done, &s_wifi_scan_cb);

  (void) res;
  return V7_OK;
}
Ejemplo n.º 14
0
/* Currently can only handle one timer */
static enum v7_err global_set_timeout(struct v7 *v7, v7_val_t *res) {
  v7_val_t *cb;
  v7_val_t msecsv = v7_arg(v7, 1);
  int msecs;
  (void) res;

  cb = (v7_val_t *) malloc(sizeof(*cb));
  v7_own(v7, cb);
  *cb = v7_arg(v7, 0);

  if (!v7_is_callable(v7, *cb)) {
    printf("cb is not a function\n");
  } else if (!v7_is_number(msecsv)) {
    printf("msecs is not a double\n");
  } else {
    msecs = v7_to_number(msecsv);

    sj_set_timeout(msecs, cb);
  }

  return V7_OK;
}
Ejemplo n.º 15
0
static void gpio_intr_handler_proxy(int pin, int level) {
  char prop_name[15];
  int len;
  v7_val_t res, args;

  len = snprintf(prop_name, sizeof(prop_name), "_ih_%d", (int) pin);

  v7_val_t cb = v7_get(s_v7, v7_get_global(s_v7), prop_name, len);

  if (!v7_is_callable(s_v7, cb)) {
    return;
  }

  args = v7_mk_array(s_v7);
  v7_array_push(s_v7, args, v7_mk_number(pin));
  v7_array_push(s_v7, args, v7_mk_number(level));

  if (v7_apply(s_v7, cb, v7_mk_undefined(), args, &res) != V7_OK) {
    /* TODO(mkm): make it print stack trace */
    fprintf(stderr, "cb threw an exception\n");
  }
}
Ejemplo n.º 16
0
static enum v7_err jsBotEvent(struct v7* v7, v7_val_t* res) {
	v7_val_t val = v7_arg(v7, 0);
	TString strEvent = (const char*)v7_to_cstring(v7, &val);
	v7_val_t* func = new v7_val_t;
	v7_own(v7, func);
	*func = v7_arg(v7, 1);
	
	//if not a function type in 2nd argument
	if (!v7_is_callable(v7, *func)) {
		//TODO: throw error
		return V7_OK;
	}
	else {

	}

	if (strEvent.IsEQNC(L"text")) {
		_activeBot->_onTexts.Add(func);
	}
	else if (strEvent.IsEQNC(L"join")) {
		_activeBot->_onJoin.Add(func);
	}
	else if (strEvent.IsEQNC(L"left")) {
		_activeBot->_onLeft.Add(func);
	}
	else if (strEvent.IsEQNC(L"talk")) {
		_activeBot->_onTalk.Add(func);
	}
	else if (strEvent.IsEQNC(L"motd")) {
		_activeBot->_onMotd.Add(func);
	}
	else if (strEvent.IsEQNC(L"im")) {
		_activeBot->_onIm.Add(func);
	}
	return V7_OK;
}
Ejemplo n.º 17
0
void sj_wifi_on_change_js(enum sj_wifi_status event, void *arg) {
  struct wifi_cb_arg *cba = (struct wifi_cb_arg *) arg;
  if (v7_is_callable(cba->v7, cba->v)) {
    sj_invoke_cb1(cba->v7, cba->v, v7_mk_number(cba->v7, event));
  }
}