コード例 #1
0
ファイル: mqtt.c プロジェクト: pvvx/EspLua
// Lua: mqtt:close()
// client disconnect and unref itself
static int mqtt_socket_close( lua_State* L )
{
  NODE_DBG("enter mqtt_socket_close.\n");
  int i = 0;
  lmqtt_userdata *mud = NULL;

  mud = (lmqtt_userdata *)luaL_checkudata(L, 1, "mqtt.socket");
  luaL_argcheck(L, mud, 1, "mqtt.socket expected");
  if(mud == NULL)
    return 0;

  if(mud->pesp_conn == NULL)
    return 0;

  // call mqtt_disconnect()
  mud->mqtt_state.auto_reconnect = 0;   // stop auto reconnect.

  if(mud->secure){
    if(mud->pesp_conn->proto.tcp->remote_port || mud->pesp_conn->proto.tcp->local_port)
      espconn_secure_disconnect(mud->pesp_conn);
  }
  else
  {
    if(mud->pesp_conn->proto.tcp->remote_port || mud->pesp_conn->proto.tcp->local_port)
      espconn_disconnect(mud->pesp_conn);
  }
  NODE_DBG("leave mqtt_socket_close.\n");
  return 0;  
}
コード例 #2
0
static void ICACHE_FLASH_ATTR receive_callback(void * arg, char * buf, unsigned short len)
{
	struct espconn * conn = (struct espconn *)arg;
	request_args * req = (request_args *)conn->reverse;

	if (req->buffer == NULL) {
		return;
	}

	// Let's do the equivalent of a realloc().
	const int new_size = req->buffer_size + len;
	char * new_buffer;
	if (new_size > BUFFER_SIZE_MAX || NULL == (new_buffer = (char *)os_malloc(new_size))) {
		os_printf("Response too long (%d)\n", new_size);
		req->buffer[0] = '\0'; // Discard the buffer to avoid using an incomplete response.
		if (req->secure)
			espconn_secure_disconnect(conn);
		else
			espconn_disconnect(conn);			
		return; // The disconnect callback will be called.
	}

	os_memcpy(new_buffer, req->buffer, req->buffer_size);
	os_memcpy(new_buffer + req->buffer_size - 1 /*overwrite the null character*/, buf, len); // Append new data.
	new_buffer[new_size - 1] = '\0'; // Make sure there is an end of string.

	os_free(req->buffer);
	req->buffer = new_buffer;
	req->buffer_size = new_size;
}
コード例 #3
0
/******************************************************************************
 * FunctionName : user_upgrade_check
 * Description  : Processing the received data from the server
 * Parameters   : arg -- Additional argument to pass to the callback function
 *                pusrdata -- The received data (or NULL when the connection has been closed!)
 *                length -- The length of received data
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
upgrade_check(struct upgrade_server_info *server)
{
	UPGRADE_DBG("upgrade_check\n");

    if (system_upgrade_flag_check() != UPGRADE_FLAG_FINISH) {
    	totallength = 0;
    	sumlength = 0;
        os_timer_disarm(&upgrade_timer);
        system_upgrade_flag_set(UPGRADE_FLAG_IDLE);
        upgrade_deinit();
        server->upgrade_flag = false;

        if (server->check_cb != NULL) {
            server->check_cb(server);
        }
    } else {
        os_timer_disarm(&upgrade_timer);
        upgrade_deinit();
        server->upgrade_flag = true;

        if (server->check_cb != NULL) {
            server->check_cb(server);
        }
    }
#ifdef UPGRADE_SSL_ENABLE
    espconn_secure_disconnect(upgrade_conn);
#else
    espconn_disconnect(upgrade_conn);

#endif
}
コード例 #4
0
void ICACHE_FLASH_ATTR net_asyncDisconnect(NetConnection* conn)
{
    uart0_tx_buffer("disconnect\r\n", 12);
    HTTPESP8266ConnectionData* driver = esp8266_getConnection(conn);
    //esp8266_destroyConnection(conn);
    //conn->disconnectCallback(conn->userData, net_ok);
    if(driver->secure)
        espconn_secure_disconnect(&driver->connection);
    else
        espconn_disconnect(&driver->connection);
}
コード例 #5
0
ファイル: fota-info.c プロジェクト: eprzenic/esp8266-dev
/**
  * @brief  after sending (version) request, wait for reply timeout
  *         we do not received right answer, close connection
  * @param  arg: contain the ip link information
  * @retval None
  */
