int serialport_send(int fd, const char* str) { static struct timeval t1; static int init_t1 = 1; struct timeval t2; long lastSend; if (init_t1) { init_t1 = 0; gettimeofday(&t1, NULL); return serialport_printlf(fd, str); } gettimeofday(&t2, NULL); lastSend = (((t2.tv_sec - t1.tv_sec)*1000000) + (t2.tv_usec - t1.tv_usec)); // usec if (lastSend < 50000) { usleep(50000 - lastSend); } gettimeofday(&t1, NULL); return serialport_printlf(fd, str); }
void signal_usr(int sd, struct mosquitto *mosq) { struct device *md_dev; struct module *md; char md_id[DEVICE_MD_ID_SIZE + 1]; if (user_signal == MODULE_SIGUSR1) { if (config.remap_usr1) strcpy(md_id, config.remap_usr1); else strcpy(md_id, MODULE_SIGUSR1_ID); } else if (user_signal == MODULE_SIGUSR2) { if (config.remap_usr2) strcpy(md_id, config.remap_usr2); else strcpy(md_id, MODULE_SIGUSR2_ID); } md = device_get_module(&bridge, md_id); if (md) { md_dev = device_get(&bridge, md->device); if (!md_dev) { fprintf(stderr, "Error: Orphan module.\n"); device_remove_module(&bridge, md_id); user_signal = 0; return; } if (md_dev->md_deps->type == MODULE_SERIAL && bridge.serial_ready) { snprintf(gbuf, GBUF_SIZE, "%s%s,%d,%s", SERIAL_INIT_MSG, md_dev->id, PROTO_MD_RAW, md->id); serialport_printlf(sd, gbuf); } if (connected) mqtt_publish(mosq, md->topic, "1"); } user_signal = 0; }
void bridge_message(struct mosquitto *mosq, int sd, struct device *dev, char *msg) { char md_id[DEVICE_MD_ID_SIZE + 1]; struct module *md; struct device *target_dev; int code, i; if (config.debug > 2) printf("Bridge - message: %s\n", msg); if (!getInt(&msg, &code)) { if (config.debug > 1) printf("MQTT - Invalid data.\n"); return; } switch (code) { case PROTO_ERROR: case PROTO_ACK: case PROTO_NACK: case PROTO_ST_TIMEOUT: case PROTO_DEVICE: return; case PROTO_ST_ALIVE: if (!getInt(&msg, &code)) return; if (dev->modules == code) return; dev->modules = code; // no return here is purposeful case PROTO_ST_MODULES_UP: // Modules Update if (dev->type == DEVICE_TYPE_NODE) { // Message from a serial device if (dev->md_deps->type == MODULE_SERIAL && bridge.serial_ready) { snprintf(gbuf, GBUF_SIZE, "%s%s,%d", SERIAL_INIT_MSG, dev->id, PROTO_GET_MODULES); serialport_printlf(sd, gbuf); } // Message from a MQTT device else if (dev->md_deps->type == MODULE_MQTT) { snprintf(gbuf, GBUF_SIZE, "%s,%d", bridge.id, PROTO_GET_MODULES); mqtt_publish(mosq, dev->topic, gbuf); return; } } return; case PROTO_GET_MODULES: // Message from a MQTT device if (dev->md_deps->type == MODULE_MQTT) { for (md = bridge.module; md != NULL; md = md->next) { snprintf(gbuf, GBUF_SIZE, "%s,%d,%s,%s,%d", bridge.id, PROTO_MODULE, md->id, md->device, md->enabled); mqtt_publish(mosq, dev->topic, gbuf); } } return; case PROTO_GET_DEVICES: // Message from a MQTT device if (dev->md_deps->type == MODULE_MQTT) { for (i = 0; i < bridge.devices_len; i++) { target_dev = &bridge.devices[i]; snprintf(gbuf, GBUF_SIZE, "%s,%d,%s,%d,%d" , bridge.id, PROTO_DEVICE, target_dev->id, target_dev->modules, target_dev->alive); mqtt_publish(mosq, dev->topic, gbuf); } } return; case PROTO_SAVE_DEVICE: target_dev = device_get(&bridge, msg); if (!target_dev) return; if (config.debug > 1) { printf("Saving device:\n"); device_print_device(target_dev); } device_save(&bridge, config.devices_folder, target_dev); return; } if (!getString(&msg, md_id, DEVICE_MD_ID_SIZE, ',')) { if (config.debug > 1) printf("Missing module id - code: %d\n", code); return; } if (!device_isValid_md_id(md_id)) { if (config.debug > 1) printf("Invalid module id - code: %d\n", code); return; } md = device_get_module(&bridge, md_id); if (code == PROTO_MODULE) { if (!md) { if (device_add_module(&bridge, md_id, dev->id) == -1) { run = 0; return; } if (config.debug > 1) { md = device_get_module(&bridge, md_id); printf("New Module:\n"); device_print_module(md); } } return; } if (!md) return; target_dev = device_get(&bridge, md->device); if (!target_dev) { fprintf(stderr, "Error: Orphan module.\n"); device_remove_module(&bridge, md_id); return; } switch (code) { case PROTO_GET_MODULE: // Message from a MQTT device if (dev->md_deps->type == MODULE_MQTT) { snprintf(gbuf, GBUF_SIZE, "%s,%d,%s,%s,%d", bridge.id, PROTO_MODULE, md->id, md->device, md->enabled); mqtt_publish(mosq, dev->topic, gbuf); } return; case PROTO_MD_GET_TOPIC: // Message from a MQTT device if (dev->md_deps->type == MODULE_MQTT) { snprintf(gbuf, GBUF_SIZE, "%s,%d,%s,%s", bridge.id, PROTO_MD_TOPIC, md->id, md->topic); mqtt_publish(mosq, dev->topic, gbuf); } return; case PROTO_MD_SET_TOPIC: case PROTO_MD_TOPIC: code = device_set_md_topic(md, msg); if (code == -1) { // Memory problem run = 0; return; } if (code == 0) { // Module topic changed snprintf(gbuf, GBUF_SIZE, "%d,%s,%s", PROTO_MD_TOPIC, md->id, md->topic); mqtt_publish(mosq, bridge.status_topic, gbuf); } return; case PROTO_MD_RAW: mqtt_publish(mosq, md->topic, msg); return; case PROTO_MD_TO_RAW: // Target module at serial if (target_dev->md_deps->type == MODULE_SERIAL && bridge.serial_ready) { snprintf(gbuf, GBUF_SIZE, "%s%s,%d,%s,%s", SERIAL_INIT_MSG, target_dev->id, PROTO_MD_TO_RAW, md->id, msg); serialport_printlf(sd, gbuf); } // Target module at MQTT else if (target_dev->md_deps->type == MODULE_MQTT) { snprintf(gbuf, GBUF_SIZE, "%s,%d,%s,%s", bridge.id, PROTO_MD_TO_RAW, md->id, msg); mqtt_publish(mosq, target_dev->topic, gbuf); } else if (!strcmp(md->device, bridge.id)) { if (md->type == MODULE_SCRIPT) { code = run_script(config.scripts_folder, msg, gbuf, GBUF_SIZE, config.debug); if (code == -1) { run = 0; } else if (code == 1) { mqtt_publish(mosq, md->topic, "0"); } else if (code == 0) { if (strlen(gbuf) > 0) { if (config.debug > 1) printf("Script output:\n-\n%s\n-\n", gbuf); mqtt_publish(mosq, md->topic, gbuf); } else { mqtt_publish(mosq, md->topic, "1"); } } } else if (md->type == MODULE_BANDWIDTH) { if (bandwidth) { if (mqtt_publish_bandwidth(mosq, md->topic) == -1) run = 0; } } else if (md->type == MODULE_SERIAL) { snprintf(gbuf, GBUF_SIZE, "%d", bridge.serial_ready); mqtt_publish(mosq, md->topic, gbuf); } } return; case PROTO_MD_ENABLE: //TODO: implement case PROTO_MD_GET_ENABLE: //TODO: implement case PROTO_MD_SET_ENABLE: //TODO: implement return; default: if (config.debug > 2) printf("Bridge - code: %d - Not treated.\n", code); } }