Пример #1
0
void ICACHE_FLASH_ATTR
MQTTCMD_Subscribe(CmdPacket *cmd) {
  CmdRequest req;
  cmdRequest(&req, cmd);

  if (cmdGetArgc(&req) != 2) return;

  MQTT_Client* client = &mqttClient;

  uint16_t len;

  // get topic
  len = cmdArgLen(&req);
  if (len > 128) return; // safety check
  uint8_t* topic = (uint8_t*)os_zalloc(len + 1);
  cmdPopArg(&req, topic, len);
  topic[len] = 0;

  // get qos
  uint32_t qos = 0;
  cmdPopArg(&req, (uint8_t*)&qos, 4);

  DBG("MQTT: MQTTCMD_Subscribe topic=%s, qos=%u\n", topic, qos);

  MQTT_Subscribe(client, (char*)topic, (uint8_t)qos);
  os_free(topic);
  return;
}
Пример #2
0
void ICACHE_FLASH_ATTR
MQTTCMD_Setup(CmdPacket *cmd) {
  CmdRequest req;
  cmdRequest(&req, cmd);

  MQTT_Client* client = &mqttClient;

  if (cmdGetArgc(&req) != 4) return;

  // create callback
  MqttCmdCb* callback = (MqttCmdCb*)os_zalloc(sizeof(MqttCmdCb));
  cmdPopArg(&req, &callback->connectedCb, 4);
  cmdPopArg(&req, &callback->disconnectedCb, 4);
  cmdPopArg(&req, &callback->publishedCb, 4);
  cmdPopArg(&req, &callback->dataCb, 4);
  client->user_data = callback;

  DBG("MQTT connectedCb=%x\n", callback->connectedCb);

  client->cmdConnectedCb = cmdMqttConnectedCb;
  client->cmdDisconnectedCb = cmdMqttDisconnectedCb;
  client->cmdPublishedCb = cmdMqttPublishedCb;
  client->cmdDataCb = cmdMqttDataCb;

  if (client->connState == MQTT_CONNECTED) {
    if (callback->connectedCb)
      cmdMqttConnectedCb(client);
  } else if (callback->disconnectedCb) {
    cmdMqttDisconnectedCb(client);
  }
}
Пример #3
0
uint32_t ICACHE_FLASH_ATTR
MQTTCMD_Connect(CmdPacket *cmd) {
  CmdRequest req;
  cmdRequest(&req, cmd);

#ifdef MQTT_1_CLIENT

  if (mqttClient.connState == MQTT_CONNECTED && mqttClient.cmdConnectedCb) {
    mqttClient.cmdConnectedCb((uint32_t*)&mqttClient);
  }
  else if (mqttClient.connState == MQTT_DISCONNECTED && mqttClient.cmdDisconnectedCb) {
    mqttClient.cmdDisconnectedCb((uint32_t*)&mqttClient);
  }

  return 1;

#else
  if (cmdGetArgc(&req) != 4)
    return 0;

  // get mqtt client
  uint32_t client_ptr;
  cmdPopArg(&req, (uint8_t*)&client_ptr, 4);
  MQTT_Client* client = (MQTT_Client*)client_ptr;
  DBG("MQTT: MQTTCMD_Connect client ptr=%p\n", (void*)client_ptr);

  uint16_t len;

  // get host
  if (client->host)
  os_free(client->host);
  len = cmdArgLen(&req);
  if (len > 128) return 0; // safety check
  client->host = (char*)os_zalloc(len + 1);
  cmdPopArg(&req, client->host, len);
  client->host[len] = 0;

  // get port
  cmdPopArg(&req, (uint8_t*)&client->port, 4);

  // get security
  cmdPopArg(&req, (uint8_t*)&client->security, 4);
  DBG("MQTT: MQTTCMD_Connect host=%s, port=%d, security=%d\n",
    client->host,
    client->port,
    client->security);

  MQTT_Connect(client);
  return 1;
#endif
}
Пример #4
0
void ICACHE_FLASH_ATTR
MQTTCMD_Publish(CmdPacket *cmd) {
  CmdRequest req;
  cmdRequest(&req, cmd);

  if (cmdGetArgc(&req) != 5) return;

  MQTT_Client* client = &mqttClient;

  uint16_t len;

  // get topic
  len = cmdArgLen(&req);
  if (len > 128) return; // safety check
  uint8_t *topic = (uint8_t*)os_zalloc(len + 1);
  cmdPopArg(&req, topic, len);
  topic[len] = 0;

  // get data
  len = cmdArgLen(&req);
  uint8_t *data = (uint8_t*)os_zalloc(len+1);
  if (!data) { // safety check
    os_free(topic);
    return;
  }
  cmdPopArg(&req, data, len);
  data[len] = 0;

  uint16_t data_len;
  uint8_t qos, retain;

  // get data length
  cmdPopArg(&req, &data_len, sizeof(data_len));

  // get qos
  cmdPopArg(&req, &qos, sizeof(qos));

  // get retain
  cmdPopArg(&req, &retain, sizeof(retain));

  DBG("MQTT: MQTTCMD_Publish topic=%s, data_len=%d, qos=%d, retain=%d\n",
    topic, data_len, qos, retain);

  MQTT_Publish(client, (char*)topic, (char*)data, data_len, qos%3, retain&1);
  os_free(topic);
  os_free(data);
  return;
}
Пример #5
0
void ICACHE_FLASH_ATTR
REST_SetHeader(CmdPacket *cmd) {
  CmdRequest req;
  cmdRequest(&req, cmd);

  if(cmdGetArgc(&req) != 2) return;

  // Get client
  uint32_t clientNum = cmd->value;
  RestClient *client = restClient + (clientNum % MAX_REST);

  // Get header selector
  uint32_t header_index;
  if (cmdPopArg(&req, (uint8_t*)&header_index, 4)) return;

  // Get header value
  uint16_t len = cmdArgLen(&req);
  if (len > 256) return; //safety check
  switch(header_index) {
  case HEADER_GENERIC:
    if(client->header) os_free(client->header);
    client->header = (char*)os_zalloc(len + 3);
    cmdPopArg(&req, (uint8_t*)client->header, len);
    client->header[len] = '\r';
    client->header[len+1] = '\n';
    client->header[len+2] = 0;
    DBG("REST: Set header: %s\r\n", client->header);
    break;
  case HEADER_CONTENT_TYPE:
    if(client->content_type) os_free(client->content_type);
    client->content_type = (char*)os_zalloc(len + 3);
    cmdPopArg(&req, (uint8_t*)client->content_type, len);
    client->content_type[len] = '\r';
    client->content_type[len+1] = '\n';
    client->content_type[len+2] = 0;
    DBG("REST: Set content_type: %s\r\n", client->content_type);
    break;
  case HEADER_USER_AGENT:
    if(client->user_agent) os_free(client->user_agent);
    client->user_agent = (char*)os_zalloc(len + 3);
    cmdPopArg(&req, (uint8_t*)client->user_agent, len);
    client->user_agent[len] = '\r';
    client->user_agent[len+1] = '\n';
    client->user_agent[len+2] = 0;
    DBG("REST: Set user_agent: %s\r\n", client->user_agent);
    break;
  }
}
Пример #6
0
void ICACHE_FLASH_ATTR
MQTTCMD_Lwt(CmdPacket *cmd) {
  CmdRequest req;
  cmdRequest(&req, cmd);

  if (cmdGetArgc(&req) != 4) return;

  MQTT_Client* client = &mqttClient;

  // free old topic & message
  if (client->connect_info.will_topic)
    os_free(client->connect_info.will_topic);
  if (client->connect_info.will_message)
    os_free(client->connect_info.will_message);

  uint16_t len;

  // get topic
  len = cmdArgLen(&req);
  if (len > 128) return; // safety check
  client->connect_info.will_topic = (char*)os_zalloc(len + 1);
  cmdPopArg(&req, client->connect_info.will_topic, len);
  client->connect_info.will_topic[len] = 0;

  // get message
  len = cmdArgLen(&req);
  if (len > 128) return; // safety check
  client->connect_info.will_message = (char*)os_zalloc(len + 1);
  cmdPopArg(&req, client->connect_info.will_message, len);
  client->connect_info.will_message[len] = 0;

  // get qos
  cmdPopArg(&req, (uint8_t*)&client->connect_info.will_qos, 4);

  // get retain
  cmdPopArg(&req, (uint8_t*)&client->connect_info.will_retain, 4);

  DBG("MQTT: MQTTCMD_Lwt topic=%s, message=%s, qos=%d, retain=%d\n",
       client->connect_info.will_topic,
       client->connect_info.will_message,
       client->connect_info.will_qos,
       client->connect_info.will_retain);

  // trigger a reconnect to set the LWT
  MQTT_Reconnect(client);
}
Пример #7
0
uint32_t ICACHE_FLASH_ATTR
MQTTCMD_Disconnect(CmdPacket *cmd) {
  CmdRequest req;
  cmdRequest(&req, cmd);

#ifdef MQTT_1_CLIENT
  return 1;

#else
  if (cmdGetArgc(&req) != 1)
    return 0;

  // get mqtt client
  uint32_t client_ptr;
  cmdPopArg(&req, (uint8_t*)&client_ptr, 4);
  MQTT_Client* client = (MQTT_Client*)client_ptr;
  DBG("MQTT: MQTTCMD_Disconnect client ptr=%p\n", (void*)client_ptr);

  // disconnect
  MQTT_Disconnect(client);
  return 1;
#endif
}
Пример #8
0
void ICACHE_FLASH_ATTR
MQTTCMD_Setup(CmdPacket *cmd) {
  CmdRequest req;
  cmdRequest(&req, cmd);

  MQTT_Client* client = &mqttClient;

  if (cmdGetArgc(&req) != 4) return;

#if 0
// This section is commented-out because we're using the same client as esp-link is using itself,
// i.e. the one set-up in the Web UI. This code was here when we used a separate client for the
// attached uC, which just makes life more complicated...

  if (cmdGetArgc(&req) != 9)
    return 0;

  // create mqtt client
  uint8_t clientLen = sizeof(MQTT_Client);
  MQTT_Client* client = (MQTT_Client*)os_zalloc(clientLen);
  if (client == NULL) return 0;
  os_memset(client, 0, clientLen);

  uint16_t len;
  uint8_t *client_id, *user_data, *pass_data;
  uint32_t keepalive, clean_session;

  // get client id
  len = cmdArgLen(&req);
  if (len > 32) return 0; // safety check
  client_id = (uint8_t*)os_zalloc(len + 1);
  cmdPopArg(&req, client_id, len);
  client_id[len] = 0;

  // get username
  len = cmdArgLen(&req);
  if (len > 32) return 0; // safety check
  user_data = (uint8_t*)os_zalloc(len + 1);
  cmdPopArg(&req, user_data, len);
  user_data[len] = 0;

  // get password
  len = cmdArgLen(&req);
  if (len > 32) return 0; // safety check
  pass_data = (uint8_t*)os_zalloc(len + 1);
  cmdPopArg(&req, pass_data, len);
  pass_data[len] = 0;

  // get keepalive
  cmdPopArg(&req, (uint8_t*)&keepalive, 4);

  // get clean session
  cmdPopArg(&req, (uint8_t*)&clean_session, 4);
#ifdef MQTTCMD_DBG
  DBG("MQTT: MQTTCMD_Setup clientid=%s, user=%s, pw=%s, keepalive=%ld, clean_session=%ld\n", client_id, user_data, pass_data, keepalive, clean_session);
#endif

  // init client
  // TODO: why malloc these all here, pass to MQTT_InitClient to be malloc'd again?
  MQTT_InitClient(client, (char*)client_id, (char*)user_data, (char*)pass_data, keepalive, clean_session);

  os_free(client_id);
  os_free(user_data);
  os_free(pass_data);
#endif

  // create callback
  MqttCmdCb* callback = (MqttCmdCb*)os_zalloc(sizeof(MqttCmdCb));
  cmdPopArg(&req, &callback->connectedCb, 4);
  cmdPopArg(&req, &callback->disconnectedCb, 4);
  cmdPopArg(&req, &callback->publishedCb, 4);
  cmdPopArg(&req, &callback->dataCb, 4);
  client->user_data = callback;

  DBG("MQTT connectedCb=%x\n", callback->connectedCb);

  client->cmdConnectedCb = cmdMqttConnectedCb;
  client->cmdDisconnectedCb = cmdMqttDisconnectedCb;
  client->cmdPublishedCb = cmdMqttPublishedCb;
  client->cmdDataCb = cmdMqttDataCb;

  if (client->connState == MQTT_CONNECTED) {
    if (callback->connectedCb)
      cmdMqttConnectedCb(client);
  } else if (callback->disconnectedCb) {
    cmdMqttDisconnectedCb(client);
  }
}
Пример #9
0
void ICACHE_FLASH_ATTR
REST_Request(CmdPacket *cmd) {
  CmdRequest req;
  cmdRequest(&req, cmd);
  DBG("REST: request");
  if (cmd->argc != 2 && cmd->argc != 3) return;

  // Get client
  uint32_t clientNum = cmd->value;
  RestClient *client = restClient + (clientNum % MAX_REST);
  DBG(" #%ld", clientNum);

  // Get HTTP method
  uint16_t len = cmdArgLen(&req);
  if (len > 15) goto fail;
  char method[16];
  cmdPopArg(&req, method, len);
  method[len] = 0;
  DBG(" method=%s", method);

  // Get HTTP path
  len = cmdArgLen(&req);
  if (len > 1023) goto fail;
  char path[1024];
  cmdPopArg(&req, path, len);
  path[len] = 0;
  DBG(" path=%s", path);

  // Get HTTP body
  uint32_t realLen = 0;
  if (cmdGetArgc(&req) == 2) {
    realLen = 0;
  } else {
    realLen = cmdArgLen(&req);
    if (realLen > 2048) goto fail;
  }
  DBG(" bodyLen=%ld", realLen);

  // we need to allocate memory for the header plus the body. First we count the length of the
  // header (including some extra counted "%s" and then we add the body length. We allocate the
  // whole shebang and copy everything into it.
  // BTW, use http/1.0 to avoid responses with transfer-encoding: chunked
  char *headerFmt = "%s %s HTTP/1.0\r\n"
                    "Host: %s\r\n"
                    "%s"
                    "Content-Length: %d\r\n"
                    "Connection: close\r\n"
                    "Content-Type: %s\r\n"
                    "User-Agent: %s\r\n\r\n";
  uint16_t headerLen = strlen(headerFmt) + strlen(method) + strlen(path) + strlen(client->host) +
      strlen(client->header) + strlen(client->content_type) + strlen(client->user_agent);
  DBG(" hdrLen=%d", headerLen);
  if (client->data) os_free(client->data);
  client->data = (char*)os_zalloc(headerLen + realLen);
  if (client->data == NULL) goto fail;
  DBG(" totLen=%ld data=%p", headerLen + realLen, client->data);
  client->data_len = os_sprintf((char*)client->data, headerFmt, method, path, client->host,
      client->header, realLen, client->content_type, client->user_agent);
  DBG(" hdrLen=%d", client->data_len);

  if (realLen > 0) {
    cmdPopArg(&req, client->data + client->data_len, realLen);
    client->data_len += realLen;
  }
  DBG("\n");

  //DBG("REST request: %s", (char*)client->data);

  //DBG("REST: pCon state=%d\n", client->pCon->state);
  client->pCon->state = ESPCONN_NONE;
  espconn_regist_connectcb(client->pCon, tcpclient_connect_cb);
  espconn_regist_reconcb(client->pCon, tcpclient_recon_cb);

  if(UTILS_StrToIP((char *)client->host, &client->pCon->proto.tcp->remote_ip)) {
    DBG("REST: Connect to ip %s:%ld\n",client->host, client->port);
    //if(client->security){
    //  espconn_secure_connect(client->pCon);
    //}
    //else {
      espconn_connect(client->pCon);
    //}
  } else {
    DBG("REST: Connect to host %s:%ld\n", client->host, client->port);
    espconn_gethostbyname(client->pCon, (char *)client->host, &client->ip, rest_dns_found);
  }

  return;

fail:
  DBG("\n");
}
Пример #10
0
void ICACHE_FLASH_ATTR
REST_Setup(CmdPacket *cmd) {
  CmdRequest req;
  uint32_t port, security;
  int32_t err = -1; // error code in case of failure

  // start parsing the command
  cmdRequest(&req, cmd);
  if(cmdGetArgc(&req) != 3) goto fail;
  err--;

  // get the hostname
  uint16_t len = cmdArgLen(&req);
  if (len > 128) goto fail; // safety check
  err--;
  uint8_t *rest_host = (uint8_t*)os_zalloc(len + 1);
  if (cmdPopArg(&req, rest_host, len)) goto fail;
  err--;
  rest_host[len] = 0;

  // get the port
  if (cmdPopArg(&req, (uint8_t*)&port, 2)) {
    os_free(rest_host);
    goto fail;
  }
  err--;

  // get the security mode
  if (cmdPopArg(&req, (uint8_t*)&security, 1)) {
    os_free(rest_host);
    goto fail;
  }
  err--;

  // clear connection structures the first time
  if (restNum == 0xff) {
    os_memset(restClient, 0, MAX_REST * sizeof(RestClient));
    restNum = 0;
  }

  // allocate a connection structure
  RestClient *client = restClient + restNum;
  uint8_t clientNum = restNum;
  restNum = (restNum+1)%MAX_REST;

  // free any data structure that may be left from a previous connection
  if (client->header) os_free(client->header);
  if (client->content_type) os_free(client->content_type);
  if (client->user_agent) os_free(client->user_agent);
  if (client->data) os_free(client->data);
  if (client->pCon) {
    if (client->pCon->proto.tcp) os_free(client->pCon->proto.tcp);
    os_free(client->pCon);
  }
  os_memset(client, 0, sizeof(RestClient));
  DBG("REST: setup #%d host=%s port=%ld security=%ld\n", clientNum, rest_host, port, security);

  client->resp_cb = cmd->value;

  client->host = (char *)rest_host;
  client->port = port;
  client->security = security;

  client->header = (char*)os_zalloc(4);
  client->header[0] = 0;

  client->content_type = (char*)os_zalloc(22);
  os_sprintf((char *)client->content_type, "x-www-form-urlencoded");

  client->user_agent = (char*)os_zalloc(9);
  os_sprintf((char *)client->user_agent, "esp-link");

  client->pCon = (struct espconn *)os_zalloc(sizeof(struct espconn));
  client->pCon->proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp));

  client->pCon->type = ESPCONN_TCP;
  client->pCon->state = ESPCONN_NONE;
  client->pCon->proto.tcp->local_port = espconn_port();
  client->pCon->proto.tcp->remote_port = client->port;

  client->pCon->reverse = client;

  cmdResponseStart(CMD_RESP_V, clientNum, 0);
  cmdResponseEnd();
  return;

fail:
  cmdResponseStart(CMD_RESP_V, err, 0);
  cmdResponseEnd();
  return;
}