LOCAL void ICACHE_FLASH_ATTR
get_version_timeout(void *arg)
{
  struct espconn *pespconn = arg;
  fota_client_t *fota_client = (fota_client_t *)pespconn->reverse;
  os_timer_disarm(&fota_client->request_timeout);

  INFO("FOTA Client: Request timeout, close connection\n");
  if (FOTA_SECURE)
    espconn_secure_disconnect(pespconn);
  else
    espconn_disconnect(pespconn);
}
コード例 #6
0
ファイル: tls.c プロジェクト: FelixPe/nodemcu-firmware
static int tls_socket_close( lua_State *L ) {
  tls_socket_ud *ud = (tls_socket_ud *)luaL_checkudata(L, 1, "tls.socket");
  luaL_argcheck(L, ud, 1, "TLS socket expected");
  if(ud==NULL){
  	NODE_DBG("userdata is nil.\n");
  	return 0;
  }

  if (ud->pesp_conn) {
    espconn_secure_disconnect(ud->pesp_conn);
  }

  return 0;
}
コード例 #7
0
ファイル: tls.c プロジェクト: FelixPe/nodemcu-firmware
static void tls_socket_cleanup(tls_socket_ud *ud) {
  if (ud->pesp_conn) {
    espconn_secure_disconnect(ud->pesp_conn);
    if (ud->pesp_conn->proto.tcp) {
      c_free(ud->pesp_conn->proto.tcp);
      ud->pesp_conn->proto.tcp = NULL;
    }
    c_free(ud->pesp_conn);
    ud->pesp_conn = NULL;
  }
  lua_State *L = lua_getstate();
  lua_gc(L, LUA_GCSTOP, 0);
  luaL_unref(L, LUA_REGISTRYINDEX, ud->self_ref);
  ud->self_ref = LUA_NOREF;
  lua_gc(L, LUA_GCRESTART, 0);
}
コード例 #8
0
ファイル: mqtt.c プロジェクト: Drummondh/esp-link
static void ICACHE_FLASH_ATTR
mqtt_doAbort(MQTT_Client* client) {
  os_printf("MQTT: Disconnecting from %s:%d (%p)\n", client->host, client->port, client->pCon);
  client->pCon->reverse = NULL; // ensure we jettison this pCon...
  if (client->security)
    espconn_secure_disconnect(client->pCon);
  else
    espconn_disconnect(client->pCon);

  if (client->disconnectedCb) client->disconnectedCb((uint32_t*)client);
  if (client->cmdDisconnectedCb) client->cmdDisconnectedCb((uint32_t*)client);

  if (client->sending_buffer != NULL) {
    os_free(client->sending_buffer);
    client->sending_buffer = NULL;
  }
  client->pCon = NULL;         // it will be freed in disconnect callback
  client->connState = TCP_RECONNECT_REQ;
  client->timeoutTick = client->reconTimeout;     // reconnect in a few seconds
  if (client->reconTimeout < 128) client->reconTimeout <<= 1;
}
コード例 #9
0
ファイル: fota-info.c プロジェクト: eprzenic/esp8266-dev
void ICACHE_FLASH_ATTR
get_version_recon_cb(void *arg, sint8 err)
{
  //error occured , tcp connection broke. user can try to reconnect here.
  INFO("FOTA Client: reconnect callback, code %d\n", err);
  struct espconn *pespconn = arg;
  fota_client_t *fota_client = (fota_client_t *)pespconn->reverse;

  if (fota_client->status != FOTA_GETTING_FIRMWARE)
    fota_client->status = FOTA_IDLE;

  INFO("State of esp conn: %d\n", pespconn->state);
  if (FOTA_SECURE)
    espconn_secure_disconnect((struct espconn *)arg);
  else
    espconn_disconnect((struct espconn *)arg);

  // when host failed to connect, disconnect will not work,
  // need to clean connection to avoid mem leak
  clear_espconn(pespconn);
}
コード例 #10
0
ファイル: tls.c プロジェクト: FelixPe/nodemcu-firmware
static int tls_socket_delete( lua_State *L ) {
  tls_socket_ud *ud = (tls_socket_ud *)luaL_checkudata(L, 1, "tls.socket");
  luaL_argcheck(L, ud, 1, "TLS socket expected");
  if(ud==NULL){
  	NODE_DBG("userdata is nil.\n");
  	return 0;
  }
  if (ud->pesp_conn) {
    espconn_secure_disconnect(ud->pesp_conn);
    if (ud->pesp_conn->proto.tcp) {
      c_free(ud->pesp_conn->proto.tcp);
      ud->pesp_conn->proto.tcp = NULL;
    }
    c_free(ud->pesp_conn);
    ud->pesp_conn = NULL;
  }

  luaL_unref(L, LUA_REGISTRYINDEX, ud->cb_connect_ref);
  ud->cb_connect_ref = LUA_NOREF;
  luaL_unref(L, LUA_REGISTRYINDEX, ud->cb_disconnect_ref);
  ud->cb_disconnect_ref = LUA_NOREF;
  luaL_unref(L, LUA_REGISTRYINDEX, ud->cb_reconnect_ref);
  ud->cb_reconnect_ref = LUA_NOREF;
  luaL_unref(L, LUA_REGISTRYINDEX, ud->cb_dns_ref);
  ud->cb_dns_ref = LUA_NOREF;
  luaL_unref(L, LUA_REGISTRYINDEX, ud->cb_receive_ref);
  ud->cb_receive_ref = LUA_NOREF;
  luaL_unref(L, LUA_REGISTRYINDEX, ud->cb_sent_ref);
  ud->cb_sent_ref = LUA_NOREF;

  lua_gc(L, LUA_GCSTOP, 0);
  luaL_unref(L, LUA_REGISTRYINDEX, ud->self_ref);
  ud->self_ref = LUA_NOREF;
  lua_gc(L, LUA_GCRESTART, 0);

  return 0;
}
コード例 #11
0
/**
  * @brief  Client received callback function.
  * @param  arg: contain the ip link information
  * @param  pdata: received data
  * @param  len: the lenght of received data
  * @retval None
  */
void ICACHE_FLASH_ATTR
mqtt_tcpclient_recv(void *arg, char *pdata, unsigned short len)
{
	uint8_t msg_type;
	uint8_t msg_qos;
	uint16_t msg_id;

	struct espconn *pCon = (struct espconn*)arg;
	MQTT_Client *client = (MQTT_Client *)pCon->reverse;

READPACKET:
	INFO("TCP: data received %d bytes\r\n", len);
	if(len < MQTT_BUF_SIZE && len > 0){
		os_memcpy(client->mqtt_state.in_buffer, pdata, len);

		msg_type = mqtt_get_type(client->mqtt_state.in_buffer);
		msg_qos = mqtt_get_qos(client->mqtt_state.in_buffer);
		msg_id = mqtt_get_id(client->mqtt_state.in_buffer, client->mqtt_state.in_buffer_length);
		switch(client->connState){
		case MQTT_CONNECT_SENDING:
			if(msg_type == MQTT_MSG_TYPE_CONNACK){
				if(client->mqtt_state.pending_msg_type != MQTT_MSG_TYPE_CONNECT){
					INFO("MQTT: Invalid packet\r\n");
					if(client->security){
						espconn_secure_disconnect(client->pCon);
					}
					else {
						espconn_disconnect(client->pCon);
					}
				} else {
					INFO("MQTT: Connected to %s:%d\r\n", client->host, client->port);
					client->connState = MQTT_DATA;
					if(client->connectedCb)
						client->connectedCb((uint32_t*)client);
				}

			}
			break;
		case MQTT_DATA:
			client->mqtt_state.message_length_read = len;
			client->mqtt_state.message_length = mqtt_get_total_length(client->mqtt_state.in_buffer, client->mqtt_state.message_length_read);


			switch(msg_type)
			{

			  case MQTT_MSG_TYPE_SUBACK:
				if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_SUBSCRIBE && client->mqtt_state.pending_msg_id == msg_id)
				  INFO("MQTT: Subscribe successful\r\n");
				break;
			  case MQTT_MSG_TYPE_UNSUBACK:
				if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_UNSUBSCRIBE && client->mqtt_state.pending_msg_id == msg_id)
				  INFO("MQTT: UnSubscribe successful\r\n");
				break;
			  case MQTT_MSG_TYPE_PUBLISH:
				if(msg_qos == 1)
					client->mqtt_state.outbound_message = mqtt_msg_puback(&client->mqtt_state.mqtt_connection, msg_id);
				else if(msg_qos == 2)
					client->mqtt_state.outbound_message = mqtt_msg_pubrec(&client->mqtt_state.mqtt_connection, msg_id);
				if(msg_qos == 1 || msg_qos == 2){
					INFO("MQTT: Queue response QoS: %d\r\n", msg_qos);
					if(QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1){
						INFO("MQTT: Queue full\r\n");
					}
				}

				deliver_publish(client, client->mqtt_state.in_buffer, client->mqtt_state.message_length_read);
				break;
			  case MQTT_MSG_TYPE_PUBACK:
				if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && client->mqtt_state.pending_msg_id == msg_id){
				  INFO("MQTT: received MQTT_MSG_TYPE_PUBACK, finish QoS1 publish\r\n");
				}

				break;
			  case MQTT_MSG_TYPE_PUBREC:
				  client->mqtt_state.outbound_message = mqtt_msg_pubrel(&client->mqtt_state.mqtt_connection, msg_id);
				  if(QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1){
				  	INFO("MQTT: Queue full\r\n");
				  }
				break;
			  case MQTT_MSG_TYPE_PUBREL:
				  client->mqtt_state.outbound_message = mqtt_msg_pubcomp(&client->mqtt_state.mqtt_connection, msg_id);
				  if(QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1){
					INFO("MQTT: Queue full\r\n");
				  }
				break;
			  case MQTT_MSG_TYPE_PUBCOMP:
				if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && client->mqtt_state.pending_msg_id == msg_id){
				  INFO("MQTT: receive MQTT_MSG_TYPE_PUBCOMP, finish QoS2 publish\r\n");
				}
				break;
			  case MQTT_MSG_TYPE_PINGREQ:
				  client->mqtt_state.outbound_message = mqtt_msg_pingresp(&client->mqtt_state.mqtt_connection);
				  if(QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1){
					INFO("MQTT: Queue full\r\n");
				  }
				break;
			  case MQTT_MSG_TYPE_PINGRESP:
				// Ignore
				break;
			}
			// NOTE: this is done down here and not in the switch case above
			// because the PSOCK_READBUF_LEN() won't work inside a switch
			// statement due to the way protothreads resume.
			if(msg_type == MQTT_MSG_TYPE_PUBLISH)
			{
			  len = client->mqtt_state.message_length_read;

			  if(client->mqtt_state.message_length < client->mqtt_state.message_length_read)
			  {
				  //client->connState = MQTT_PUBLISH_RECV;
				  //Not Implement yet
				  len -= client->mqtt_state.message_length;
				  pdata += client->mqtt_state.message_length;

				  INFO("Get another published message\r\n");
				  goto READPACKET;
			  }

			}
			break;
		}
	} else {
		INFO("ERROR: Message too long\r\n");
	}
	system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client);
}
コード例 #12
0
ファイル: mqtt.c プロジェクト: kanflo/esp8266-ghost
/**
  * @brief  Client received callback function.
  * @param  arg: contain the ip link information
  * @param  pdata: received data
  * @param  len: the lenght of received data
  * @retval None
  */
