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; }
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; }