void mqtt_sn_receive_connack(int sock) { connack_packet_t *packet = mqtt_sn_receive_packet(sock); if (packet == NULL) { log_err("Failed to connect to MQTT-SN gateway."); exit(EXIT_FAILURE); } if (packet->type != MQTT_SN_TYPE_CONNACK) { log_err("Was expecting CONNACK packet but received: %s", mqtt_sn_type_string(packet->type)); exit(EXIT_FAILURE); } // Check Connack return code log_debug("CONNACK return code: 0x%2.2x", packet->return_code); if (packet->return_code) { log_err("CONNECT error: %s", mqtt_sn_return_code_string(packet->return_code)); exit(packet->return_code); } }
void* mqtt_sn_wait_for(uint8_t type, int sock) { while(TRUE) { time_t now = time(NULL); int ret; // Time to send a ping? if (keep_alive > 0 && (now - last_transmit) >= keep_alive) { mqtt_sn_send_pingreq(sock); } ret = mqtt_sn_select(sock); if (ret < 0) { break; } else if (ret > 0) { char* packet = mqtt_sn_receive_packet(sock); if (packet) { switch(packet[1]) { case MQTT_SN_TYPE_PUBLISH: mqtt_sn_print_publish_packet((publish_packet_t *)packet); break; case MQTT_SN_TYPE_REGISTER: mqtt_sn_process_register(sock, (register_packet_t*)packet); break; case MQTT_SN_TYPE_PINGRESP: // do nothing break; case MQTT_SN_TYPE_DISCONNECT: if (type != MQTT_SN_TYPE_DISCONNECT) { log_warn("Received DISCONNECT from gateway."); exit(EXIT_FAILURE); } break; default: if (packet[1] != type) { log_warn( "Was expecting %s packet but received: %s", mqtt_sn_type_string(type), mqtt_sn_type_string(packet[1]) ); } break; } // Did we find what we were looking for? if (packet[1] == type) { return packet; } } } // Check for receive timeout if (keep_alive > 0 && (now - last_receive) >= (keep_alive * 1.5)) { log_err("Keep alive error: timed out while waiting for a %s from gateway.", mqtt_sn_type_string(type)); exit(EXIT_FAILURE); } } return NULL; }
int main(int argc, char* argv[]) { int sock; // Parse the command-line options parse_opts(argc, argv); // Enable debugging? mqtt_sn_set_debug(debug); // Create a UDP socket sock = mqtt_sn_create_socket(mqtt_sn_host, mqtt_sn_port); if (sock) { // Connect to gateway if (qos >= 0) { if (qos==0) { mqtt_sn_send_connect(sock, client_id, MQTT_SN_FLAG_CLEAN, keep_alive); mqtt_sn_receive_connack(sock); } else if (qos==1) { mqtt_sn_send_connect(sock, client_id, MQTT_SN_FLAG_CLEAN | MQTT_SN_FLAG_WILL , keep_alive); connack_packet_t *p= mqtt_sn_receive_packet(sock); if ( p!= NULL && p->type==MQTT_SN_TYPE_WILLTOPICREQ) { mqtt_sn_send_will_topic(sock, t_topic_name, MQTT_SN_FLAG_QOS_1 | MQTT_SN_FLAG_RETAIN); p= mqtt_sn_receive_packet(sock); if ( p!= NULL && p->type==MQTT_SN_TYPE_WILLMSGREQ) { mqtt_sn_send_will_msg(sock, t_message_data); } else { fprintf(stderr,"Error: did not get MQTT_SN_TYPE_WILLMSGREQ.\n"); exit(-1); } } else { fprintf(stderr,"Error: did not get MQTT_SN_TYPE_WILLTOPICREQ.\n"); exit(-1); } mqtt_sn_receive_connack(sock); } } if (topic_id) { // Use pre-defined topic ID topic_id_type = MQTT_SN_TOPIC_TYPE_PREDEFINED; } else if (strlen(topic_name) == 2) { // Convert the 2 character topic name into a 2 byte topic id topic_id = (topic_name[0] << 8) + topic_name[1]; topic_id_type = MQTT_SN_TOPIC_TYPE_SHORT; } else if (qos >= 0) { // Register the topic name mqtt_sn_send_register(sock, topic_name); topic_id = mqtt_sn_receive_regack(sock); topic_id_type = MQTT_SN_TOPIC_TYPE_NORMAL; } // Publish to the topic mqtt_sn_send_publish(sock, topic_id, topic_id_type, message_data, qos, retain); if (qos==1) { int retries=0; while (1) { connack_packet_t *p= mqtt_sn_receive_packet(sock); if ( p!= NULL && p->type==MQTT_SN_TYPE_PUBACK) { break; } else fprintf(stderr,"Warn: QoS 1 and send not acked -- retrying.. (%d/10)\n",retries); if (retries++>10) { fprintf(stderr,"Error: QoS 1 and send not acked, tried %d times\n",retries); exit(-1); } sleep(1); mqtt_sn_send_publish(sock, topic_id, topic_id_type, message_data, qos, retain); } if (retries) fprintf(stderr,"Warn: Send required %d times, but was successful.\n",retries); } // Finally, disconnect if (qos >= 0) { mqtt_sn_send_disconnect(sock); connack_packet_t *p= mqtt_sn_receive_packet(sock); if ( p!= NULL && p->type==MQTT_SN_TYPE_DISCONNECT) { // disconnect acked ok } else fprintf(stderr,"Warn: QoS >=0 and DISCONNECT not acked\n"); } close(sock); } mqtt_sn_cleanup(); return 0; }