static void tcp_recv_handler(struct mbuf *mb, void *arg) { struct esp_client *ec = (struct esp_client *)arg; struct dm_packet *packet = (struct dm_packet *)mb->buf; if((int)mb->end != (int)dm_packet_size(packet)) return; switch(dm_packet_flag(packet)) { case 0: on_ack(ec, packet); break; default: DEBUG_INFO("%s %d | pkt.size=%d\n", __func__, __LINE__, (int)dm_packet_size(packet)); DEBUG_INFO("%s %d | pkt.flag=%d\n", __func__, __LINE__, (int)dm_packet_flag(packet)); break; } }
void emcute_run(uint16_t port, const char *id) { assert(strlen(id) < EMCUTE_ID_MAXLEN); sock_udp_ep_t local = SOCK_IPV6_EP_ANY; sock_udp_ep_t remote; local.port = port; cli_id = id; timer.callback = time_evt; timer.arg = NULL; mutex_init(&txlock); if (sock_udp_create(&sock, &local, NULL, 0) < 0) { LOG_ERROR("[emcute] unable to open UDP socket on port %i\n", (int)port); return; } uint32_t start = xtimer_now_usec(); uint32_t t_out = (EMCUTE_KEEPALIVE * US_PER_SEC); while (1) { ssize_t len = sock_udp_recv(&sock, rbuf, sizeof(rbuf), t_out, &remote); if ((len < 0) && (len != -ETIMEDOUT)) { LOG_ERROR("[emcute] error while receiving UDP packet\n"); return; } if (len >= 2) { /* handle the packet */ uint16_t pkt_len; /* catch invalid length field */ if ((len == 2) && (rbuf[0] == 0x01)) { continue; } /* parse length field */ size_t pos = get_len(rbuf, &pkt_len); /* verify length to prevent overflows */ if (((size_t)pkt_len > (size_t)len) || (pos >= (size_t)len)) { continue; } /* get packet type */ uint8_t type = rbuf[pos]; switch (type) { case CONNACK: on_ack(type, 0, 2, 0); break; case WILLTOPICREQ: on_ack(type, 0, 0, 0); break; case WILLMSGREQ: on_ack(type, 0, 0, 0); break; case REGACK: on_ack(type, 4, 6, 2); break; case PUBLISH: on_publish((size_t)pkt_len, pos); break; case PUBACK: on_ack(type, 4, 6, 0); break; case SUBACK: on_ack(type, 5, 7, 3); break; case UNSUBACK: on_ack(type, 2, 0, 0); break; case PINGREQ: on_pingreq(&remote); break; case PINGRESP: on_pingresp(); break; case DISCONNECT: on_disconnect(); break; case WILLTOPICRESP: on_ack(type, 0, 0, 0); break; case WILLMSGRESP: on_ack(type, 0, 0, 0); break; default: LOG_DEBUG("[emcute] received unexpected type [%s]\n", emcute_type_str(type)); } } uint32_t now = xtimer_now_usec(); if ((now - start) >= (EMCUTE_KEEPALIVE * US_PER_SEC)) { send_ping(); start = now; t_out = (EMCUTE_KEEPALIVE * US_PER_SEC); } else { t_out = (EMCUTE_KEEPALIVE * US_PER_SEC) - (now - start); } } }