コード例 #1
0
ファイル: mqtt-service.c プロジェクト: EmuxEvans/contiki-mqtt
int mqtt_unsubscribe(const char* topic)
{
  if(!mqtt_ready())
    return -1;

  printf("sending unsubscribe\n");
  mqtt_state.outbound_message = mqtt_msg_unsubscribe(&mqtt_state.mqtt_connection, topic, 
                                                     &mqtt_state.pending_msg_id);
  mqtt_flags &= ~MQTT_FLAG_READY;
  mqtt_state.pending_msg_type = MQTT_MSG_TYPE_UNSUBSCRIBE;
  tcpip_poll_tcp(mqtt_state.tcp_connection);

  return 0;
}
コード例 #2
0
ファイル: mqtt-service.c プロジェクト: EmuxEvans/contiki-mqtt
// Publish the specified message
int mqtt_publish_with_length(const char* topic, const char* data, int data_length, int qos, int retain)
{
  if(!mqtt_ready())
    return -1;

  printf("mqtt: sending publish...\n");
  mqtt_state.outbound_message = mqtt_msg_publish(&mqtt_state.mqtt_connection, 
                                                 topic, data, data_length, 
                                                 qos, retain,
                                                 &mqtt_state.pending_msg_id);
  mqtt_flags &= ~MQTT_FLAG_READY;
  mqtt_state.pending_msg_type = MQTT_MSG_TYPE_PUBLISH;
  tcpip_poll_tcp(mqtt_state.tcp_connection);

  return 0;
}
コード例 #3
0
ファイル: mqtt-client.c プロジェクト: zzeekk/cc26xx-st2
/*---------------------------------------------------------------------------*/
static void
state_machine(void)
{
    switch(state) {
    case MQTT_CLIENT_STATE_INIT:
        /* If we have just been configured register MQTT connection */
        mqtt_register(&conn, &mqtt_client_process, client_id, mqtt_event,
                      MQTT_CLIENT_MAX_SEGMENT_SIZE);

        /*
         * Authentication: provide user name and password
         */
        if(strlen(conf->auth_token) > 0) {
            mqtt_set_username_password(&conn, "use-token-auth",
                                       conf->auth_token);
        }

        /* _register() will set auto_reconnect. We don't want that. */
        conn.auto_reconnect = 0;
        connect_attempt = 1;

        /*
         * Wipe out the default route so we'll republish it every time we switch to
         * a new broker
         */
        memset(&def_route, 0, sizeof(def_route));

        state = MQTT_CLIENT_STATE_REGISTERED;
        DBG("Init\n");
    /* Continue */
    case MQTT_CLIENT_STATE_REGISTERED:
        if(uip_ds6_get_global(ADDR_PREFERRED) != NULL) {
            /* Registered and with a public IP. Connect */
            DBG("Registered. Connect attempt %u\n", connect_attempt);
            ping_parent();
            connect_to_broker();
        }
        etimer_set(&publish_periodic_timer, CC26XX_WEB_DEMO_NET_CONNECT_PERIODIC);
        return;
        break;
    case MQTT_CLIENT_STATE_CONNECTING:
        leds_on(CC26XX_WEB_DEMO_STATUS_LED);
        ctimer_set(&ct, CONNECTING_LED_DURATION, publish_led_off, NULL);
        /* Not connected yet. Wait */
        DBG("Connecting (%u)\n", connect_attempt);
        break;
    case MQTT_CLIENT_STATE_CONNECTED:
    /* Don't subscribe unless we are a registered device
    if(strncasecmp(conf->org_id, QUICKSTART, strlen(conf->org_id)) == 0) {
      DBG("Using 'quickstart': Skipping subscribe\n");
      state = MQTT_CLIENT_STATE_PUBLISHING;
    }*/
    /* Continue */
    case MQTT_CLIENT_STATE_PUBLISHING:
        /* If the timer expired, the connection is stable. */
        if(timer_expired(&connection_life)) {
            /*
             * Intentionally using 0 here instead of 1: We want RECONNECT_ATTEMPTS
             * attempts if we disconnect after a successful connect
             */
            connect_attempt = 0;
        }

        if(mqtt_ready(&conn) && conn.out_buffer_sent) {
            /* Connected. Publish */
            if(state == MQTT_CLIENT_STATE_CONNECTED) {
                subscribe();
                state = MQTT_CLIENT_STATE_PUBLISHING;
            } else {
                leds_on(CC26XX_WEB_DEMO_STATUS_LED);
                ctimer_set(&ct, PUBLISH_LED_ON_DURATION, publish_led_off, NULL);
                publish();
            }
            etimer_set(&publish_periodic_timer, conf->pub_interval);

            DBG("Publishing\n");
            /* Return here so we don't end up rescheduling the timer */
            return;
        } else {
            /*
             * Our publish timer fired, but some MQTT packet is already in flight
             * (either not sent at all, or sent but not fully ACKd).
             *
             * This can mean that we have lost connectivity to our broker or that
             * simply there is some network delay. In both cases, we refuse to
             * trigger a new message and we wait for TCP to either ACK the entire
             * packet after retries, or to timeout and notify us.
             */
            DBG("Publishing... (MQTT state=%d, q=%u)\n", conn.state,
                conn.out_queue_full);
        }
        break;
    case MQTT_CLIENT_STATE_DISCONNECTED:
        DBG("Disconnected\n");
        if(connect_attempt < RECONNECT_ATTEMPTS ||
                RECONNECT_ATTEMPTS == RETRY_FOREVER) {
            /* Disconnect and backoff */
            clock_time_t interval;
            mqtt_disconnect(&conn);
            connect_attempt++;

            interval = connect_attempt < 3 ? RECONNECT_INTERVAL << connect_attempt :
                       RECONNECT_INTERVAL << 3;

            DBG("Disconnected. Attempt %u in %lu ticks\n", connect_attempt, interval);

            etimer_set(&publish_periodic_timer, interval);

            state = MQTT_CLIENT_STATE_REGISTERED;
            return;
        } else {
            /* Max reconnect attempts reached. Enter error state */
            state = MQTT_CLIENT_STATE_ERROR;
            DBG("Aborting connection after %u attempts\n", connect_attempt - 1);
        }
        break;
    case MQTT_CLIENT_STATE_NEWCONFIG:
        /* Only update config after we have disconnected */
        if(conn.state == MQTT_CONN_STATE_NOT_CONNECTED) {
            update_config();
            DBG("New config\n");

            /* update_config() scheduled next pass. Return */
            return;
        }
        break;
    case MQTT_CLIENT_STATE_CONFIG_ERROR:
        /* Idle away. The only way out is a new config */
        printf("Bad configuration.\n");
        return;
    case MQTT_CLIENT_STATE_ERROR:
    default:
        leds_on(CC26XX_WEB_DEMO_STATUS_LED);
        /*
         * 'default' should never happen.
         *
         * If we enter here it's because of some error. Stop timers. The only thing
         * that can bring us out is a new config event
         */
        printf("Default case: State=0x%02x\n", state);
        return;
    }

    /* If we didn't return so far, reschedule ourselves */
    etimer_set(&publish_periodic_timer, STATE_MACHINE_PERIODIC);
}