int main(int argc, char *argv[]) {
  // initialize the system logging
  openlog("doorstate", LOG_CONS | LOG_PID, LOG_USER);
  syslog(LOG_INFO, "Starting doorstate observer.");

  // initialize I2C
  I2C_init();
  
  // initialize MQTT
  mosquitto_lib_init();
  
  void *mqtt_obj;
  struct mosquitto *mosq;
  mosq = mosquitto_new("doorstate", true, mqtt_obj);
  if ((int)mosq == ENOMEM) {
    syslog(LOG_ERR, "Not enough memory to create a new mosquitto session.");
    mosq = NULL;
  }
  if ((int)mosq == EINVAL) {
    syslog(LOG_ERR, "Invalid values for creating mosquitto session.");
    return -1;
  }
  
  if (mosq) {
    int ret;
    
    ret = mosquitto_connect(mosq, MQTT_HOST, MQTT_PORT, 30);
    if (ret == MOSQ_ERR_SUCCESS)
      syslog(LOG_INFO, "MQTT connection to %s established.", MQTT_HOST);
      
    // TODO error handling
  }
  
  char mqtt_payload[MQTT_MSG_MAXLEN];
  
  // the known door status
  struct door_status_t before; 
  decode_door_status(doorctrl_read_status(), &before);
  
  char run=1;
  int i=0;
  while(run) {
    printf("****** %u\n", i++);

    uint8_t status = doorctrl_read_status();    
    struct door_status_t ds;
    decode_door_status(status, &ds);
    
    printf("Door status byte: 0x%02x\n", status);
    printf("Green active:\t%s\n", (ds.green_active ? "yes" : "no"));
    printf("Red active:\t%s\n", (ds.red_active ? "yes" : "no"));
    printf("Door closed:\t%s\n", (ds.door_closed ? "yes" : "no"));
    printf("Lock open:\t%s\n", (ds.lock_open ? "yes" : "no"));
    printf("Force closed:\t%s\n", (ds.force_close ? "yes" : "no"));
    printf("Force open:\t%s\n", (ds.force_open ? "yes" : "no"));
    printf("\n");

    // Check door status for changes and emit MQTT messages
    mqtt_payload[0] = 0;

    // door status changed
    if (before.door_closed != ds.door_closed) {
      if (ds.door_closed) {
        syslog(LOG_INFO, "Door has been closed.");
        //MQTT message
        strcpy(mqtt_payload, MQTT_MSG_DOORCLOSE);
      } else {
        syslog(LOG_INFO, "Door has been opened.");
        //MQTT message
        strcpy(mqtt_payload, MQTT_MSG_DOOROPEN);
      }
      
      before.door_closed = ds.door_closed;
    }

    // lock status changed
    if (before.lock_open != ds.lock_open) {
      if (ds.lock_open) {
        syslog(LOG_INFO, "Door has been unlocked.");
        //MQTT message
        strcpy(mqtt_payload, MQTT_MSG_LOCKOPEN);
      } else {
        syslog(LOG_INFO, "Door has been locked.");
        //MQTT message
        strcpy(mqtt_payload, MQTT_MSG_LOCKCLOSE);
      }
      
      before.lock_open = ds.lock_open;
    }

    // send MQTT messages if there is payload
    mqtt_send(mosq, mqtt_payload, MQTT_TOPIC);
    mqtt_payload[0] = 0;
    
    // green button status changed
    if (before.green_active != ds.green_active) {
      if (ds.green_active) {
        syslog(LOG_INFO, "Green button active.");
        //MQTT message
        strcpy(mqtt_payload, MQTT_MSG_BTNGREEN);
      }
      // only button activation is an event
      before.green_active = ds.green_active;
    }

    // send MQTT messages if there is payload
    mqtt_send(mosq, mqtt_payload, MQTT_TOPIC_BTN);
    mqtt_payload[0] = 0;

    // red button status changed
    if (before.red_active != ds.red_active) {
      if (ds.red_active) {
        syslog(LOG_INFO, "Red button active.");
        //MQTT message
        strcpy(mqtt_payload, MQTT_MSG_BTNRED);
      }
      // only button activation is an event
      before.red_active = ds.red_active;
    }

    // send MQTT messages if there is payload
    mqtt_send(mosq, mqtt_payload, MQTT_TOPIC_BTN);

    // call the mosquitto loop to process messages
    if (mosq) {
      int ret;
      ret = mosquitto_loop(mosq, 100, 1);
      // if failed, try to reconnect
      if (ret)
        mosquitto_reconnect(mosq);
    }

    //I3C_reset_doorctrl();
    
    if (sleep(1)) 
      break;
  }

  // clean-up MQTT
  if (mosq) {
    mosquitto_disconnect(mosq);
    mosquitto_destroy(mosq);
  }
  mosquitto_lib_cleanup();

  syslog(LOG_INFO, "Doorstate observer finished.");
  closelog();
    
  return 0;
}
Exemple #2
0
mqtt_err_t mqtt_sendConnect(mqtt_client_t *client)
{

    mqtt_msg_t *msg = mqtt_createMsg(80);//FIXME: Fix the length to be correct based on values
    uint8_t *buf;
    printf("sending Connect for:%s\n", client->name);

    buf = msg->pkt;

    msg->fHdr.bits.msg_type = CONNECT;
    msg->fHdr.bits.dup_flag = 0;
    msg->fHdr.bits.qos = 0;
    msg->fHdr.bits.retain = 0;
    *buf++ = msg->fHdr.firstByte;

    //printf("Fixed Header first byte: 0x%X for %s\n", msg->fHdr.firstByte, client->name);
    //TODO: fix to a dynamic len right now it has to have a constant client ID len
    msg->fHdr.pkt_len = (44); //client id + variable header + client id len
    *buf++ = msg->fHdr.pkt_len;
    if(user_flag)
    {
        msg->vHdr.bits.user_flag = 1;
        //TODO: add username and password code
        if(pass_flag)
        {
            msg->vHdr.bits.pass_flag = 1;
        }
    }

    /*******************************************
     * Variable Header
     ******************************************/

    /* Protocol */
    buf += mqtt_stringToUtf("MQIsdp", buf);

    /* Version */
    *buf++ = 3;

    //TODO: change clean session to be selectable
    msg->vHdr.bits.pass_flag = 0;
    msg->vHdr.bits.user_flag = 0;
    if(client->will)
    {
        msg->vHdr.bits.will_flag = 1;
        msg->vHdr.bits.will_qos = client->will->qos;
        msg->vHdr.bits.will_retain = 0;
    }
    else
    {
        msg->vHdr.bits.will_flag = 0;
        msg->vHdr.bits.will_qos = 0;
        msg->vHdr.bits.will_retain = 0;
    }

    msg->vHdr.bits.clean_session = 1;
    *buf++ = msg->vHdr.firstbyte;

    /* Keep Alive */
    uint32_t toSec = client->keepalive / 1000;
    *buf++ = (uint8_t)(0xff & (toSec >> 8));
    *buf++ = 0xff & toSec;

    /* order the variable header must be in
     * client ID
     * will topic
     * will message
     * username
     * password */

    //TODO Add user authentication
    buf += mqtt_stringToUtf(client_id, buf);//FIXME and variable client ID

    if(client->will)
    {
        buf += mqtt_stringToUtf(client->will->topic, buf);
        buf += mqtt_stringToUtf(client->will->message, buf);
    }
    msg->len = buf - msg->pkt;

    mqtt_send(client, msg);

    /* wait for connack for 5s */
    if(mqtt_waitForConnAck(client, 10000))
    {
        printf("mqtt: server timeout\n");
    }

    //TODO: Add error code handler after we attempt to connect

    //TODO: I might start the thread here
    return mqtt_errSuccess;
}