void ICACHE_FLASH_ATTR
mqtt_tcpclient_recv(void *arg, char *pdata, unsigned short len)
{
	uint8_t msg_type;
	uint8_t msg_qos;

	uint16_t msg_id;

	struct espconn *pCon = (struct espconn*)arg;
	MQTT_Client *client = (MQTT_Client *)pCon->reverse;

//spam 	INFO("TCP: data received\r\n");
	if(len < MQTT_BUF_SIZE && len > 0){
		memcpy(client->mqtt_state.in_buffer, pdata, len);

		switch(client->connState){
		case MQTT_CONNECT_SENDING:
			if(mqtt_get_type(client->mqtt_state.in_buffer) != MQTT_MSG_TYPE_CONNACK){
//spam 				INFO("MQTT: Invalid packet\r\n");
				if(client->security){
					espconn_secure_disconnect(client->pCon);
				}
				else {
					espconn_disconnect(client->pCon);
				}

			} else {
//spam 				INFO("MQTT: Connected to %s:%d\r\n", client->host, client->port);
				client->connState = MQTT_DATA;
				if(client->connectedCb)
					client->connectedCb((uint32_t*)client);
			}
			break;

		case MQTT_DATA:
			client->mqtt_state.message_length_read = len;
			client->mqtt_state.message_length = mqtt_get_total_length(client->mqtt_state.in_buffer, client->mqtt_state.message_length_read);
			msg_type = mqtt_get_type(client->mqtt_state.in_buffer);
			msg_qos = mqtt_get_qos(client->mqtt_state.in_buffer);
			msg_id = mqtt_get_id(client->mqtt_state.in_buffer, client->mqtt_state.in_buffer_length);
			switch(msg_type)
			{
			  case MQTT_MSG_TYPE_SUBACK:
//spam				if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_SUBSCRIBE && client->mqtt_state.pending_msg_id == msg_id)
//spam 				  INFO("MQTT: Subscribe successful to %s:%d\r\n", client->host, client->port);
				break;
			  case MQTT_MSG_TYPE_UNSUBACK:
//spam				if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_UNSUBSCRIBE && client->mqtt_state.pending_msg_id == msg_id)
//spam 				  INFO("MQTT: UnSubscribe successful\r\n");
				break;
			  case MQTT_MSG_TYPE_PUBLISH:
				if(msg_qos == 1)
					client->mqtt_state.outbound_message = mqtt_msg_puback(&client->mqtt_state.mqtt_connection, msg_id);
				else if(msg_qos == 2)
					client->mqtt_state.outbound_message = mqtt_msg_pubrec(&client->mqtt_state.mqtt_connection, msg_id);

				deliver_publish(client, client->mqtt_state.in_buffer, client->mqtt_state.message_length_read);
				break;
			  case MQTT_MSG_TYPE_PUBACK:
				if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && client->mqtt_state.pending_msg_id == msg_id){
//spam				  INFO("MQTT: Publish successful\r\n");
				  if(client->publishedCb)
					  client->publishedCb((uint32_t*)client);
				}

				break;
			  case MQTT_MSG_TYPE_PUBREC:
				  client->mqtt_state.outbound_message = mqtt_msg_pubrel(&client->mqtt_state.mqtt_connection, msg_id);
				break;
			  case MQTT_MSG_TYPE_PUBREL:
				  client->mqtt_state.outbound_message = mqtt_msg_pubcomp(&client->mqtt_state.mqtt_connection, msg_id);
				break;
			  case MQTT_MSG_TYPE_PUBCOMP:
				if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && client->mqtt_state.pending_msg_id == msg_id){
//spam				  INFO("MQTT: Public successful\r\n");
				  if(client->publishedCb)
					  client->publishedCb((uint32_t*)client);
				}
				break;
			  case MQTT_MSG_TYPE_PINGREQ:
				  client->mqtt_state.outbound_message = mqtt_msg_pingresp(&client->mqtt_state.mqtt_connection);
				break;
			  case MQTT_MSG_TYPE_PINGRESP:
				// Ignore
				break;
			}
			// NOTE: this is done down here and not in the switch case above
			// because the PSOCK_READBUF_LEN() won't work inside a switch
			// statement due to the way protothreads resume.
			if(msg_type == MQTT_MSG_TYPE_PUBLISH)
			{
			  uint16_t len;

			  // adjust message_length and message_length_read so that
			  // they only account for the publish data and not the rest of the
			  // message, this is done so that the offset passed with the
			  // continuation event is the offset within the publish data and
			  // not the offset within the message as a whole.
			  len = client->mqtt_state.message_length_read;
			  mqtt_get_publish_data(client->mqtt_state.in_buffer, &len);
			  len = client->mqtt_state.message_length_read - len;
			  client->mqtt_state.message_length -= len;
			  client->mqtt_state.message_length_read -= len;

			  if(client->mqtt_state.message_length_read < client->mqtt_state.message_length)
			  {
				  //client->connState = MQTT_PUBLISH_RECV;
			  }

			}
			break;
			case MQTT_PUBLISH_RECV:
				/*
				 * Long publish message, not implement yet
				 * TODO: Implement method used deliver_publish_continuation
				 */
				break;
		}
	}
	system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client);
}
コード例 #13
0
ファイル: mqtt.c プロジェクト: hehao3344/mkit
void ICACHE_FLASH_ATTR
MQTT_Task(os_event_t *e)
{
    MQTT_Client* client = (MQTT_Client*)e->par;
    uint8_t dataBuffer[MQTT_BUF_SIZE];
    uint16_t dataLen;
    if (e->par == 0)
        return;
    switch (client->connState) {

    case TCP_RECONNECT_REQ:
        break;
    case TCP_RECONNECT:
        mqtt_tcpclient_delete(client);
        MQTT_Connect(client);
        INFO("TCP: Reconnect to: %s:%d\r\n", client->host, client->port);
        client->connState = TCP_CONNECTING;
        break;
    case MQTT_DELETING:
    case TCP_DISCONNECTING:
    case TCP_RECONNECT_DISCONNECTING:
        if (client->security) {
#ifdef MQTT_SSL_ENABLE
            espconn_secure_disconnect(client->pCon);
#else
            INFO("TCP: Do not support SSL\r\n");
#endif
        }
        else {
            espconn_disconnect(client->pCon);
        }
        break;
    case TCP_DISCONNECTED:
        INFO("MQTT: Disconnected\r\n");
        mqtt_tcpclient_delete(client);
        break;
    case MQTT_DELETED:
        INFO("MQTT: Deleted client\r\n");
        mqtt_client_delete(client);
        break;
    case MQTT_KEEPALIVE_SEND:
        mqtt_send_keepalive(client);
        break;
    case MQTT_DATA:
        if (QUEUE_IsEmpty(&client->msgQueue) || client->sendTimeout != 0) {
            break;
        }
        if (QUEUE_Gets(&client->msgQueue, dataBuffer, &dataLen, MQTT_BUF_SIZE) == 0) {
            client->mqtt_state.pending_msg_type = mqtt_get_type(dataBuffer);
            client->mqtt_state.pending_msg_id = mqtt_get_id(dataBuffer, dataLen);


            client->sendTimeout = MQTT_SEND_TIMOUT;
            INFO("MQTT: Sending, type: %d, id: %04X\r\n", client->mqtt_state.pending_msg_type, client->mqtt_state.pending_msg_id);
            if (client->security) {
#ifdef MQTT_SSL_ENABLE
                espconn_secure_send(client->pCon, dataBuffer, dataLen);
#else
                INFO("TCP: Do not support SSL\r\n");
#endif
            }
            else {
                espconn_send(client->pCon, dataBuffer, dataLen);
            }

            client->mqtt_state.outbound_message = NULL;
            break;
        }
        break;
    }
}
コード例 #14
0
ファイル: net.c プロジェクト: aeickho/nodemcu-firmware
// Lua: server/socket:close()
// server disconnect everything, unref everything
// client disconnect and unref itself
static int net_close( lua_State* L, const char* mt )
{
  NODE_DBG("net_close is called.\n");
  bool isserver = false;
  int i = 0;
  lnet_userdata *nud = NULL, *skt = NULL;

  nud = (lnet_userdata *)luaL_checkudata(L, 1, mt);
  luaL_argcheck(L, nud, 1, "Server/Socket expected");
  if(nud == NULL)
    return 0;

  if(nud->pesp_conn == NULL)
    return 0;

  if (mt!=NULL && c_strcmp(mt, "net.server")==0)
    isserver = true;
  else if (mt!=NULL && c_strcmp(mt, "net.socket")==0)
    isserver = false;
  else
  {
    NODE_DBG("wrong metatable for net_close.\n");
    return 0;
  }

  if(isserver && nud->pesp_conn->type == ESPCONN_TCP && tcpserver_cb_connect_ref != LUA_NOREF){
    luaL_unref(L, LUA_REGISTRYINDEX, tcpserver_cb_connect_ref);
    tcpserver_cb_connect_ref = LUA_NOREF;
  }

  int n = lua_gettop(L);
  skt = nud;

  do{
    if(isserver && skt == NULL){
      if(socket[i] != LUA_NOREF){  // there is client socket exists
        lua_rawgeti(L, LUA_REGISTRYINDEX, socket[i]);    // get the referenced user_data to stack top
#if 0
        socket[i] = LUA_NOREF;
        socket_num--;
#endif  // do this in net_server_disconnected
        i++;
        if(lua_isuserdata(L,-1)){
          skt = lua_touserdata(L,-1);
        } else {
          lua_pop(L, 1);
          continue;
        }
      }else{
        // skip LUA_NOREF
        i++;
        continue;
      }
    }

    if(skt==NULL){
    	NODE_DBG("userdata is nil.\n");
    	continue;
    }

    if(skt->pesp_conn)    // disconnect the connection
    {
      if(skt->pesp_conn->type == ESPCONN_TCP)
      {
  #ifdef CLIENT_SSL_ENABLE
        if(skt->secure){
        	if(skt->pesp_conn->proto.tcp->remote_port || skt->pesp_conn->proto.tcp->local_port)
        	  espconn_secure_disconnect(skt->pesp_conn);
        }
        else
  #endif
        {
        	if(skt->pesp_conn->proto.tcp->remote_port || skt->pesp_conn->proto.tcp->local_port)
            espconn_disconnect(skt->pesp_conn);
        }
      }else if(skt->pesp_conn->type == ESPCONN_UDP)
      {
        if(skt->pesp_conn->proto.tcp->remote_port || skt->pesp_conn->proto.tcp->local_port)
          espconn_delete(skt->pesp_conn);

        // a udp server/socket unref it self here. not in disconnect.
        if(LUA_NOREF!=skt->self_ref){    // for a udp self_ref is NOREF
          luaL_unref(L, LUA_REGISTRYINDEX, skt->self_ref);
          skt->self_ref = LUA_NOREF;   // for a socket, now only var in lua is ref to the userdata
        }
      }
    }
#if 0
    // unref the self_ref
    if(LUA_NOREF!=skt->self_ref){    // for a server self_ref is NOREF
    	luaL_unref(L, LUA_REGISTRYINDEX, skt->self_ref);
    	skt->self_ref = LUA_NOREF;   // for a socket, now only var in lua is ref to the userdata
    }
#endif
    lua_settop(L, n);   // reset the stack top
    skt = NULL;
  } while( isserver && i<MAX_SOCKET);
#if 0
  // unref the self_ref, for both socket and server
  if(LUA_NOREF!=nud->self_ref){    // for a server self_ref is NOREF
    luaL_unref(L, LUA_REGISTRYINDEX, nud->self_ref);
    nud->self_ref = LUA_NOREF;   // now only var in lua is ref to the userdata
  }
#endif

  return 0;  
}
コード例 #15
0
ファイル: net.c プロジェクト: aeickho/nodemcu-firmware
// Lua: server:listen( port, ip, function(con) )
// Lua: socket:connect( port, ip, function(con) )
static int net_start( lua_State* L, const char* mt )
{
  NODE_DBG("net_start is called.\n");
  struct espconn *pesp_conn = NULL;
  lnet_userdata *nud;
  unsigned port;
  size_t il;
  bool isserver = false;
  ip_addr_t ipaddr;
  const char *domain;
  uint8_t stack = 1;
  
  if (mt!=NULL && c_strcmp(mt, "net.server")==0)
    isserver = true;
  else if (mt!=NULL && c_strcmp(mt, "net.socket")==0)
    isserver = false;
  else
  {
    NODE_DBG("wrong metatable for net_start.\n");
    return 0;
  }
  nud = (lnet_userdata *)luaL_checkudata(L, stack, mt);
  luaL_argcheck(L, nud, stack, "Server/Socket expected");
  stack++;

  if(nud==NULL){
  	NODE_DBG("userdata is nil.\n");
  	return 0;
  }

  pesp_conn = nud->pesp_conn;
  port = luaL_checkinteger( L, stack );
  stack++;
  if( pesp_conn->type == ESPCONN_TCP )
  {
    if(isserver)
      pesp_conn->proto.tcp->local_port = port;
    else{
      pesp_conn->proto.tcp->remote_port = port;
      pesp_conn->proto.tcp->local_port = espconn_port();
    }
    NODE_DBG("TCP port is set: %d.\n", port);
  }
  else if (pesp_conn->type == ESPCONN_UDP)
  {
    if(isserver)
      pesp_conn->proto.udp->local_port = port;
    else{
      pesp_conn->proto.udp->remote_port = port;
      pesp_conn->proto.udp->local_port = espconn_port();
    }
    NODE_DBG("UDP port is set: %d.\n", port);
  }

  if( lua_isstring(L,stack) )   // deal with the domain string
  {
    domain = luaL_checklstring( L, stack, &il );
    stack++;
    if (domain == NULL)
    {
      if(isserver)
        domain = "0.0.0.0";
      else
        domain = "127.0.0.1";
    }
    ipaddr.addr = ipaddr_addr(domain);
    if( pesp_conn->type == ESPCONN_TCP )
    {
      if(isserver)
        c_memcpy(pesp_conn->proto.tcp->local_ip, &ipaddr.addr, 4);
      else
        c_memcpy(pesp_conn->proto.tcp->remote_ip, &ipaddr.addr, 4);
      NODE_DBG("TCP ip is set: ");
      NODE_DBG(IPSTR, IP2STR(&ipaddr.addr));
      NODE_DBG("\n");
    }
    else if (pesp_conn->type == ESPCONN_UDP)
    {
      if(isserver)
        c_memcpy(pesp_conn->proto.udp->local_ip, &ipaddr.addr, 4);
      else
        c_memcpy(pesp_conn->proto.udp->remote_ip, &ipaddr.addr, 4);
      NODE_DBG("UDP ip is set: ");
      NODE_DBG(IPSTR, IP2STR(&ipaddr.addr));
      NODE_DBG("\n");
    }
  }

  // call back function when a connection is obtained, tcp only
  if ( pesp_conn->type == ESPCONN_TCP ) {
    if (lua_type(L, stack) == LUA_TFUNCTION || lua_type(L, stack) == LUA_TLIGHTFUNCTION){
      lua_pushvalue(L, stack);  // copy argument (func) to the top of stack
      if(isserver)    // for tcp server connected callback
      {
        if(tcpserver_cb_connect_ref != LUA_NOREF)
          luaL_unref(L, LUA_REGISTRYINDEX, tcpserver_cb_connect_ref);
        tcpserver_cb_connect_ref = luaL_ref(L, LUA_REGISTRYINDEX);
      } 
      else 
      {
        if(nud->cb_connect_ref != LUA_NOREF)
          luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_connect_ref);
        nud->cb_connect_ref = luaL_ref(L, LUA_REGISTRYINDEX);
      }
    }
  }

  if(!isserver || pesp_conn->type == ESPCONN_UDP){    // self_ref is only needed by socket userdata, or udp server
  	lua_pushvalue(L, 1);  // copy to the top of stack
    if(nud->self_ref != LUA_NOREF)
      luaL_unref(L, LUA_REGISTRYINDEX, nud->self_ref);
  	nud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  }

  if( pesp_conn->type == ESPCONN_TCP )
  {
    if(isserver){   // no secure server support for now
      espconn_regist_connectcb(pesp_conn, net_server_connected);
      // tcp server, SSL is not supported
#ifdef CLIENT_SSL_ENABLE
      // if(nud->secure)
      //   espconn_secure_accept(pesp_conn);
      // else
#endif
        espconn_accept(pesp_conn);    // if it's a server, no need to dns.
        espconn_regist_time(pesp_conn, tcp_server_timeover, 0);
    }
    else{
      espconn_regist_connectcb(pesp_conn, net_socket_connected);
      espconn_regist_reconcb(pesp_conn, net_socket_reconnected);
#ifdef CLIENT_SSL_ENABLE
      if(nud->secure){
      	if(pesp_conn->proto.tcp->remote_port || pesp_conn->proto.tcp->local_port)
          espconn_secure_disconnect(pesp_conn);
        // espconn_secure_connect(pesp_conn);
      }
      else
#endif
      {
      	if(pesp_conn->proto.tcp->remote_port || pesp_conn->proto.tcp->local_port)
          espconn_disconnect(pesp_conn);
        // espconn_connect(pesp_conn);
      }
    }
  }
  else if (pesp_conn->type == ESPCONN_UDP)
  {
    espconn_regist_recvcb(pesp_conn, net_socket_received);
    espconn_regist_sentcb(pesp_conn, net_socket_sent);
  	if(pesp_conn->proto.tcp->remote_port || pesp_conn->proto.tcp->local_port)
    	espconn_delete(pesp_conn);
    if(isserver)
      espconn_create(pesp_conn);    // if it's a server, no need to dns.
  }

  if(!isserver){
    if((ipaddr.addr == IPADDR_NONE) && (c_memcmp(domain,"255.255.255.255",16) != 0))
    {
      host_ip.addr = 0;
      dns_reconn_count = 0;
      if(ESPCONN_OK == espconn_gethostbyname(pesp_conn, domain, &host_ip, socket_dns_found)){
        socket_dns_found(domain, &host_ip, pesp_conn);  // ip is returned in host_ip.
      }
    }
    else
    {
      socket_connect(pesp_conn);
    }
  }
  return 0;  
}
コード例 #16
0
ファイル: rest.c プロジェクト: christiantigor/esp_bridge_emma
void ICACHE_FLASH_ATTR
tcpclient_recv(void *arg, char *pdata, unsigned short len)
{
	uint8_t currentLineIsBlank = 0;
	uint8_t httpBody = 0;
	uint8_t inStatus = 0;
	char statusCode[4];
	int i = 0, j;
	uint32_t code = 0;
	uint16_t crc;

	struct espconn *pCon = (struct espconn*)arg;
	REST_CLIENT *client = (REST_CLIENT *)pCon->reverse;

	for(j=0 ;j<len; j++){
		char c = pdata[j];

		if(c == ' ' && !inStatus){
			inStatus = 1;
		}
		if(inStatus && i < 3 && c != ' '){
			statusCode[i] = c;
			i++;
			//start edit for emma
			if(i == 3) {
				statusCode[i] = '\0';
				code = atoi(statusCode);
				INFO("REST: status = %d\r\n",code);
			}
			//end edit for emma
		}
		if(i == 3){
			statusCode[i] = '\0';
			code = atoi(statusCode);
		}
		 if(httpBody){
			 //only write response if its not null
			 uint32_t body_len = len - j;
			 INFO("REST: status = %d, body_len = %d\r\n",code, body_len);
			 if(body_len == 0){
				 crc = CMD_ResponseStart(CMD_REST_EVENTS, client->resp_cb, code, 0);
			 } else {
				 crc = CMD_ResponseStart(CMD_REST_EVENTS, client->resp_cb, code, 1);
				 crc = CMD_ResponseBody(crc, &pdata[j], body_len);
			 }
			 CMD_ResponseEnd(crc);
			 break;
		}
		else
		{
			if (c == '\n' && currentLineIsBlank) {
				httpBody = true;
			}
			if (c == '\n') {
				// you're starting a new line
				currentLineIsBlank = true;
			}
			else if (c != '\r') {
				// you've gotten a character on the current line
				currentLineIsBlank = false;
			}
		}
	}
	if(client->security)
		espconn_secure_disconnect(client->pCon);
	else
		espconn_disconnect(client->pCon);

}
コード例 #17
0
ファイル: mqtt.c プロジェクト: pvvx/EspLua
static void mqtt_socket_received(void *arg, char *pdata, unsigned short len)
{
  NODE_DBG("enter mqtt_socket_received.\n");

  uint8_t msg_type;
  uint8_t msg_qos;
  uint16_t msg_id;
  msg_queue_t *node = NULL;
  int length = (int)len;
  // uint8_t in_buffer[MQTT_BUF_SIZE];
  uint8_t *in_buffer = (uint8_t *)pdata;

  struct espconn *pesp_conn = arg;
  if(pesp_conn == NULL)
    return;
  lmqtt_userdata *mud = (lmqtt_userdata *)pesp_conn->reverse;
  if(mud == NULL)
    return;

READPACKET:
  if(length > MQTT_BUF_SIZE || length <= 0)
	  return;

  // c_memcpy(in_buffer, pdata, length);
  uint8_t temp_buffer[MQTT_BUF_SIZE];
  mqtt_msg_init(&mud->mqtt_state.mqtt_connection, temp_buffer, MQTT_BUF_SIZE);
  mqtt_message_t *temp_msg = NULL;
  switch(mud->connState){
    case MQTT_CONNECT_SENDING:
    case MQTT_CONNECT_SENT:
      if(mqtt_get_type(in_buffer) != MQTT_MSG_TYPE_CONNACK){
        NODE_DBG("MQTT: Invalid packet\r\n");
        mud->connState = MQTT_INIT;
        if(mud->secure)
          espconn_secure_disconnect(pesp_conn);
        else
          espconn_disconnect(pesp_conn);
      } else {
        mud->connState = MQTT_DATA;
        NODE_DBG("MQTT: Connected\r\n");
        if(mud->cb_connect_ref == LUA_NOREF)
          break;
        if(mud->self_ref == LUA_NOREF)
          break;
        if(mud->L == NULL)
          break;
        lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->cb_connect_ref);
        lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->self_ref);  // pass the userdata(client) to callback func in lua
        lua_call(mud->L, 1, 0);
        break;
      }
      break;

    case MQTT_DATA:
      mud->mqtt_state.message_length_read = length;
      mud->mqtt_state.message_length = mqtt_get_total_length(in_buffer, mud->mqtt_state.message_length_read);
      msg_type = mqtt_get_type(in_buffer);
      msg_qos = mqtt_get_qos(in_buffer);
      msg_id = mqtt_get_id(in_buffer, mud->mqtt_state.message_length);

      msg_queue_t *pending_msg = msg_peek(&(mud->mqtt_state.pending_msg_q));

      NODE_DBG("MQTT_DATA: type: %d, qos: %d, msg_id: %d, pending_id: %d\r\n",
            msg_type,
            msg_qos,
            msg_id,
            (pending_msg)?pending_msg->msg_id:0);
      switch(msg_type)
      {
        case MQTT_MSG_TYPE_SUBACK:
          if(pending_msg && pending_msg->msg_type == MQTT_MSG_TYPE_SUBSCRIBE && pending_msg->msg_id == msg_id){
            NODE_DBG("MQTT: Subscribe successful\r\n");
            msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q)));
            if (mud->cb_suback_ref == LUA_NOREF)
              break;
            if (mud->self_ref == LUA_NOREF)
              break;
            if(mud->L == NULL)
              break;
            lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->cb_suback_ref);
            lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->self_ref);
            lua_call(mud->L, 1, 0);
          }
          break;
        case MQTT_MSG_TYPE_UNSUBACK:
          if(pending_msg && pending_msg->msg_type == MQTT_MSG_TYPE_UNSUBSCRIBE && pending_msg->msg_id == msg_id){
            NODE_DBG("MQTT: UnSubscribe successful\r\n");
            msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q)));
          }
          break;
        case MQTT_MSG_TYPE_PUBLISH:
          if(msg_qos == 1){
            temp_msg = mqtt_msg_puback(&mud->mqtt_state.mqtt_connection, msg_id);
            node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), temp_msg, 
                      msg_id, MQTT_MSG_TYPE_PUBACK, (int)mqtt_get_qos(temp_msg->data) );
          }
          else if(msg_qos == 2){
            temp_msg = mqtt_msg_pubrec(&mud->mqtt_state.mqtt_connection, msg_id);
            node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), temp_msg, 
                      msg_id, MQTT_MSG_TYPE_PUBREC, (int)mqtt_get_qos(temp_msg->data) );
          }
          if(msg_qos == 1 || msg_qos == 2){
            NODE_DBG("MQTT: Queue response QoS: %d\r\n", msg_qos);
          }
          deliver_publish(mud, in_buffer, mud->mqtt_state.message_length);
          break;
        case MQTT_MSG_TYPE_PUBACK:
          if(pending_msg && pending_msg->msg_type == MQTT_MSG_TYPE_PUBLISH && pending_msg->msg_id == msg_id){
            NODE_DBG("MQTT: Publish with QoS = 1 successful\r\n");
            msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q)));
            if(mud->cb_puback_ref == LUA_NOREF)
              break;
            if(mud->self_ref == LUA_NOREF)
              break;
            if(mud->L == NULL)
              break;
            lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->cb_puback_ref);
            lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->self_ref);  // pass the userdata to callback func in lua
            lua_call(mud->L, 1, 0);
          }

          break;
        case MQTT_MSG_TYPE_PUBREC:
          if(pending_msg && pending_msg->msg_type == MQTT_MSG_TYPE_PUBLISH && pending_msg->msg_id == msg_id){
            NODE_DBG("MQTT: Publish  with QoS = 2 Received PUBREC\r\n"); 
            // Note: actrually, should not destroy the msg until PUBCOMP is received.
            msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q)));
            temp_msg = mqtt_msg_pubrel(&mud->mqtt_state.mqtt_connection, msg_id);
            node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), temp_msg, 
                      msg_id, MQTT_MSG_TYPE_PUBREL, (int)mqtt_get_qos(temp_msg->data) );
            NODE_DBG("MQTT: Response PUBREL\r\n");
          }
          break;
        case MQTT_MSG_TYPE_PUBREL:
          if(pending_msg && pending_msg->msg_type == MQTT_MSG_TYPE_PUBREC && pending_msg->msg_id == msg_id){
            msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q)));
            temp_msg = mqtt_msg_pubcomp(&mud->mqtt_state.mqtt_connection, msg_id);
            node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), temp_msg, 
                      msg_id, MQTT_MSG_TYPE_PUBCOMP, (int)mqtt_get_qos(temp_msg->data) );
            NODE_DBG("MQTT: Response PUBCOMP\r\n");
          }
          break;
        case MQTT_MSG_TYPE_PUBCOMP:
          if(pending_msg && pending_msg->msg_type == MQTT_MSG_TYPE_PUBREL && pending_msg->msg_id == msg_id){
            NODE_DBG("MQTT: Publish  with QoS = 2 successful\r\n");
            msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q)));
            if(mud->cb_puback_ref == LUA_NOREF)
              break;
            if(mud->self_ref == LUA_NOREF)
              break;
            if(mud->L == NULL)
              break;
            lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->cb_puback_ref);
            lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->self_ref);  // pass the userdata to callback func in lua
            lua_call(mud->L, 1, 0);
          }
          break;
        case MQTT_MSG_TYPE_PINGREQ:
            temp_msg = mqtt_msg_pingresp(&mud->mqtt_state.mqtt_connection);
            node = msg_enqueue(&(mud->mqtt_state.pending_msg_q), temp_msg, 
                      msg_id, MQTT_MSG_TYPE_PINGRESP, (int)mqtt_get_qos(temp_msg->data) );
            NODE_DBG("MQTT: Response PINGRESP\r\n");
          break;
        case MQTT_MSG_TYPE_PINGRESP:
          // Ignore
          NODE_DBG("MQTT: PINGRESP received\r\n");
          break;
      }
      // NOTE: this is done down here and not in the switch case above
      // because the PSOCK_READBUF_LEN() won't work inside a switch
      // statement due to the way protothreads resume.
      if(msg_type == MQTT_MSG_TYPE_PUBLISH)
      {

        length = mud->mqtt_state.message_length_read;

        if(mud->mqtt_state.message_length < mud->mqtt_state.message_length_read)
				{
					length -= mud->mqtt_state.message_length;
					in_buffer += mud->mqtt_state.message_length;

					NODE_DBG("Get another published message\r\n");
					goto READPACKET;
				}
      }
      break;
  }

  if(node && (1==msg_size(&(mud->mqtt_state.pending_msg_q))) && mud->event_timeout == 0){
    mud->event_timeout = MQTT_SEND_TIMEOUT;
    NODE_DBG("Sent: %d\n", node->msg.length);
    if( mud->secure )
      espconn_secure_sent( pesp_conn, node->msg.data, node->msg.length );
    else
      espconn_sent( pesp_conn, node->msg.data, node->msg.length );
  }
  mud->keep_alive_tick = 0;
  NODE_DBG("receive, queue size: %d\n", msg_size(&(mud->mqtt_state.pending_msg_q)));
  NODE_DBG("leave mqtt_socket_received.\n");
  return;
}
コード例 #18
0
ファイル: mqtt.c プロジェクト: pvvx/EspLua
void mqtt_socket_timer(void *arg)
{
  NODE_DBG("enter mqtt_socket_timer.\n");
  lmqtt_userdata *mud = (lmqtt_userdata*) arg;

  if(mud == NULL)
    return;
  if(mud->pesp_conn == NULL){
    NODE_DBG("mud->pesp_conn is NULL.\n");
    os_timer_disarm(&mud->mqttTimer);
    return;
  }

  NODE_DBG("timer, queue size: %d\n", msg_size(&(mud->mqtt_state.pending_msg_q)));
  if(mud->event_timeout > 0){
    NODE_DBG("event_timeout: %d.\n", mud->event_timeout);
  	mud->event_timeout --;
    if(mud->event_timeout > 0){
      return;
    } else {
      NODE_DBG("event timeout. \n");
      if(mud->connState == MQTT_DATA)
        msg_destroy(msg_dequeue(&(mud->mqtt_state.pending_msg_q)));
      // should remove the head of the queue and re-send with DUP = 1
      // Not implemented yet.
    }
  }

  if(mud->connState == MQTT_INIT){ // socket connect time out.
    NODE_DBG("Can not connect to broker.\n");
    // Never goes here.
  } else if(mud->connState == MQTT_CONNECT_SENDING){ // MQTT_CONNECT send time out.
    NODE_DBG("sSend MQTT_CONNECT failed.\n");
    mud->connState = MQTT_INIT;
    if(mud->secure)
      espconn_secure_disconnect(mud->pesp_conn);
    else 
      espconn_disconnect(mud->pesp_conn);
    mud->keep_alive_tick = 0; // not need count anymore
  } else if(mud->connState == MQTT_CONNECT_SENT){ // wait for CONACK time out.
    NODE_DBG("MQTT_CONNECT failed.\n");
  } else if(mud->connState == MQTT_DATA){
    msg_queue_t *pending_msg = msg_peek(&(mud->mqtt_state.pending_msg_q));
    if(pending_msg){
      mud->event_timeout = MQTT_SEND_TIMEOUT;
      if(mud->secure)
        espconn_secure_sent(mud->pesp_conn, pending_msg->msg.data, pending_msg->msg.length);
      else
        espconn_sent(mud->pesp_conn, pending_msg->msg.data, pending_msg->msg.length);
      mud->keep_alive_tick = 0;
      NODE_DBG("id: %d - qos: %d, length: %d\n", pending_msg->msg_id, pending_msg->publish_qos, pending_msg->msg.length);
    } else {
      // no queued event.
      mud->keep_alive_tick ++;
      if(mud->keep_alive_tick > mud->mqtt_state.connect_info->keepalive){
        mud->event_timeout = MQTT_SEND_TIMEOUT;
        uint8_t temp_buffer[MQTT_BUF_SIZE];
        mqtt_msg_init(&mud->mqtt_state.mqtt_connection, temp_buffer, MQTT_BUF_SIZE);
        NODE_DBG("\r\nMQTT: Send keepalive packet\r\n");
        mqtt_message_t* temp_msg = mqtt_msg_pingreq(&mud->mqtt_state.mqtt_connection);
        msg_queue_t *node = msg_enqueue( &(mud->mqtt_state.pending_msg_q), temp_msg, 
                            0, MQTT_MSG_TYPE_PINGREQ, (int)mqtt_get_qos(temp_msg->data) );
        // only one message in queue, send immediately.
        if(mud->secure)
          espconn_secure_sent(mud->pesp_conn, temp_msg->data, temp_msg->length);
        else
          espconn_sent(mud->pesp_conn, temp_msg->data, temp_msg->length);
        mud->keep_alive_tick = 0;
      }
    }
  }
  NODE_DBG("leave mqtt_socket_timer.\n");
}
コード例 #19
0
ファイル: mqtt.c プロジェクト: leeshineSZ/tisan_project
/**
  * @brief  Client received callback function.
  * @param  arg: contain the ip link information
  * @param  pdata: received data
  * @param  len: the lenght of received data
  * @retval None
  */
