int main(int argc, char *argv[]) { int sd = -1; char *conf_file = NULL; struct mosquitto *mosq; struct module *md; struct device *dev; int rc; int i; gbuf[0] = 0; if (!quiet) printf("Version: %s\n", version); signal(SIGINT, handle_signal); signal(SIGTERM, handle_signal); signal(SIGUSR1, handle_signal); signal(SIGUSR2, handle_signal); signal(SIGALRM, each_sec); for (i=1; i<argc; i++) { if(!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config")){ if(i==argc-1){ fprintf(stderr, "Error: -c argument given but no file specified.\n\n"); print_usage(argv[0]); return 1; }else{ conf_file = argv[i+1]; } i++; }else if(!strcmp(argv[i], "--quiet")){ quiet = true; }else{ fprintf(stderr, "Error: Unknown option '%s'.\n",argv[i]); print_usage(argv[0]); return 1; } } if (!conf_file) { fprintf(stderr, "Error: No config file given.\n"); return 1; } memset(&config, 0, sizeof(struct bridge_config)); if (config_parse(conf_file, &config)) return 1; if (quiet) config.debug = 0; if (config.debug != 0) printf("Debug: %d\n", config.debug); rc = bridge_init(&bridge, config.id, MODULES_BRIDGE_ID); if (rc) { if (config.debug) printf("Error: Failed to initialize bridge: %d\n", rc); return 1; } mosquitto_lib_init(); mosq = mosquitto_new(config.id, true, NULL); if(!mosq){ fprintf(stderr, "Error creating mqtt instance.\n"); switch(errno){ case ENOMEM: fprintf(stderr, " out of memory.\n"); break; case EINVAL: fprintf(stderr, " invalid id.\n"); break; } return 1; } snprintf(gbuf, GBUF_SIZE, "%d", PROTOCOL_TIMEOUT); mosquitto_will_set(mosq, bridge.bridge_dev->status_topic, strlen(gbuf), gbuf, config.mqtt_qos, MQTT_RETAIN); mosquitto_connect_callback_set(mosq, on_mqtt_connect); mosquitto_disconnect_callback_set(mosq, on_mqtt_disconnect); mosquitto_message_callback_set(mosq, on_mqtt_message); mosquitto_user_data_set(mosq, &sd); md = bridge_add_module(bridge.bridge_dev, MODULES_MQTT_ID, true); if (!md) { fprintf(stderr, "Failed to add MQTT module.\n"); return 1; } if (config.scripts_folder) { if (access(config.scripts_folder, R_OK )) { fprintf(stderr, "Couldn't open scripts folder: %s\n", config.scripts_folder); return 1; } md = bridge_add_module(bridge.bridge_dev, MODULES_SCRIPT_ID, true); if (!md) { fprintf(stderr, "Failed to add script module.\n"); return 1; } } if (config.interface) { //TODO: check if interface exists if (access("/proc/net/dev", R_OK )) { fprintf(stderr, "Couldn't open /proc/net/dev\n"); return 1; } md = bridge_add_module(bridge.bridge_dev, MODULES_BANDWIDTH_ID, true); if (!md) { fprintf(stderr, "Failed to add bandwidth module.\n"); return 1; } bandwidth = true; } if (config.serial.port) { sd = serialport_init(config.serial.port, config.serial.baudrate); if( sd == -1 ) { fprintf(stderr, "Couldn't open serial port.\n"); return 1; } else { md = bridge_add_module(bridge.bridge_dev, MODULES_SERIAL_ID, true); if (!md) { fprintf(stderr, "Failed to add serial module.\n"); return 1; } serialport_flush(sd); bridge.serial_ready = true; if (config.debug) printf("Serial ready.\n"); } } if (config.debug > 2) bridge_print_modules(bridge.bridge_dev); rc = mosquitto_connect(mosq, config.mqtt_host, config.mqtt_port, 60); if (rc) { fprintf(stderr, "ERROR: %s\n", mosquitto_strerror(rc)); return -1; } alarm(1); while (run) { if (bridge.serial_ready) { rc = serial_in(sd, mosq, MODULES_SERIAL_ID); if (rc == -1) { serial_hang(mosq); } else if (rc > 0) { bridge.serial_alive = DEVICE_ALIVE_MAX; } } if (user_signal) { if (config.debug > 2) printf("Signal - SIGUSR: %d\n", user_signal); signal_usr(sd, mosq); } rc = mosquitto_loop(mosq, 100, 1); if (run && rc) { if (config.debug > 2) printf("MQTT loop: %s\n", mosquitto_strerror(rc)); usleep(100000); // wait 100 msec mosquitto_reconnect(mosq); } usleep(20); if (every1s) { every1s = false; for (dev = bridge.dev_list; dev != NULL; dev = dev->next) { if (dev->alive) { dev->alive--; if (!dev->alive) { if (connected) { snprintf(gbuf, GBUF_SIZE, "%d", PROTOCOL_TIMEOUT); mqtt_publish(mosq, dev->status_topic, gbuf); rc = mosquitto_unsubscribe(mosq, NULL, dev->config_topic); if (rc) fprintf(stderr, "Error: MQTT unsubscribe returned: %s\n", mosquitto_strerror(rc)); } if (config.debug) printf("Device: %s - Timeout.\n", dev->id); bridge_remove_device(&bridge, dev->id); } } } } if (every30s) { every30s = false; if (connected) { send_alive(mosq); if (bandwidth) { md = bridge_get_module(bridge.bridge_dev, MODULES_BANDWIDTH_ID); if (md) { snprintf(gbuf, GBUF_SIZE, "%.0f,%.0f", upspeed, downspeed); mqtt_publish(mosq, md->topic, gbuf); if (config.debug > 2) printf("down: %f - up: %f\n", downspeed, upspeed); } } } else { if (config.debug) printf("MQTT Offline.\n"); } if (bridge.serial_alive) { bridge.serial_alive--; if (!bridge.serial_alive) { if (config.debug > 1) printf("Serial timeout.\n"); serial_hang(mosq); } } else { if (config.serial.port && !bridge.serial_ready) { if (config.debug > 1) printf("Trying to reconnect serial port.\n"); serialport_close(sd); sd = serialport_init(config.serial.port, config.serial.baudrate); if( sd == -1 ) { fprintf(stderr, "Couldn't open serial port.\n"); } else { serialport_flush(sd); bridge.serial_ready = true; snprintf(gbuf, GBUF_SIZE, "%d", MODULES_SERIAL_OPEN); mqtt_publish(mosq, md->topic, gbuf); if (config.debug) printf("Serial reopened.\n"); } } } } } if (bridge.serial_ready) { serialport_close(sd); } mosquitto_destroy(mosq); mosquitto_lib_cleanup(); config_cleanup(&config); printf("Exiting..\n\n"); return 0; }
void mosquittopp::user_data_set(void *userdata) { mosquitto_user_data_set(m_mosq, userdata); }
int main(int argc, char *argv[]) { int sd = -1; char *conf_file = NULL; struct mosquitto *mosq; struct module *md; struct device *dev; int rc; int i; if (!quiet) printf("Version: %s\n", version); signal(SIGINT, handle_signal); signal(SIGTERM, handle_signal); signal(SIGUSR1, handle_signal); signal(SIGUSR2, handle_signal); signal(SIGALRM, each_sec); for (i=1; i<argc; i++) { if(!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config")){ if(i==argc-1){ fprintf(stderr, "Error: -c argument given but no file specified.\n\n"); print_usage(argv[0]); return 1; }else{ conf_file = argv[i+1]; } i++; }else if(!strcmp(argv[i], "--quiet")){ quiet = true; }else{ fprintf(stderr, "Error: Unknown option '%s'.\n",argv[i]); print_usage(argv[0]); return 1; } } if(!conf_file) { fprintf(stderr, "Error: No config file given.\n"); return 1; } memset(&config, 0, sizeof(struct bridge_config)); if(config_parse(conf_file, &config)) return 1; if (quiet) config.debug = 0; if (config.debug != 0) printf("Debug: %d\n", config.debug); if (!device_isValid_id(config.id)) { fprintf(stderr, "Invalid id.\n"); return -1; } if (device_init(&bridge, config.id) == -1) return 1; mosquitto_lib_init(); mosq = mosquitto_new(config.id, true, NULL); if(!mosq){ fprintf(stderr, "Error creating mqtt instance.\n"); switch(errno){ case ENOMEM: fprintf(stderr, " out of memory.\n"); break; case EINVAL: fprintf(stderr, " invalid id.\n"); break; } return 1; } snprintf(gbuf, GBUF_SIZE, "%d", PROTO_ST_TIMEOUT); mosquitto_will_set(mosq, bridge.status_topic, strlen(gbuf), gbuf, config.mqtt_qos, MQTT_RETAIN); mosquitto_connect_callback_set(mosq, on_mqtt_connect); mosquitto_disconnect_callback_set(mosq, on_mqtt_disconnect); mosquitto_message_callback_set(mosq, on_mqtt_message); mosquitto_user_data_set(mosq, &sd); if (config.debug > 1) printf("Subscribe topic: %s\n", bridge.config_topic); rc = device_add_module(&bridge, MODULE_MQTT_ID, bridge.id); //TODO: autogen id? if (rc) { fprintf(stderr, "Failed to add mqtt module.\n"); return 1; } if (config.scripts_folder) { if (access(config.scripts_folder, R_OK )) { fprintf(stderr, "Couldn't open scripts folder: %s\n", config.scripts_folder); return 1; } rc = device_add_module(&bridge, MODULE_SCRIPT_ID, bridge.id); //TODO: autogen id? if (rc) { fprintf(stderr, "Failed to add script module.\n"); return 1; } } if (config.interface) { //TODO: check if interface exists if (access("/proc/net/dev", R_OK )) { fprintf(stderr, "Couldn't open /proc/net/dev\n"); return 1; } rc = device_add_module(&bridge, MODULE_BANDWIDTH_ID, bridge.id); //TODO: autogen id? if (rc) { fprintf(stderr, "Failed to add bandwidth module.\n"); return 1; } bandwidth = true; } if (config.serial.port) { sd = serialport_init(config.serial.port, config.serial.baudrate); if( sd == -1 ) { fprintf(stderr, "Couldn't open serial port.\n"); return 1; } else { rc = device_add_module(&bridge, MODULE_SERIAL_ID, bridge.id); //TODO: autogen id? if (rc) { fprintf(stderr, "Failed to add serial module.\n"); return 1; } serialport_flush(sd); bridge.serial_ready = true; if (config.debug) printf("Serial ready.\n"); } } rc = device_add_module(&bridge, MODULE_SIGUSR1_ID, bridge.id); //TODO: autogen id? if (rc) { fprintf(stderr, "Failed to add sigusr1 module.\n"); return 1; } rc = device_add_module(&bridge, MODULE_SIGUSR2_ID, bridge.id); //TODO: autogen id? if (rc) { fprintf(stderr, "Failed to add sigusr2 module.\n"); return 1; } device_print_modules(&bridge); rc = mosquitto_connect(mosq, config.mqtt_host, config.mqtt_port, 60); if (rc) { fprintf(stderr, "Wrong MQTT parameters. Check your config.\n"); return -1; } alarm(1); while (run) { if (bridge.serial_ready) { rc = serial_in(sd, mosq, MODULE_SERIAL_ID); if (rc == -1) { serial_hang(mosq); } else if (rc > 0) { bridge.serial_alive = ALIVE_CNT; } } if (user_signal) { if (config.debug > 1) printf("Signal - SIGUSR: %d\n", user_signal); signal_usr(sd, mosq); } rc = mosquitto_loop(mosq, -1, 1); if (run && rc) { if (config.debug > 2) printf("MQTT loop: %s\n", mosquitto_strerror(rc)); usleep(100000); // wait 100 msec mosquitto_reconnect(mosq); } if (every30s) { every30s = false; bridge.controller = false; for (i = 0; i < bridge.devices_len; i++) { dev = &bridge.devices[i]; if (dev->alive) { dev->alive--; if (!dev->alive) { snprintf(gbuf, GBUF_SIZE, "%d,%s", PROTO_ST_TIMEOUT, dev->id); mqtt_publish(mosq, bridge.status_topic, gbuf); if (dev->md_deps->type == MODULE_MQTT && dev->type == DEVICE_TYPE_NODE) { snprintf(gbuf, GBUF_SIZE, "status/%s", dev->id); rc = mosquitto_unsubscribe(mosq, NULL, gbuf); if (rc) fprintf(stderr, "Error: MQTT unsubscribe returned: %s\n", mosquitto_strerror(rc)); } if (config.debug) printf("Device timeout - id: %s\n", dev->id); } else { if (dev->type == DEVICE_TYPE_CONTROLLER) bridge.controller = true; } } } if (!bridge.controller) bridge.modules_update = false; if (connected) { snprintf(gbuf, GBUF_SIZE, "%d,%d", PROTO_ST_ALIVE, bridge.modules_len); mqtt_publish(mosq, bridge.status_topic, gbuf); if (bridge.modules_update) { snprintf(gbuf, GBUF_SIZE, "%d", PROTO_ST_MODULES_UP); if (mqtt_publish(mosq, bridge.status_topic, gbuf)) bridge.modules_update = false; } if (bandwidth) { md = device_get_module(&bridge, MODULE_BANDWIDTH_ID); if (md) { if (mqtt_publish_bandwidth(mosq, md->topic) == -1) break; } } } else { if (config.debug != 0) printf("MQTT Offline.\n"); } if (bridge.serial_alive) { bridge.serial_alive--; if (!bridge.serial_alive) { if (config.debug > 1) printf("Serial timeout.\n"); serial_hang(mosq); } } else { if (config.serial.port && !bridge.serial_ready) { if (config.debug > 1) printf("Trying to reconnect serial port.\n"); serialport_close(sd); sd = serialport_init(config.serial.port, config.serial.baudrate); if( sd == -1 ) fprintf(stderr, "Couldn't open serial port.\n"); else { serialport_flush(sd); bridge.serial_ready = true; if (config.debug) printf("Serial reopened.\n"); } } } } usleep(20); } if (bridge.serial_ready) { serialport_close(sd); } mosquitto_destroy(mosq); mosquitto_lib_cleanup(); config_cleanup(&config); printf("Exiting..\n\n"); return 0; }