examples/zolertia/tutorial/99-apps/mqtt-node/cloud/ubidots.c
static void
ubidots_pub_handler(const char *topic, uint16_t topic_len, const uint8_t *chunk,
            uint16_t chunk_len)
{
  uint8_t i;
  uint16_t aux;

  PRINTF("Ubidots: Pub Handler, topic='%s' (len=%u), chunk='%s', chunk_len=%u\n",
         topic, topic_len, chunk, chunk_len);

  /* Most of the commands follow a boolean-logic at least */
  if(chunk_len <= 0) {
    PRINTF("Ubidots: Chunk should be at least a single digit integer or string\n");
    return;
  }

  /* This is a command event, it uses "1" and "0" strings for true or false
   * As default we use the "/lv" request upon subscribing, we expect an numeric
   * string as chunk
   */
  if(strncmp(topic, cmd_topic, CONFIG_SUB_CMD_TOPIC_LEN) == 0) {

    /* Add an extra byte for the level separator */
    aux = strlen(DEFAULT_TOPIC_LONG) + UBIDOTS_LABEL_LEN + 1;

    /* Toggle a given LED */
    if(strncmp((const char *)&topic[aux], DEFAULT_SUBSCRIBE_CMD_LEDS,
               strlen(DEFAULT_SUBSCRIBE_CMD_LEDS)) == 0) {
      PRINTF("Ubidots: Command received --> toggle LED\n");

      if(strncmp((const char *)chunk, "1", 1) == 0) {
        leds_on(CMD_LED);
      } else if(strncmp((const char *)chunk, "0", 1) == 0) {
        leds_off(CMD_LED);
      } else {
        PRINTF("Ubidots: invalid command argument (expected boolean)!\n");
      }

      return;

    /* Restart the device */
    } else if(strncmp((const char *)&topic[aux], DEFAULT_SUBSCRIBE_CMD_REBOOT,
               strlen(DEFAULT_SUBSCRIBE_CMD_REBOOT)) == 0) {
      PRINTF("Ubidots: Command received --> reboot\n");

      /* This is fixed to check only "true" arguments */
      if(strncmp((const char *)chunk, "1", 1) == 0) {
        sys_ctrl_reset();
      } else {
        PRINTF("Ubidots: invalid command argument (expected only 'true')!\n");
      }

      return;

    /* Enable or disable external sensors */
    } else if(strncmp((const char *)&topic[aux], DEFAULT_SUBSCRIBE_CMD_SENSOR,
               strlen(DEFAULT_SUBSCRIBE_CMD_SENSOR)) == 0) {
      PRINTF("Ubidots: Command received --> enable/disable sensor\n");

      if(strncmp((const char *)chunk, "1", 1) == 0) {
        activate_sensors(0x01);
      } else if(strncmp((const char *)chunk, "0", 1) == 0) {
        activate_sensors(0x00);
      } else {
        PRINTF("Ubidots: invalid command argument (expected boolean)!\n");
      }

      return;

    /* This is a configuration event
     * As currently Contiki's MQTT driver does not support more than one SUBSCRIBE
     * we are handling both commands and configurations in the same "cmd" topic
     * We expect the configuration payload to follow the next syntax:
     * {"name":"update_period","value":61}
     */

    /* Change the update period */
    } else if(strncmp((const char *)&topic[aux], DEFAULT_SUBSCRIBE_CMD_EVENT,
               strlen(DEFAULT_SUBSCRIBE_CMD_EVENT)) == 0) {

      /* Take integers as configuration value */
      aux = atoi((const char*) chunk);

      if(mqtt_check_int_chunk_len(aux, chunk_len)) {
        PRINTF("Ubidots: chunk lenght doesn't match integer\n");
        return;
      }

      /* Check for allowed values */
      if((aux < DEFAULT_UPDATE_PERIOD_MIN) || (aux > DEFAULT_UPDATE_PERIOD_MAX)) {
        PRINTF("Ubidots: update interval should be between %u and %u\n", 
                DEFAULT_UPDATE_PERIOD_MIN, DEFAULT_UPDATE_PERIOD_MAX);
        return;
      }

      conf.pub_interval_check = aux;
      PRINTF("Ubidots: New update interval --> %u secs\n", conf.pub_interval_check);
      // mqtt_write_config_to_flash();
      return;
    }
#if DEFAULT_SENSORS_NUM
    /* Change a sensor's threshold, skip is `sensor_config` is empty */
    for(i=0; i<SENSORS_NAME(MQTT_SENSORS, _sensors.num); i++) {

      if((strlen(SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].sensor_config))) &&
        (strncmp((const char *)&topic[aux], SENSORS_NAME(MQTT_SENSORS, _sensors.sensor[i].sensor_config),
                      strlen(SENSORS_NAME(MQTT_SENSORS, _sensors.sensor[i].sensor_config))) == 0)) {

        /* Take integers as configuration value */
        aux = atoi((const char*) chunk);

        if(mqtt_check_int_chunk_len(aux, chunk_len)) {
          PRINTF("Ubidots: chunk lenght doesn't match integer\n");
          return;
        }

        if((aux < SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].min)) || 
          (aux > SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].max))) {
          PRINTF("Ubidots: %s threshold should be between %d and %d\n",
                 SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].sensor_name),
                 SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].min),
                 SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].max));
          return;
        }

        /* We have now a valid threshold value, the logic is simple: each
         * variable has a `thresh` to configure a limit over the given value,
         * and `thresl` which respectively checks for values below this limit.
         * As a convention we are expecting `sensor_config` strings ending in
         * `_thresh` or `_thresl`.  The check below "should" be "safe" as we are
         * sure it matches an expected string.
         */

        if(strstr((const char *)topic, "_thresh") != NULL) {
          SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].over_threshold) = aux;
          PRINTF("Ubidots: New %s over threshold --> %u\n",
                 SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].sensor_name),
                 SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].over_threshold));
        } else if(strstr((const char *)topic, "_thresl") != NULL) {
          SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].below_threshold) = aux;
          PRINTF("Ubidots: New %s below threshold --> %u\n",
                 SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].sensor_name),
                 SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].below_threshold));
        } else {
          PRINTF("Ubidots: Expected threshold configuration name to end ");
          PRINTF("either in thresh or thresl\n");
        }

        return;
      }
    }