void ICACHE_FLASH_ATTR
mqtt_tcpclient_recv(void *arg, char *pdata, unsigned short len)
{
	INFO("TCP: data received %d bytes\r\n", len);

	uint8_t msg_type;
	uint8_t msg_qos;
	uint16_t msg_id;

	struct espconn *pCon = (struct espconn*)arg;
	MQTT_Client *client = (MQTT_Client *)pCon->reverse;

	if(len > MQTT_BUF_SIZE || len == 0)
	{
		INFO("receive length is invalid.\n");
		return;
	}

	os_memcpy(client->mqtt_state.in_buffer + client->mqtt_state.message_length_read, pdata, len);
	client->mqtt_state.message_length_read += len;

READPACKET:
	if(client->mqtt_state.message_length_read == 1)
	{
		INFO("not enough data for read package length.\n!");
		return;
	}

	client->mqtt_state.message_length = mqtt_get_total_length(client->mqtt_state.in_buffer, client->mqtt_state.message_length_read);
	INFO("message length:%d\n", client->mqtt_state.message_length);

	show_package(client->mqtt_state.in_buffer, client->mqtt_state.message_length_read);

	if(client->mqtt_state.message_length > client->mqtt_state.message_length_read)
	{
		INFO("not enough data.\n");
		return;
	}

	msg_type = mqtt_get_type(client->mqtt_state.in_buffer);
	msg_qos = mqtt_get_qos(client->mqtt_state.in_buffer);
	msg_id = mqtt_get_id(client->mqtt_state.in_buffer, client->mqtt_state.message_length);
	INFO("client->connstate:%d, type:%d, Qos:%d, id:%d, message length:%d\n", client->connState, msg_type, msg_qos, \
			msg_id, client->mqtt_state.message_length);
	switch(client->connState)

	{
		case MQTT_CONNECT_SENDING:
		if(msg_type == MQTT_MSG_TYPE_CONNACK)
		{
			if(client->mqtt_state.pending_msg_type != MQTT_MSG_TYPE_CONNECT)
			{
				INFO("MQTT: Invalid packet\r\n");
				if(client->security)
				{
					espconn_secure_disconnect(client->pCon);
				}
				else
				{
					espconn_disconnect(client->pCon);
				}
			}

			else
			{
				INFO("MQTT: Connected to %s:%d\r\n", client->host, client->port);
				client->connState = MQTT_DATA;
				if(client->connectedCb)
					client->connectedCb((uint32_t*)client);
			}

		}
		break;

		case MQTT_DATA:
		switch(msg_type)
		{
			case MQTT_MSG_TYPE_SUBACK:
			if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_SUBSCRIBE && client->mqtt_state.pending_msg_id == msg_id)
			INFO("MQTT: Subscribe successful\r\n");
			break;

			case MQTT_MSG_TYPE_UNSUBACK:
			if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_UNSUBSCRIBE && client->mqtt_state.pending_msg_id == msg_id)
			INFO("MQTT: UnSubscribe successful\r\n");
			break;

			case MQTT_MSG_TYPE_PUBLISH:
			if(msg_qos == 1)
			client->mqtt_state.outbound_message = mqtt_msg_puback(&client->mqtt_state.mqtt_connection, msg_id);
			else if(msg_qos == 2)
			client->mqtt_state.outbound_message = mqtt_msg_pubrec(&client->mqtt_state.mqtt_connection, msg_id);
			if(msg_qos == 1 || msg_qos == 2)
			{
				INFO("MQTT: Queue response QoS: %d\r\n", msg_qos);
				if(QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data,\
						client->mqtt_state.outbound_message->length) == -1)
				{
					INFO("MQTT: Queue full\r\n");
				}
			}
			show_package(client->mqtt_state.in_buffer, client->mqtt_state.message_length);
			deliver_publish(client, client->mqtt_state.in_buffer, client->mqtt_state.message_length);
			break;

			case MQTT_MSG_TYPE_PUBACK:
			if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && client->mqtt_state.pending_msg_id == msg_id)
			{
				INFO("MQTT: received MQTT_MSG_TYPE_PUBACK, finish QoS1 publish\r\n");
			}
			break;

			case MQTT_MSG_TYPE_PUBREC:
			client->mqtt_state.outbound_message = mqtt_msg_pubrel(&client->mqtt_state.mqtt_connection, msg_id);
			if(QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1)
			{
				INFO("MQTT: Queue full\r\n");
			}
			break;

			case MQTT_MSG_TYPE_PUBREL:
			client->mqtt_state.outbound_message = mqtt_msg_pubcomp(&client->mqtt_state.mqtt_connection, msg_id);
			if(QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1)
			{
				INFO("MQTT: Queue full\r\n");
			}
			break;

			case MQTT_MSG_TYPE_PUBCOMP:
			if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && client->mqtt_state.pending_msg_id == msg_id)
			{
				INFO("MQTT: receive MQTT_MSG_TYPE_PUBCOMP, finish QoS2 publish\r\n");
			}
			break;

			case MQTT_MSG_TYPE_PINGREQ:
			client->mqtt_state.outbound_message = mqtt_msg_pingresp(&client->mqtt_state.mqtt_connection);
			if(QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1)
			{
				INFO("MQTT: Queue full\r\n");
			}
			break;

			case MQTT_MSG_TYPE_PINGRESP:
			INFO("receive a heart beat response!\n");
			client->heart_beat_flag  = 1;
			break;
		}

		break;
	}

	// process package adhesive.
	uint16_t remain_length = client->mqtt_state.message_length_read - client->mqtt_state.message_length;
	client->mqtt_state.message_length_read = remain_length;
	INFO("client->mqtt_state.message_length_read = %d\n", client->mqtt_state.message_length_read);
	INFO("client->mqtt_state.message_length = %d\n", client->mqtt_state.message_length);
	INFO("the package is\n");
	show_package(client->mqtt_state.in_buffer, client->mqtt_state.message_length);
	if(remain_length > 0)
	{
		int i = 0;
		for(i = 0; i< remain_length; i++)
		{
			client->mqtt_state.in_buffer[i] = \
					client->mqtt_state.in_buffer[client->mqtt_state.message_length_read - remain_length + i];
		}

		INFO("Get another published message\r\n");
		goto READPACKET;
	}

	system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client);
}
コード例 #20
0
ファイル: fota-info.c プロジェクト: bcatalin/esp8266-dev
/**
  * @brief  response for get version request.
  *         parse answer, save online version to flash.
  * @param  arg: contain the ip link information
  *         pusrdata: data
  *         len: len of data (strlen)
  * @retval None
  */
