Exemplo n.º 1
0
Arquivo: mqtt.c Projeto: pvvx/EspLua
static void deliver_publish(lmqtt_userdata * mud, uint8_t* message, int length)
{
  NODE_DBG("enter deliver_publish.\n");
  if(mud == NULL)
    return;
  mqtt_event_data_t event_data;

  event_data.topic_length = length;
  event_data.topic = mqtt_get_publish_topic(message, &event_data.topic_length);

  event_data.data_length = length;
  event_data.data = mqtt_get_publish_data(message, &event_data.data_length);

  if(mud->cb_message_ref == LUA_NOREF)
    return;
  if(mud->self_ref == LUA_NOREF)
    return;
  if(mud->L == NULL)
    return;
  if(event_data.topic && (event_data.topic_length > 0)){
    lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->cb_message_ref);
    lua_rawgeti(mud->L, LUA_REGISTRYINDEX, mud->self_ref);  // pass the userdata to callback func in lua
    lua_pushlstring(mud->L, event_data.topic, event_data.topic_length);
  } else {
    NODE_DBG("get wrong packet.\n");
    return;
  }
  if(event_data.data && (event_data.data_length > 0)){
    lua_pushlstring(mud->L, event_data.data, event_data.data_length);
    lua_call(mud->L, 3, 0);
  } else {
    lua_call(mud->L, 2, 0);
  }
  NODE_DBG("leave deliver_publish.\n");
}
Exemplo n.º 2
0
LOCAL void ICACHE_FLASH_ATTR deliver_publish(MQTT_Client * client, uint8_t * message, int length) {
    mqtt_event_data_t event_data;

    event_data.topic_length = length;
    event_data.topic = mqtt_get_publish_topic(message, &event_data.topic_length);
    event_data.data_length = length;
    event_data.data = mqtt_get_publish_data(message, &event_data.data_length);

    if (client->dataCb)
	client->dataCb((uint32_t *) client, event_data.topic, event_data.topic_length, event_data.data,
		       event_data.data_length);

}
Exemplo n.º 3
0
static void FUNCTION_ATTRIBUTE
deliver_publish(MQTT_Client* client, uint8_t* message, int length)
{
	mqtt_event_data_t event_data;

	event_data.topic_length = length;
	event_data.topic = mqtt_get_publish_topic(message, &event_data.topic_length);
	event_data.data_length = length;
	event_data.data = mqtt_get_publish_data(message, &event_data.data_length);

	if(client->dataCb)
		client->dataCb((uint32_t*)client, event_data.topic, event_data.topic_length, event_data.data, event_data.data_length);

}
Exemplo n.º 4
0
// Deliver a publish message to the client
static void ICACHE_FLASH_ATTR
deliver_publish(MQTT_Client* client, uint8_t* message, uint16_t length) {

  // parse the message into topic and data
  uint16_t topic_length = length;
  const char *topic = mqtt_get_publish_topic(message, &topic_length);
  uint16_t data_length = length;
  const char *data = mqtt_get_publish_data(message, &data_length);

  // callback to client
  if (client->dataCb)
    client->dataCb((uint32_t*)client, topic, topic_length, data, data_length);
  if (client->cmdDataCb)
    client->cmdDataCb((uint32_t*)client, topic, topic_length, data, data_length);
}
Exemplo n.º 5
0
static void deliver_publish(mqtt_state_t* state, uint8_t* message, int length)
{
  mqtt_event_data_t event_data;

  event_data.type = MQTT_EVENT_TYPE_PUBLISH;

  event_data.topic_length = length;
  event_data.topic = mqtt_get_publish_topic(message, &event_data.topic_length);

  event_data.data_length = length;
  event_data.data = mqtt_get_publish_data(message, &event_data.data_length);

  memmove((char*)event_data.data + 1, (char*)event_data.data, event_data.data_length);
  event_data.data += 1;
  ((char*)event_data.topic)[event_data.topic_length] = '\0';
  ((char*)event_data.data)[event_data.data_length] = '\0';

  process_post_synch(state->calling_process, mqtt_event, &event_data);
}
Exemplo n.º 6
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;