#endif /* DEFAULT_SENSORS_NUM */

    /* We are now checking for any string command expected by the subscribed
     * sensor module
     */
#if DEFAULT_COMMANDS_NUM
    for(i=0; i<SENSORS_NAME(MQTT_SENSORS, _commands.num); i++) {

      if(strncmp((const char *)&topic[aux], 
          SENSORS_NAME(MQTT_SENSORS, _commands.command[i].command_name),
          strlen(SENSORS_NAME(MQTT_SENSORS, _commands.command[i].command_name))) == 0) {

        /* Take integers as argument value */
        aux = atoi((const char*) chunk);

        /* Invoke the command handler */
        SENSORS_NAME(MQTT_SENSORS,_commands.command[i].cmd(aux));
        return;
      }
    }
#endif /* DEFAULT_COMMANDS_NUM */

    /* Invalid configuration topic, we should have returned before */
    PRINTF("Ubidots: Configuration/Command parameter not recognized\n");

  } else {
    PRINTF("Ubidots: Incorrect topic or chunk len. Ignored\n");
  }
}
/* DEFAULT_SENSORS_NUM */
/*---------------------------------------------------------------------------*/
/* This function handler receives publications to which we are subscribed */
DEFAULT_SENSORS_NUM
This function handler receives publications to which we are subscribed
DEFAULT_SENSORS_NUM This function handler receives publications to which we are subscribed
static void
ubidots_pub_handler(const char *topic, uint16_t topic_len, const uint8_t *chunk,
            uint16_t chunk_len)
{
  uint8_t i;
  uint16_t aux;
  PRINTF("Ubidots: Pub Handler, topic='%s' (len=%u), chunk='%s', chunk_len=%u\n",
         topic, topic_len, chunk, chunk_len);
  if(chunk_len <= 0) {
    PRINTF("Ubidots: Chunk should be at least a single digit integer or string\n");
    return;
  }
  if(strncmp(topic, cmd_topic, CONFIG_SUB_CMD_TOPIC_LEN) == 0) {
    aux = strlen(DEFAULT_TOPIC_LONG) + UBIDOTS_LABEL_LEN + 1;
    if(strncmp((const char *)&topic[aux], DEFAULT_SUBSCRIBE_CMD_LEDS,
               strlen(DEFAULT_SUBSCRIBE_CMD_LEDS)) == 0) {
      PRINTF("Ubidots: Command received --> toggle LED\n");
      if(strncmp((const char *)chunk, "1", 1) == 0) {
        leds_on(CMD_LED);
      } else if(strncmp((const char *)chunk, "0", 1) == 0) {
        leds_off(CMD_LED);
      } else {
        PRINTF("Ubidots: invalid command argument (expected boolean)!\n");
      }
      return;
    } else if(strncmp((const char *)&topic[aux], DEFAULT_SUBSCRIBE_CMD_REBOOT,
               strlen(DEFAULT_SUBSCRIBE_CMD_REBOOT)) == 0) {
      PRINTF("Ubidots: Command received --> reboot\n");
      if(strncmp((const char *)chunk, "1", 1) == 0) {
        sys_ctrl_reset();
      } else {
        PRINTF("Ubidots: invalid command argument (expected only 'true')!\n");
      }
      return;
    } else if(strncmp((const char *)&topic[aux], DEFAULT_SUBSCRIBE_CMD_SENSOR,
               strlen(DEFAULT_SUBSCRIBE_CMD_SENSOR)) == 0) {
      PRINTF("Ubidots: Command received --> enable/disable sensor\n");
      if(strncmp((const char *)chunk, "1", 1) == 0) {
        activate_sensors(0x01);
      } else if(strncmp((const char *)chunk, "0", 1) == 0) {
        activate_sensors(0x00);
      } else {
        PRINTF("Ubidots: invalid command argument (expected boolean)!\n");
      }
      return;
    } else if(strncmp((const char *)&topic[aux], DEFAULT_SUBSCRIBE_CMD_EVENT,
               strlen(DEFAULT_SUBSCRIBE_CMD_EVENT)) == 0) {
      aux = atoi((const char*) chunk);
      if(mqtt_check_int_chunk_len(aux, chunk_len)) {
        PRINTF("Ubidots: chunk lenght doesn't match integer\n");
        return;
      }
      if((aux < DEFAULT_UPDATE_PERIOD_MIN) || (aux > DEFAULT_UPDATE_PERIOD_MAX)) {
        PRINTF("Ubidots: update interval should be between %u and %u\n", 
                DEFAULT_UPDATE_PERIOD_MIN, DEFAULT_UPDATE_PERIOD_MAX);
        return;
      }
      conf.pub_interval_check = aux;
      PRINTF("Ubidots: New update interval --> %u secs\n", conf.pub_interval_check);
      return;
    }
#if DEFAULT_SENSORS_NUM
    for(i=0; i<SENSORS_NAME(MQTT_SENSORS, _sensors.num); i++) {
      if((strlen(SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].sensor_config))) &&
        (strncmp((const char *)&topic[aux], SENSORS_NAME(MQTT_SENSORS, _sensors.sensor[i].sensor_config),
                      strlen(SENSORS_NAME(MQTT_SENSORS, _sensors.sensor[i].sensor_config))) == 0)) {
        aux = atoi((const char*) chunk);
        if(mqtt_check_int_chunk_len(aux, chunk_len)) {
          PRINTF("Ubidots: chunk lenght doesn't match integer\n");
          return;
        }
        if((aux < SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].min)) || 
          (aux > SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].max))) {
          PRINTF("Ubidots: %s threshold should be between %d and %d\n",
                 SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].sensor_name),
                 SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].min),
                 SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].max));
          return;
        }
        if(strstr((const char *)topic, "_thresh") != NULL) {
          SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].over_threshold) = aux;
          PRINTF("Ubidots: New %s over threshold --> %u\n",
                 SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].sensor_name),
                 SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].over_threshold));
        } else if(strstr((const char *)topic, "_thresl") != NULL) {
          SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].below_threshold) = aux;
          PRINTF("Ubidots: New %s below threshold --> %u\n",
                 SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].sensor_name),
                 SENSORS_NAME(MQTT_SENSORS,_sensors.sensor[i].below_threshold));
        } else {
          PRINTF("Ubidots: Expected threshold configuration name to end ");
          PRINTF("either in thresh or thresl\n");
        }
        return;
      }
    }