LOCAL void ICACHE_FLASH_ATTR
get_version_recv(void *arg, char *pusrdata, unsigned short len)
{
  struct espconn *pespconn = arg;
  fota_client_t *fota_client = (fota_client_t *)pespconn->reverse;

  /* get body */
  char *body = (char*)os_strstr(pusrdata, "\r\n\r\n");
  if (body == NULL) {
    INFO("Invalide response\n");
    return;
  }
  INFO("Body: %s\n", body+4);
  uint32_t bodylen = os_strlen(body);

  /* parse json, get version */  
  char *n_host,
       *n_url,
       *n_version,
       *n_protocol;

  if (parse_fota(body, bodylen, &n_version, &n_host, &n_url, &n_protocol) < 0) {
    INFO("FOTA Client: Invalid response\n");
    goto CLEAN_MEM;
  }
  INFO("\tVersion %s\n", n_version);
  INFO("\tHost %s\n", n_host);
  INFO("\tURL %s\n", n_url);
  INFO("\tProtocol %s\n", n_protocol);

  /* then, we have valide JSON response */  
  // disable data receiving timeout handing
  // and close connection 
  os_timer_disarm(&fota_client->request_timeout);
#if (FOTA_SECURE)
  espconn_secure_disconnect(pespconn);
#else
  espconn_disconnect(pespconn);
#endif

  uint32_t version;
  if (convert_version(n_version, os_strlen(n_version), &version) < 0) {
    REPORT("FOTA Client: Invalide version return %s\n", n_version);
    goto CLEAN_MEM;
  }

  /* if we still have lastest version */
  if (version <= version_fwr) {
    INFO("FOTA Client: We have lastest firmware (current %u.%u.%u vs online %u.%u.%u)\n", 
      (version_fwr/256/256)%256, (version_fwr/256)%256, version_fwr%256,
      (version/256/256)%256, (version/256)%256, version%256);
    goto CLEAN_MEM;
  }

  INFO("FOTA Client: Preparing to get firmware\n");

  start_cdn(&fota_client->fw_server, n_version, n_host, n_url, n_protocol);

CLEAN_MEM:
  FREE(n_host);
  FREE(n_url);
  FREE(n_version);
  FREE(n_protocol);
}