/*
 * Subscribes a mqtt client to a topic.
 */
enum v7_err MQTT_subscribe(struct v7 *v7, v7_val_t *res) {
  enum v7_err rcode = V7_OK;
  struct user_data *ud;
  struct mg_connection *nc;
  struct mg_mqtt_topic_expression expr;
  v7_val_t topicv = v7_arg(v7, 0);
  const char *topic;

  nc = v7_to_foreign(v7_get(v7, v7_get_this(v7), "_nc", ~0));
  if (nc == NULL) {
    rcode = v7_throwf(v7, "Error", "unsupported protocol");
    goto clean;
  }
  ud = (struct user_data *) nc->user_data;

  topic = v7_to_cstring(v7, &topicv);
  if (topic == NULL || strlen(topic) == 0) {
    rcode = v7_throwf(v7, "TypeError", "invalid topic");
    goto clean;
  }

  expr.topic = topic;
  expr.qos = 0;
  mg_mqtt_subscribe(nc, &expr, 1, ud->msgid++);

  *res = v7_mk_boolean(1);
clean:
  return rcode;
}
static v7_val_t WebSocket_send(struct v7 *v7, v7_val_t this_obj,
                               v7_val_t args) {
  v7_val_t datav = v7_array_get(v7, args, 0);
  v7_val_t ncv = v7_get(v7, this_obj, "_nc", ~0);
  struct mg_connection *nc;
  /*
   * TODO(alashkin): check why v7_is_instanceof throws exception
   * in case of string
   */
  int is_blob = !v7_is_string(datav) && v7_is_instanceof(v7, datav, "Blob");

  if (!v7_is_string(datav) && !is_blob) {
    v7_throw(v7, "arg should be string or Blob");
    return v7_create_undefined();
  }

  if (!v7_is_foreign(ncv) ||
      (nc = (struct mg_connection *) v7_to_foreign(ncv)) == NULL) {
    v7_throw(v7, "ws not connected");
    return v7_create_undefined();
  }

  if (is_blob) {
    _WebSocket_send_blob(v7, nc, datav);
  } else {
    _WebSocket_send_string(v7, nc, datav);
  }

  return v7_create_undefined();
}
/*
 * Publishes a message to a topic.
 *
 * Args:
 * - `topic`: topic, string.
 * - `message`: message, string.
 *
 * Only QOS 0 is implemented at the moment.
 */
enum v7_err MQTT_publish(struct v7 *v7, v7_val_t *res) {
  enum v7_err rcode = V7_OK;
  struct user_data *ud;
  struct mg_connection *nc;
  const char *topic;
  const char *message;
  size_t message_len;
  v7_val_t topicv = v7_arg(v7, 0), messagev = v7_arg(v7, 1);
  (void) res;

  topic = v7_to_cstring(v7, &topicv);
  if (topic == NULL || strlen(topic) == 0) {
    rcode = v7_throwf(v7, "TypeError", "invalid topic");
    goto clean;
  }

  if (!v7_is_string(messagev)) {
    rcode = v7_throwf(v7, "TypeError", "invalid message");
    goto clean;
  }
  message = v7_get_string_data(v7, &messagev, &message_len);

  nc = v7_to_foreign(v7_get(v7, v7_get_this(v7), "_nc", ~0));
  if (nc == NULL) {
    rcode = v7_throwf(v7, "Error", "invalid connection");
    goto clean;
  }
  ud = (struct user_data *) nc->user_data;

  mg_mqtt_publish(nc, topic, ud->msgid++, MG_MQTT_QOS(0), message, message_len);

clean:
  return rcode;
}
Exemple #4
0
/*
 * Read the content of the UART. It does not block.
 * Optional `max_len` parameter, defaults to max size_t.
 */
static enum v7_err UART_read(struct v7 *v7, v7_val_t *res) {
  v7_val_t this_obj = v7_get_this(v7);
  v7_val_t dev = v7_get(v7, this_obj, "_dev", ~0), maxv = v7_arg(v7, 0);
  size_t max = v7_is_number(maxv) ? (size_t) v7_to_number(maxv) : ~0;
  *res = sj_hal_read_uart(v7, v7_to_foreign(dev), max);

  return V7_OK;
}
static struct clubby *get_clubby(struct v7 *v7, v7_val_t obj) {
  v7_val_t clubbyv = v7_get(v7, obj, s_clubby_prop, sizeof(s_clubby_prop));
  if (!v7_is_foreign(clubbyv)) {
    return 0;
  }

  return v7_to_foreign(clubbyv);
}
static v7_val_t WebSocket_close(struct v7 *v7, v7_val_t this_obj,
                                v7_val_t args) {
  struct ns_connection *nc;
  v7_val_t ncv = v7_get(v7, this_obj, "_nc", ~0);
  (void) args;
  if (v7_is_foreign(ncv) &&
      (nc = (struct ns_connection *) v7_to_foreign(ncv)) != NULL) {
    nc->flags |= NSF_CLOSE_IMMEDIATELY;
  }
  return v7_create_undefined();
}
Exemple #7
0
static enum v7_err UART_write(struct v7 *v7, v7_val_t *res) {
  v7_val_t this_obj = v7_get_this(v7);
  v7_val_t dev = v7_get(v7, this_obj, "_dev", ~0), data = v7_arg(v7, 0);
  size_t len;
  const char *d = v7_get_string_data(v7, &data, &len);

  (void) v7;
  (void) this_obj;

  sj_hal_write_uart(v7_to_foreign(dev), d, len);

  return V7_OK;
}
Exemple #8
0
/*
 * Regiter a callback to be invoked when there is at least N bytes available.
 * N defaults to maxint if undefined
 */
static enum v7_err UART_recv(struct v7 *v7, v7_val_t *res) {
  v7_val_t this_obj = v7_get_this(v7);
  v7_val_t cb = v7_arg(v7, 0);
  v7_val_t wantv = v7_arg(v7, 1);
  v7_val_t udv = v7_get(v7, this_obj, "_ud", ~0);
  size_t want = v7_is_number(wantv) ? (size_t) v7_to_number(wantv) : ~0;

  struct user_data *ud = (struct user_data *) v7_to_foreign(udv);
  ud->cb = cb;
  v7_own(v7, &ud->cb);
  ud->want = want;
  /* TODO(mkm): trigger cb if there is already something in the buffer */

  return V7_OK;
}
static v7_val_t WebSocket_send(struct v7 *v7, v7_val_t this_obj,
                               v7_val_t args) {
  v7_val_t datav = v7_array_get(v7, args, 0);
  v7_val_t ncv = v7_get(v7, this_obj, "_nc", ~0);
  struct ns_connection *nc;
  const char *data;
  size_t len;

  if (!v7_is_string(datav)) {
    v7_throw(v7, "non string data not implemented");
    return v7_create_undefined();
  }

  if (!v7_is_foreign(ncv) ||
      (nc = (struct ns_connection *) v7_to_foreign(ncv)) == NULL) {
    v7_throw(v7, "ws not connected");
    return v7_create_undefined();
  }

  data = v7_to_string(v7, &datav, &len);
  ns_send_websocket_frame(nc, WEBSOCKET_OP_TEXT, data, len);

  return v7_create_undefined();
}
Exemple #10
0
/*
 * Returns mongoose connection saved in the user data object `obj`.
 *
 * For some details on `obj`, see `struct user_data::obj`
 */
static struct mg_connection *get_mgconn_obj(struct v7 *v7, v7_val_t obj) {
  v7_val_t _c = v7_get(v7, obj, "_c", ~0);
  return (struct mg_connection *) v7_to_foreign(_c);
}