static void mosq_ev_io(evutil_socket_t fd, short what, void *arg) { (void)fd; int rc; struct _squash *st = arg; if (what & EV_READ) { rc = mosquitto_loop_read(st->mosq, 1); if (MOSQ_ERR_SUCCESS != rc) { mosq_reconnect(st); return; } } if (what & EV_TIMEOUT) { rc = mosquitto_loop_misc(st->mosq); if (MOSQ_ERR_SUCCESS != rc) { mosq_reconnect(st); return; } } if (what & EV_WRITE) { rc = mosquitto_loop_write(st->mosq, 1); if (MOSQ_ERR_SUCCESS != rc) { mosq_reconnect(st); return; } } /* Only get to here if the other routines passed ok */ if (mosquitto_want_write(st->mosq)) { event_add(st->mosq_write, NULL); } }
static int ctx_want_write(lua_State *L) { ctx_t *ctx = ctx_check(L, 1); lua_pushboolean(L, mosquitto_want_write(ctx->mosq)); return 1; }
bool mosq_setup(struct _squash *st) { mosquitto_lib_init(); DLOG("mosquitto -> (re)connecting\n"); st->mosq = mosquitto_new(NULL, true, st); mosquitto_log_callback_set(st->mosq, mosq_logger); mosquitto_message_callback_set(st->mosq, st->msg_handler); int rc = mosquitto_connect(st->mosq, st->mq_host, 1883, 60); if (MOSQ_ERR_SUCCESS != rc) { WLOG("Failed to connect: %s\n", strerror(errno)); rc = -1; goto unwind; } int mosq_fd = mosquitto_socket(st->mosq); if (evutil_make_socket_nonblocking(mosq_fd)) { WLOG("Failed to make non-blocking: fd = %d, possibly ok\n", mosq_fd); } st->mosq_readidle = event_new(st->base, mosq_fd, EV_READ|EV_PERSIST, mosq_ev_io, st); if (st->mosq_readidle == NULL) { WLOG("Failed to create mosquitto read/idle watcher\n"); rc = -1; goto unwind_readidle; } st->mosq_write = event_new(st->base, mosq_fd, EV_WRITE, mosq_ev_io, st); if (st->mosq_write == NULL) { WLOG("Failed to create mosquitto write watcher\n"); rc = -1; goto unwind_write; } if (mosquitto_want_write(st->mosq)) { event_add(st->mosq_write, NULL); } struct timeval mosq_idle_loop_time = { 0, 100 * 1000 }; if (event_add(st->mosq_readidle, &mosq_idle_loop_time) < 0) { WLOG("Failed to activate mosquitto watcher\n"); rc = -1; goto unwind_write; } goto out; unwind_write: event_free(st->mosq_write); unwind_readidle: event_free(st->mosq_readidle); unwind: mosquitto_destroy(st->mosq); mosquitto_lib_cleanup(); out: return rc == 0; }
void auth_mqtt_select_setup(fd_set *read_set, fd_set *write_set, int *max_fd) { int fd = auth_mqtt_fd(); if (fd != INVALID_SOCKET) { FD_SET(fd, read_set); if (*max_fd < fd) { *max_fd = fd; } if (mosquitto_want_write(auth_mqtt_mosq)) { FD_SET(fd, write_set); } } }
static void mqtt_timeout_cb(struct ev_loop *loop, struct ev_io *w, int revents) { ev_timer_helper_t *watcher = (ev_timer_helper_t *)w; mqtt_context_t *mqttctx = (mqtt_context_t *)watcher->userdata; if (EV_TIMEOUT & revents) { if (mqttctx->connected) { if (MOSQ_ERR_SUCCESS != mosquitto_loop_misc(mqttctx->mosq)) { LOG_ERROR("mosquitto_loop_misc fail"); mqtt_disconnect(mqttctx); } #if LIBMOSQUITTO_VERSION_NUMBER > 1000000 if (mosquitto_want_write(mqttctx->mosq)) #endif ev_io_start(g_srvctx.loop, &mqttctx->write_watcher.io); } } }
static void mqtt_ev_cb(struct ev_loop *loop, ev_io *w, int revents) { ev_io_helper_t *watcher = (ev_io_helper_t *)w; mqtt_context_t *mqttctx = (mqtt_context_t *)watcher->userdata; if (EV_READ & revents) { if (MOSQ_ERR_SUCCESS != mosquitto_loop_read(mqttctx->mosq #if LIBMOSQUITTO_VERSION_NUMBER > 1000000 , 1 #endif )) { LOG_ERROR("read fail"); mqtt_disconnect(mqttctx); } } if (EV_WRITE & revents) { if (MOSQ_ERR_SUCCESS != mosquitto_loop_write(mqttctx->mosq #if LIBMOSQUITTO_VERSION_NUMBER > 1000000 , 1 #endif )) { LOG_ERROR("write fail"); mqtt_disconnect(mqttctx); } #if LIBMOSQUITTO_VERSION_NUMBER > 1000000 if (!mosquitto_want_write(mqttctx->mosq)) #endif ev_io_stop(g_srvctx.loop, &mqttctx->write_watcher.io); } }
bool mosquittopp::want_write() { return mosquitto_want_write(m_mosq); }
int main(int argc, char *argv[]) { int pid, opt, ret, running, keepalive; int baudrate; bool clean_session; struct mosquitto *mosq = NULL; char uart[MAX_BUFFER]; char broker[MAX_BUFFER]; clean_session = true; running = 1; clean_session = true; background = 0; keepalive = 5; baudrate = 9600; memset(topic, 0, sizeof(topic)); memset(broker, 0, sizeof(broker)); memcpy(broker, mqtt_broker_host, strlen(mqtt_broker_host)); while ((opt = getopt(argc, argv, "b:d:s:t:fh?")) != -1) { switch (opt) { case 'd': strncpy(uart, optarg, sizeof(uart) - 1); break; case 's': baudrate = atoi(optarg); break; case 'b': strncpy(broker, optarg, sizeof(broker) - 1); break; case 't': strncpy(topic, optarg, sizeof(topic) - 1); break; case 'f': background = 1; break; case 'h': case '?': print_usage(basename(argv[0])); exit(EXIT_SUCCESS); break; default: fprintf(stderr, "Unknown option %c\n", opt); print_usage(basename(argv[0])); exit(EXIT_FAILURE); } } mosquitto_lib_init(); mosq = mosquitto_new(NULL, clean_session, NULL); if (!mosq) { fprintf(stderr, "Error: Out of memory.\n"); return (EXIT_FAILURE); } /* daemonize the process if requested */ if (background) { /* fork off the parent process */ pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } /* if we got a good PID, then we can exit the parent process */ if (pid > 0) { printf("Going into background ...\n"); exit(EXIT_SUCCESS); } } snprintf(topic_in, MAX_BUFFER - 3, "%s/in", topic); pfd[1].fd = openDevice(uart, serial_speed(baudrate)); if (pfd[1].fd <= 0) exit(EXIT_FAILURE); printf("open serial device fd : %d\n", pfd[1].fd); mosquitto_connect_callback_set(mosq, mqtt_cb_connect); mosquitto_message_callback_set(mosq, mqtt_cb_msg); mosquitto_subscribe_callback_set(mosq, mqtt_cb_subscribe); mosquitto_disconnect_callback_set(mosq, mqtt_cb_disconnect); if (!background) mosquitto_log_callback_set(mosq, mqtt_cb_log); // we try until we succeed, or we killed while (running) { if (mosquitto_connect(mosq, broker, mqtt_broker_port, keepalive)) { printf("Unable to connect, host: %s, port: %d\n", broker, mqtt_broker_port); sleep(2); continue; } break; } // pfd[0] is for the mosquitto socket, pfd[1] is for UART, or any // other file descriptor we need to handle // pfd[1].fd = 0; pfd[1].events = POLLIN; //these 2 won't change, so enough to set it once const int nfds = sizeof(pfd) / sizeof(struct pollfd); while (running) { // this might change (when reconnecting for example) // so better check it always int mosq_fd = mosquitto_socket(mosq); pfd[0].fd = mosq_fd; pfd[0].events = POLLIN; // we check whether libmosquitto wants to write, and if yes, we // also register the POLLOUT event for poll, so it will return // when it's possible to write to the socket. if (mosquitto_want_write(mosq)) { printf("Set POLLOUT\n"); pfd[0].events |= POLLOUT; } // we set the poll()-s timeout here to the half // of libmosquitto's keepalive value, to stay on the safe side if (poll(pfd, nfds, keepalive / 2 * 1000) < 0) { printf("Poll() failed with <%s>, exiting", strerror(errno)); return EXIT_FAILURE; } // first checking the mosquitto socket // if we supposed to write: if (pfd[0].revents & POLLOUT) { mosquitto_loop_write(mosq, 1); } // or read: if (pfd[0].revents & POLLIN) { ret = mosquitto_loop_read(mosq, 1); if (ret == MOSQ_ERR_CONN_LOST) { printf("reconnect...\n"); mosquitto_reconnect(mosq); } } // we call the misc() funtion in both cases mosquitto_loop_misc(mosq); // checking if there is data on the UART, if yes, reading it // and publish if (pfd[1].revents & POLLIN) { char input[64]; memset(input, 0, sizeof(input)); ret = read(pfd[1].fd, input, 64); if (ret < 0) { fprintf(stderr, "%s: read_error\n", __func__); exit(EXIT_FAILURE); } printf("%s: %s", uart, input); mosquitto_publish(mosq, NULL, topic_in, strlen(input), input, 0, false); } } mosquitto_destroy(mosq); mosquitto_lib_cleanup(); printf("bye\n"); return EXIT_SUCCESS; }