static void mqtt_misc(void* userdata) { mqtt_t inst = (mqtt_t) userdata; int rval; int fd; if (inst->connected == 0) { inst->reconnect_timer++; inst->reconnect_timer %= 20; if (inst->reconnect_timer == 0) { rval = mosquitto_reconnect(inst->mosq); if (rval != MOSQ_ERR_SUCCESS) { error("Cannot reconnect mosquitto: %s", mosquitto_strerror(rval)); } else { fd = mosquitto_socket(inst->mosq); assert(fd != 0); rval = dispatch_register(inst->dispatch, fd, mqtt_read, mqtt_write, NULL, mqtt_close, inst); assert(rval == 0); } } } rval = mosquitto_loop_misc(inst->mosq); switch (rval) { case MOSQ_ERR_SUCCESS: break; case MOSQ_ERR_NO_CONN: //debug("mosquitto_loop_misc: No connection"); break; case MOSQ_ERR_INVAL: default: error("mosquitto_loop_misc: %s", mosquitto_strerror(rval)); break; } }
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; }
/* {{{ Mosquitto\Client::getSocket() */ PHP_METHOD(Mosquitto_Client, getSocket) { mosquitto_client_object *object; PHP_MOSQUITTO_ERROR_HANDLING(); if (zend_parse_parameters_none() == FAILURE) { PHP_MOSQUITTO_RESTORE_ERRORS(); return; } PHP_MOSQUITTO_RESTORE_ERRORS(); object = (mosquitto_client_object *) mosquitto_client_object_get(getThis() TSRMLS_CC); RETURN_LONG(mosquitto_socket(object->client)); }
bool MosquittoHandler::getSocket(int &socket) { if(!m_mosquittoStruct) { m_lastErrorString = "Mosquitto not initialized"; return false; } int sock = mosquitto_socket(m_mosquittoStruct); if(sock == -1) { m_lastErrorString = "Socket error"; return false; } socket = sock; return true; }
static int ctx_socket(lua_State *L) { ctx_t *ctx = ctx_check(L, 1); int fd = mosquitto_socket(ctx->mosq); switch (fd) { case -1: lua_pushboolean(L, false); break; default: lua_pushinteger(L, fd); break; } return 1; }
int mqtt_open(mqtt_t inst, dispatch_t d, const char* name, const char* host, int port, int keepalive) { int rval = -1; int fd; inst->mosq = mosquitto_new(name, true, inst); if (inst->mosq == NULL) { error("Cannot create mqtt"); } else { inst->dispatch = d; mosquitto_log_callback_set(inst->mosq, on_log); mosquitto_connect_callback_set(inst->mosq, on_connect); mosquitto_disconnect_callback_set(inst->mosq, on_disconnect); mosquitto_publish_callback_set(inst->mosq, on_publish); mosquitto_message_callback_set(inst->mosq, on_message); mosquitto_subscribe_callback_set(inst->mosq, on_subscribe); mosquitto_unsubscribe_callback_set(inst->mosq, on_unsubscribe); inst->timer = dispatch_create_timer(d, 2000000, mqtt_misc, inst); if (inst->timer == NULL) { error("Cannot create timer"); } rval = mosquitto_connect(inst->mosq, host, port, keepalive); if (rval != MOSQ_ERR_SUCCESS) { error("Cannot connect mqtt"); } else { fd = mosquitto_socket(inst->mosq); rval = dispatch_register(d, fd, mqtt_read, mqtt_write, NULL, mqtt_close, inst); if (rval != 0) { error("Cannot register mqtt"); } } } return rval; }
static int mosq_poll_one_ctx(mosq_t *ctx, int revents, size_t timeout, int max_packets) { /** XXX * I'm confused: socket < 0 means MOSQ_ERR_NO_CONN */ int rc = MOSQ_ERR_NO_CONN; int fd = mosquitto_socket(ctx->mosq); if (fd >= 0) { /** Wait until event */ revents = coio_wait(fd, revents, timeout); if (revents != 0) { if (revents & COIO_READ) rc = mosquitto_loop_read(ctx->mosq, max_packets); if (revents & COIO_WRITE) rc = mosquitto_loop_write(ctx->mosq, max_packets); } /** * mosquitto_loop_miss * This function deals with handling PINGs and checking * whether messages need to be retried, * so should be called fairly _frequently_(!). * */ if (ctx->next_misc_timeout < fiber_time64()) { rc = mosquitto_loop_misc(ctx->mosq); ctx->next_misc_timeout = fiber_time64() + 1200; } } return rc; }
int mosquittopp::socket() { return mosquitto_socket(m_mosq); }
int auth_mqtt_fd(void) { if (auth_mqtt_mosq) return mosquitto_socket(auth_mqtt_mosq); return -1; }
int run_subscriber(int argc, char* const argv[]) //int main(int argc, char* const argv[]) { mosquitto_lib_init(); #if 0 { int major, minor, revision; mosquitto_lib_version(&major, &minor, &revision); std::cout << "Mosquitto library version - " << major << "." << minor << "." << revision << std::endl; } #endif std::cout << "Rx Measurement test program" << std::endl; std::string hostname("localhost"); std::list<std::string> topics; int qos = 0; // Cheap. int port = 1883; bool use_json = false; int num_threads = 1; enum { HELP_OPTION = '?', HOST_OPTION = 'h', TOPIC_OPTION = 't', QOS_OPTION = 'q', PORT_OPTION = 'p', JSON_MSG_OPTION = 'j', BINARY_MSG_OPTION = 'B', PARALLEL_OPTION = 'P', }; struct option options[] = { {"help", 0, nullptr, HELP_OPTION}, {"mqtt-host", 1, nullptr, HOST_OPTION}, {"topic", 1, nullptr, TOPIC_OPTION}, {"qos", 1, nullptr, QOS_OPTION}, {"mqtt-port", 1, nullptr, PORT_OPTION}, {"json", 0, nullptr, JSON_MSG_OPTION}, {"binary", 0, nullptr, BINARY_MSG_OPTION}, {"parallel", 1, nullptr, PARALLEL_OPTION}, {0} }; bool more_options = true; while (more_options) { int status = getopt_long(argc, argv, "h:t:q:p:j", options, nullptr); switch (status) { case HOST_OPTION: hostname = optarg; break; case TOPIC_OPTION: topics.push_back(optarg); break; case HELP_OPTION: exit(EXIT_FAILURE); break; case QOS_OPTION: qos = atoi(optarg); break; case PORT_OPTION: port = atoi(optarg); break; case JSON_MSG_OPTION: use_json = true; break; case BINARY_MSG_OPTION: use_json = false; break; case PARALLEL_OPTION: num_threads = atoi(optarg); break; default: more_options = false; break; } } std::cout << "Connect to host " << hostname << " on port " << port << std::endl; for (auto& topic : topics) { std::cout << "Subscribe under topic " << topic << std::endl; } std::cout << "Subscribe with quality of service of " << qos << std::endl; { std::list<struct mosquitto*> mosq_list; ReceiveStats data_obj; get_timestamp(data_obj.base_nsec); data_obj.last_report_nsec = data_obj.base_nsec; for (int i = 0; i < num_threads; i++) { struct mosquitto *mosq = mosquitto_new(nullptr, /*clean_session=*/true, &data_obj); int code = mosquitto_connect(mosq, hostname.c_str(), port, /*keepalive=*/-1); if (code != MOSQ_ERR_SUCCESS) { switch (code) { case MOSQ_ERR_INVAL: std::cerr << "Mosquitto connect failure - invalid input parameters" << std::endl; break; case MOSQ_ERR_ERRNO: std::cerr << "Mosquitto connect failure - " << strerror(errno) << std::endl; break; default: std::cerr << "Mosquitto connect failure - unknown error" << std::endl; break; } exit(EXIT_FAILURE); } mosq_list.push_back(mosq); } #if DISABLE_NAGLE for (auto mosq : mosq_list) { int sock = mosquitto_socket(mosq); if (sock >= 0) { int flag = 1; int result = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag)); if (result < 0) { std::cerr << "Unable to disable Nagle algorithm on Misquitto socket, " << strerror(errno) << std::endl; } else { std::cout << "Disabled Nagle algorithm on Misquitto socket" << std::endl; } } else { std::cerr << "Unable to disable Nagle algorithm on Misquitto, no socket" << std::endl; } } #endif for (auto mosq : mosq_list) { if (use_json) { mosquitto_message_callback_set(mosq, &message_callback_json); } else { mosquitto_message_callback_set(mosq, &message_callback_binary); } mosquitto_subscribe_callback_set(mosq, &subscribe_callback); } for (auto mosq : mosq_list) { int code = mosquitto_loop_start(mosq); if (code != MOSQ_ERR_SUCCESS) { switch (code) { case MOSQ_ERR_INVAL: std::cerr << "Mosquitto loop start failure - invalid input parameters" << std::endl; break; case MOSQ_ERR_NOT_SUPPORTED: std::cerr << "Mosquitto loop start failure - not supported" << std::endl; break; default: std::cerr << "Mosquitto loop start failure - unknown error" << std::endl; break; } exit(EXIT_FAILURE); } } for (auto& topic : topics) { int mid; struct mosquitto* mosq = mosq_list.front(); // Transfer to back of list. mosq_list.pop_front(); mosq_list.push_back(mosq); int code = mosquitto_subscribe(mosq, &mid, topic.c_str(), qos); if (code != MOSQ_ERR_SUCCESS) { switch (code) { case MOSQ_ERR_INVAL: std::cerr << "Mosquitto subscribe failure - invalid input parameters" << std::endl; break; case MOSQ_ERR_NOMEM: std::cerr << "Mosquitto subscribe failure - out of memory" << std::endl; break; case MOSQ_ERR_NO_CONN: std::cerr << "Mosquitto subscribe failure - no connection" << std::endl; break; default: std::cerr << "Mosquitto subscribe failure - unknown error" << std::endl; break; } exit(EXIT_FAILURE); } std::cout << "Subscribing to topic " << topic << " with mid " << mid << std::endl; } for (auto mosq : mosq_list) { // mosquitto_disconnect(mosq); mosquitto_loop_stop(mosq, false); mosquitto_destroy(mosq); } } mosquitto_lib_cleanup(); }
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; }
int main( int argc, char* argv[] ) { setbuf(stdout, NULL); INFO("%s v1.0\n", argv[0]); config_t cfg; global_data_t state; struct mosquitto *mosq = NULL; config_init(&cfg); loadDefaults(&cfg); loadSerialDefaults(&cfg); if(parseArgs(argc, argv, &cfg)) { exit(1); } if(parseSerialArgs(argc, argv, &cfg)) { exit(1); } //config_write(&cfg, stderr); port_t serial; loadSerial(&cfg, &serial); if(serial.name == NULL) { ERR("Could not load serial configuration\n"); exit(2); } if(!strlen(serial.name)) { ERR("You must specify the serial port\n"); exit(2); } DBG("Setting up serial port..."); state.arduino_fd = setupSerial(serial.name, serial.speed); if(state.arduino_fd < 0) { ERR("Failed to setup serial port %s @ %d\n", serial.name, serial.speed); exit(2); } INFO("listening for event on %s\n", serial.name); mosquitto_lib_init(); mqttserver_t mqtt; loadMQTT(&cfg, &mqtt); char hostname[BUF_MAX]; gethostname(hostname, BUF_MAX); asprintf(&state.client_id, "%s.%s", hostname, (char *) strlaststr(serial.name, "/")); mosq = mosquitto_new(state.client_id, true, &state.arduino_fd); //use port name as client id if(!mosq) { ERR("Couldn't create a new mosquitto client instance\n"); exit(3); } //TODO setup callbacks mosquitto_log_callback_set(mosq, log_callback); mosquitto_disconnect_callback_set(mosq, disconnect_callback); mosquitto_connect_callback_set(mosq, connect_callback); mosquitto_message_callback_set(mosq, message_callback); INFO("Connecting to %s:%d ... ", mqtt.servername, mqtt.port); if(mosquitto_connect(mosq, mqtt.servername, mqtt.port, mqtt.keepalive)){ ERR("\nUnable to connect to %s:%d.\n", mqtt.servername, mqtt.port); exit(3); } INFO("done\n"); int mosq_fd = mosquitto_socket(mosq); fd_set active_fd_set, read_fd_set; /* Initialize the set of active sockets. */ FD_ZERO (&active_fd_set); FD_SET (state.arduino_fd, &active_fd_set); FD_SET (mosq_fd, &active_fd_set); char buf[BUF_MAX]; bzero(buf,BUF_MAX); int retries = 0; //TODO setup syscall to stop process while(1) { /* Block until input arrives on one or more active sockets. */ read_fd_set = active_fd_set; if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0) { ERR("Error in select\n"); sleep(BACKOFF); int r = mosquitto_reconnect(mosq); retries++; if(r != MOSQ_ERR_SUCCESS) { ERR("Could not reconnect to broker: %s\n", strerror(r)); if(retries > MAX_RETRIES) { /* Cleanup */ mosquitto_destroy(mosq); mosquitto_lib_cleanup(); exit (EXIT_FAILURE); } } else { retries = 0; continue; } } /* Service all the sockets with input pending. */ int i; for (i = 0; i < FD_SETSIZE; ++i) if (FD_ISSET (i, &read_fd_set)) { if(i == state.arduino_fd) { if(!readSerial(state.arduino_fd, buf, BUF_MAX, serial.timeout)) { arduinoEvent(buf, &cfg, mosq); bzero(buf,BUF_MAX); } } else if(i == mosq_fd) { mosquitto_loop_read(mosq, 1); mosquitto_loop_write(mosq, 1); mosquitto_loop_misc(mosq); } } }; return EXIT_SUCCESS; }