//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);
}
Exemplo n.º 7
0
static PT_THREAD(handle_mqtt_connection(mqtt_state_t* state))
{
  static struct etimer keepalive_timer;

  uint8_t msg_type;
  uint8_t msg_qos;
  uint16_t msg_id;

  PSOCK_BEGIN(&state->ps);

  // Initialise and send CONNECT message
  mqtt_msg_init(&state->mqtt_connection, state->out_buffer, state->out_buffer_length);
  state->outbound_message =  mqtt_msg_connect(&state->mqtt_connection, state->connect_info);
  PSOCK_SEND(&state->ps, state->outbound_message->data, state->outbound_message->length);
  state->outbound_message = NULL;

  // Wait for CONACK message
  PSOCK_READBUF_LEN(&state->ps, 2);
  if(mqtt_get_type(state->in_buffer) != MQTT_MSG_TYPE_CONNACK)
    PSOCK_CLOSE_EXIT(&state->ps);
  
  // Tell the client we're connected
  mqtt_flags |= MQTT_FLAG_CONNECTED;
  complete_pending(state, MQTT_EVENT_TYPE_CONNECTED);

  // Setup the keep alive timer and enter main message processing loop
  etimer_set(&keepalive_timer, CLOCK_SECOND * state->connect_info->keepalive);
  while(1)
  {
    // Wait for something to happen: 
    //   new incoming data, 
    //   new outgoing data, 
    //   keep alive timer expired
    PSOCK_WAIT_UNTIL(&state->ps, PSOCK_NEWDATA(&state->ps) || 
                                 state->outbound_message != NULL ||
                                 etimer_expired(&keepalive_timer));

    // If there's a new message waiting to go out, then send it
    if(state->outbound_message != NULL)
    {
      PSOCK_SEND(&state->ps, state->outbound_message->data, state->outbound_message->length);
      state->outbound_message = NULL;

      // If it was a PUBLISH message with QoS-0 then tell the client it's done
      if(state->pending_msg_type == MQTT_MSG_TYPE_PUBLISH && state->pending_msg_id == 0)
        complete_pending(state, MQTT_EVENT_TYPE_PUBLISHED);

      // Reset the keepalive timer as we've just sent some data
      etimer_restart(&keepalive_timer);
      continue;
    }

    // If the keep-alive timer expired then prepare a ping for sending
    // and reset the timer
    if(etimer_expired(&keepalive_timer))
    {
      state->outbound_message = mqtt_msg_pingreq(&state->mqtt_connection);
      etimer_reset(&keepalive_timer);
      continue;
    }

    // If we get here we must have woken for new incoming data, 
    // read and process it.
    PSOCK_READBUF_LEN(&state->ps, 2);
    
    state->message_length_read = PSOCK_DATALEN(&state->ps);
    state->message_length = mqtt_get_total_length(state->in_buffer, state->message_length_read);

    msg_type = mqtt_get_type(state->in_buffer);
    msg_qos  = mqtt_get_qos(state->in_buffer);
    msg_id   = mqtt_get_id(state->in_buffer, state->in_buffer_length);
    switch(msg_type)
    {
      case MQTT_MSG_TYPE_SUBACK:
        if(state->pending_msg_type == MQTT_MSG_TYPE_SUBSCRIBE && state->pending_msg_id == msg_id)
          complete_pending(state, MQTT_EVENT_TYPE_SUBSCRIBED);
        break;
      case MQTT_MSG_TYPE_UNSUBACK:
        if(state->pending_msg_type == MQTT_MSG_TYPE_UNSUBSCRIBE && state->pending_msg_id == msg_id)
          complete_pending(state, MQTT_EVENT_TYPE_UNSUBSCRIBED);
        break;
      case MQTT_MSG_TYPE_PUBLISH:
        if(msg_qos == 1)
          state->outbound_message = mqtt_msg_puback(&state->mqtt_connection, msg_id);
        else if(msg_qos == 2)
          state->outbound_message = mqtt_msg_pubrec(&state->mqtt_connection, msg_id);

        deliver_publish(state, state->in_buffer, state->message_length_read);
        break;
      case MQTT_MSG_TYPE_PUBACK:
        if(state->pending_msg_type == MQTT_MSG_TYPE_PUBLISH && state->pending_msg_id == msg_id)
          complete_pending(state, MQTT_EVENT_TYPE_PUBLISHED);
        break;
      case MQTT_MSG_TYPE_PUBREC:
        state->outbound_message = mqtt_msg_pubrel(&state->mqtt_connection, msg_id);
        break;
      case MQTT_MSG_TYPE_PUBREL:
        state->outbound_message = mqtt_msg_pubcomp(&state->mqtt_connection, msg_id);
        break;
      case MQTT_MSG_TYPE_PUBCOMP:
        if(state->pending_msg_type == MQTT_MSG_TYPE_PUBLISH && state->pending_msg_id == msg_id)
          complete_pending(state, MQTT_EVENT_TYPE_PUBLISHED);
        break;
      case MQTT_MSG_TYPE_PINGREQ:
        state->outbound_message = mqtt_msg_pingresp(&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 = state->message_length_read;
      mqtt_get_publish_data(state->in_buffer, &len);
      len = state->message_length_read - len;
      state->message_length -= len;
      state->message_length_read -= len;

      while(state->message_length_read < state->message_length)
      {
        PSOCK_READBUF_LEN(&state->ps, state->message_length - state->message_length_read);
        deliver_publish_continuation(state, state->message_length_read, state->in_buffer, PSOCK_DATALEN(&state->ps));
        state->message_length_read += PSOCK_DATALEN(&state->ps);
      }
    }
  }

  PSOCK_END(&state->ps);
}