#endif 
#if DEFAULT_COMMANDS_NUM
    for(i=0; i<SENSORS_NAME(MQTT_SENSORS, _commands.num); i++) {
      if(strncmp((const char *)&topic[aux], 
          SENSORS_NAME(MQTT_SENSORS, _commands.command[i].command_name),
          strlen(SENSORS_NAME(MQTT_SENSORS, _commands.command[i].command_name))) == 0) {
        aux = atoi((const char*) chunk);
        SENSORS_NAME(MQTT_SENSORS,_commands.command[i].cmd(aux));
        return;
      }
    }
#endif 
    PRINTF("Ubidots: Configuration/Command parameter not recognized\n");
  } else {
    PRINTF("Ubidots: Incorrect topic or chunk len. Ignored\n");
  }
}
static void ubidots_pub_handler ( const char * topic , uint16_t topic_len , const uint8_t * chunk , uint16_t chunk_len ) { uint8_t i ; uint16_t aux ; PRINTF ( " \n " , topic , topic_len , chunk , chunk_len ) ; if ( chunk_len <= 0 ) { PRINTF ( " \n " ) ; return ; } if ( strncmp ( topic , cmd_topic , CONFIG_SUB_CMD_TOPIC_LEN ) == 0 ) { aux = strlen ( DEFAULT_TOPIC_LONG ) + UBIDOTS_LABEL_LEN + 1 ; if ( strncmp ( ( const char * ) & topic [ aux ] , DEFAULT_SUBSCRIBE_CMD_LEDS , strlen ( DEFAULT_SUBSCRIBE_CMD_LEDS ) ) == 0 ) { PRINTF ( " \n " ) ; if ( strncmp ( ( const char * ) chunk , " " , 1 ) == 0 ) { leds_on ( CMD_LED ) ; } else if ( strncmp ( ( const char * ) chunk , " " , 1 ) == 0 ) { leds_off ( CMD_LED ) ; } else { PRINTF ( " \n " ) ; } return ; } else if ( strncmp ( ( const char * ) & topic [ aux ] , DEFAULT_SUBSCRIBE_CMD_REBOOT , strlen ( DEFAULT_SUBSCRIBE_CMD_REBOOT ) ) == 0 ) { PRINTF ( " \n " ) ; if ( strncmp ( ( const char * ) chunk , " " , 1 ) == 0 ) { sys_ctrl_reset ( ) ; } else { PRINTF ( " \n " ) ; } return ; } else if ( strncmp ( ( const char * ) & topic [ aux ] , DEFAULT_SUBSCRIBE_CMD_SENSOR , strlen ( DEFAULT_SUBSCRIBE_CMD_SENSOR ) ) == 0 ) { PRINTF ( " \n " ) ; if ( strncmp ( ( const char * ) chunk , " " , 1 ) == 0 ) { activate_sensors ( 0x01 ) ; } else if ( strncmp ( ( const char * ) chunk , " " , 1 ) == 0 ) { activate_sensors ( 0x00 ) ; } else { PRINTF ( " \n " ) ; } return ; } else if ( strncmp ( ( const char * ) & topic [ aux ] , DEFAULT_SUBSCRIBE_CMD_EVENT , strlen ( DEFAULT_SUBSCRIBE_CMD_EVENT ) ) == 0 ) { aux = atoi ( ( const char * ) chunk ) ; if ( mqtt_check_int_chunk_len ( aux , chunk_len ) ) { PRINTF ( " \n " ) ; return ; } if ( ( aux < DEFAULT_UPDATE_PERIOD_MIN ) || ( aux > DEFAULT_UPDATE_PERIOD_MAX ) ) { PRINTF ( " \n " , DEFAULT_UPDATE_PERIOD_MIN , DEFAULT_UPDATE_PERIOD_MAX ) ; return ; } conf . pub_interval_check = aux ; PRINTF ( " \n " , conf . pub_interval_check ) ; return ; } #if DEFAULT_SENSORS_NUM for ( i = 0 ; i < SENSORS_NAME ( MQTT_SENSORS , _sensors . num ) ; i ++ ) { if ( ( strlen ( SENSORS_NAME ( MQTT_SENSORS , _sensors . sensor [ i ] . sensor_config ) ) ) && ( strncmp ( ( const char * ) & topic [ aux ] , SENSORS_NAME ( MQTT_SENSORS , _sensors . sensor [ i ] . sensor_config ) , strlen ( SENSORS_NAME ( MQTT_SENSORS , _sensors . sensor [ i ] . sensor_config ) ) ) == 0 ) ) { aux = atoi ( ( const char * ) chunk ) ; if ( mqtt_check_int_chunk_len ( aux , chunk_len ) ) { PRINTF ( " \n " ) ; return ; } if ( ( aux < SENSORS_NAME ( MQTT_SENSORS , _sensors . sensor [ i ] . min ) ) || ( aux > SENSORS_NAME ( MQTT_SENSORS , _sensors . sensor [ i ] . max ) ) ) { PRINTF ( " \n " , SENSORS_NAME ( MQTT_SENSORS , _sensors . sensor [ i ] . sensor_name ) , SENSORS_NAME ( MQTT_SENSORS , _sensors . sensor [ i ] . min ) , SENSORS_NAME ( MQTT_SENSORS , _sensors . sensor [ i ] . max ) ) ; return ; } if ( strstr ( ( const char * ) topic , " " ) != NULL ) { SENSORS_NAME ( MQTT_SENSORS , _sensors . sensor [ i ] . over_threshold ) = aux ; PRINTF ( " \n " , SENSORS_NAME ( MQTT_SENSORS , _sensors . sensor [ i ] . sensor_name ) , SENSORS_NAME ( MQTT_SENSORS , _sensors . sensor [ i ] . over_threshold ) ) ; } else if ( strstr ( ( const char * ) topic , " " ) != NULL ) { SENSORS_NAME ( MQTT_SENSORS , _sensors . sensor [ i ] . below_threshold ) = aux ; PRINTF ( " \n " , SENSORS_NAME ( MQTT_SENSORS , _sensors . sensor [ i ] . sensor_name ) , SENSORS_NAME ( MQTT_SENSORS , _sensors . sensor [ i ] . below_threshold ) ) ; } else { PRINTF ( " " ) ; PRINTF ( " \n " ) ; } return ; } } #endif #if DEFAULT_COMMANDS_NUM for ( i = 0 ; i < SENSORS_NAME ( MQTT_SENSORS , _commands . num ) ; i ++ ) { if ( strncmp ( ( const char * ) & topic [ aux ] , SENSORS_NAME ( MQTT_SENSORS , _commands . command [ i ] . command_name ) , strlen ( SENSORS_NAME ( MQTT_SENSORS , _commands . command [ i ] . command_name ) ) ) == 0 ) { aux = atoi ( ( const char * ) chunk ) ; SENSORS_NAME ( MQTT_SENSORS , _commands . command [ i ] . cmd ( aux ) ) ; return ; } } #endif PRINTF ( " \n " ) ; } else { PRINTF ( " \n " ) ; } }
DEFAULT_SENSORS_NUM
This function handler receives publications to which we are subscribed
DEFAULT_SENSORS_NUM This function handler receives publications to which we are subscribed
/* Most of the commands follow a boolean-logic at least */ /* This is a command event, it uses "1" and "0" strings for true or false
   * As default we use the "/lv" request upon subscribing, we expect an numeric
   * string as chunk
   */ /* Add an extra byte for the level separator */ /* Toggle a given LED */ /* Restart the device */ /* This is fixed to check only "true" arguments */ /* Enable or disable external sensors */ /* This is a configuration event
     * As currently Contiki's MQTT driver does not support more than one SUBSCRIBE
     * we are handling both commands and configurations in the same "cmd" topic
     * We expect the configuration payload to follow the next syntax:
     * {"name":"update_period","value":61}
     */ /* Change the update period */ /* Take integers as configuration value */ /* Check for allowed values */ // mqtt_write_config_to_flash(); /* Change a sensor's threshold, skip is `sensor_config` is empty */ /* Take integers as configuration value */ /* We have now a valid threshold value, the logic is simple: each
         * variable has a `thresh` to configure a limit over the given value,
         * and `thresl` which respectively checks for values below this limit.
         * As a convention we are expecting `sensor_config` strings ending in
         * `_thresh` or `_thresl`.  The check below "should" be "safe" as we are
         * sure it matches an expected string.
         */ /* DEFAULT_SENSORS_NUM */ /* We are now checking for any string command expected by the subscribed
     * sensor module
     */ /* Take integers as argument value */ /* Invoke the command handler */ /* DEFAULT_COMMANDS_NUM */ /* Invalid configuration topic, we should have returned before */