diff --git a/examples/arduino/sim800-mqtt/sim800-mqtt.ino b/examples/arduino/sim800-mqtt/sim800-mqtt.ino index 355090da..d1d99e6d 100644 --- a/examples/arduino/sim800-mqtt/sim800-mqtt.ino +++ b/examples/arduino/sim800-mqtt/sim800-mqtt.ino @@ -12,14 +12,16 @@ static const char *script[] = { "AT+CNMI=0,0,0,0,0\r\n", "*OK\r\n", "AT+CGDCONT=1,\"IP\",\"iot.1nce.net\"\r\n", "*OK\r\n", "AT+CGDATA=\"PPP\",1\r\n", "*CONNECT\r\n", - NULL + NULL, }; -// We use software serial to communicate with the modem +// We use Serial1 or software serial to communicate with the modem #define LED_PIN LED_BUILTIN -#define RX_PIN 9 -#define TX_PIN 8 -SoftwareSerial SSerial(RX_PIN, TX_PIN); +#define RST_PIN 10 +#define ModemSerial Serial1 +//#define RX_PIN 9 +//#define TX_PIN 8 +//SoftwareSerial ModemSerial(RX_PIN, TX_PIN); struct mg_connection *mqtt_connection; struct mg_tcpip_driver_ppp_data driver_data; @@ -76,23 +78,26 @@ void reconnect_if_not_connected(void) { } void setup() { - Serial.begin(115200); // Initialise serial + Serial.begin(115200); // Initialise serial for logs while (!Serial) delay(50); // for debug output - pinMode(LED_PIN, OUTPUT); // Initialise LED - pinMode(RX_PIN, INPUT); - pinMode(TX_PIN, OUTPUT); - SSerial.begin(19200); + pinMode(LED_PIN, OUTPUT); // Initialise pins + pinMode(RST_PIN, OUTPUT); + digitalWrite(RST_PIN, HIGH); + //pinMode(RX_PIN, INPUT); // Only required for + //pinMode(TX_PIN, OUTPUT); // software serial + ModemSerial.begin(115200); // Serial for modem communication mg_mgr_init(&mgr); // Initialise Mongoose event manager mg_log_set(MG_LL_DEBUG); // Set debug log level - mg_log_set_fn([](char ch, void *) { Serial.print(ch); }, NULL); // Log serial + mg_log_set_fn([](char c, void *) { Serial.print(c); }, NULL); // Log serial mif.driver = &mg_tcpip_driver_ppp; // Initialise built-in TCP/IP stack mif.driver_data = &driver_data; // with the cellular driver driver_data.script = script; - driver_data.tx = [](void *, uint8_t c) { SSerial.write(c); }, - driver_data.rx = [](void *) { return SSerial.available() ? SSerial.read() : -1; }, + driver_data.reset = [](void *) { digitalWrite(RST_PIN, LOW); delay(1); digitalWrite(RST_PIN, HIGH); }, + driver_data.tx = [](void *, uint8_t c) { ModemSerial.write(c); }, + driver_data.rx = [](void *) { return ModemSerial.available() ? ModemSerial.read() : -1; }, mg_tcpip_init(&mgr, &mif); mif.enable_dhcp_client = false; } diff --git a/mongoose.c b/mongoose.c index 8ce4515d..e4ec04e0 100644 --- a/mongoose.c +++ b/mongoose.c @@ -4964,14 +4964,14 @@ static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t now) { bool expired_1000ms = mg_timer_expired(&ifp->timer_1000ms, 1000, now); ifp->now = now; -#if MG_ENABLE_TCPIP_PRINT_DEBUG_STATS if (expired_1000ms) { +#if MG_ENABLE_TCPIP_PRINT_DEBUG_STATS const char *names[] = {"down", "up", "req", "ip", "ready"}; MG_INFO(("Status: %s, IP: %M, rx:%u, tx:%u, dr:%u, er:%u", names[ifp->state], mg_print_ip4, &ifp->ip, ifp->nrecv, ifp->nsent, ifp->ndrop, ifp->nerr)); - } #endif + } // Handle gw ARP request timeout, order is important if (expired_1000ms && ifp->state == MG_TCPIP_STATE_IP) { ifp->state = MG_TCPIP_STATE_READY; // keep best-effort MAC @@ -17825,6 +17825,12 @@ static size_t print_atcmd(void (*out)(char, void *), void *arg, va_list *ap) { return s.len; } +static void mg_ppp_reset(struct mg_tcpip_driver_ppp_data *dd) { + dd->script_index = 0; + dd->deadline = 0; + if (dd->reset) dd->reset(dd->uart); +} + static bool mg_ppp_atcmd_handle(struct mg_tcpip_if *ifp) { struct mg_tcpip_driver_ppp_data *dd = (struct mg_tcpip_driver_ppp_data *) ifp->driver_data; @@ -17845,11 +17851,9 @@ static bool mg_ppp_atcmd_handle(struct mg_tcpip_if *ifp) { int is_timeout = dd->deadline > 0 && mg_millis() > dd->deadline; int is_overflow = q->head >= q->size - 1; if (is_timeout || is_overflow) { - MG_ERROR(("AT error: %s, retrying... %u [%.*s]", - is_timeout ? "timeout" : "overflow", q->head, q->head, q->buf)); - dd->script_index = 0; - dd->deadline = mg_millis() + MG_PPP_AT_TIMEOUT; - if (dd->reset) dd->reset(dd->uart); + MG_ERROR(("AT error: %s, retrying...", + is_timeout ? "timeout" : "overflow")); + mg_ppp_reset(dd); return false; // FAIL: timeout } if ((c = dd->rx(dd->uart)) < 0) return false; // no data @@ -18024,7 +18028,8 @@ static void mg_ppp_handle_lcp(struct mg_tcpip_if *ifp, uint8_t *lcp, uint8_t ack[4] = {MG_PPP_LCP_CFG_TERM_ACK, id, 0, 4}; MG_DEBUG(("LCP termination request, acknowledging...")); mg_ppp_tx_frame(dd, MG_PPP_PROTO_LCP, ack, sizeof(ack)); - ifp->state = MG_TCPIP_STATE_DOWN; + mg_ppp_reset(dd); + ifp->state = MG_TCPIP_STATE_UP; if (dd->reset) dd->reset(dd->uart); } break; } @@ -18046,7 +18051,7 @@ static void mg_ppp_handle_ipcp(struct mg_tcpip_if *ifp, uint8_t *ipcp, MG_DEBUG(("got IPCP config request, acknowledging...")); if (len >= 10 && ipcp[4] == MG_PPP_IPCP_IPADDR) { uint8_t *ip = ipcp + 6; - MG_INFO(("host ip: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3])); + MG_DEBUG(("host ip: %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3])); } ipcp[0] = MG_PPP_IPCP_ACK; mg_ppp_tx_frame(dd, MG_PPP_PROTO_IPCP, ipcp, len); @@ -18064,10 +18069,11 @@ static void mg_ppp_handle_ipcp(struct mg_tcpip_if *ifp, uint8_t *ipcp, // NACK contains our "suggested" IP address, use it if (len >= 10 && ipcp[4] == MG_PPP_IPCP_IPADDR) { uint8_t *ip = ipcp + 6; - MG_INFO(("ipcp ack, ip: %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3])); + MG_DEBUG(("ipcp ack, ip: %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3])); ipcp[0] = MG_PPP_IPCP_REQ; mg_ppp_tx_frame(dd, MG_PPP_PROTO_IPCP, ipcp, len); ifp->ip = ifp->mask = MG_IPV4(ip[0], ip[1], ip[2], ip[3]); + ifp->state = MG_TCPIP_STATE_READY; } break; } diff --git a/src/drivers/ppp.c b/src/drivers/ppp.c index 463a7639..78cfd089 100644 --- a/src/drivers/ppp.c +++ b/src/drivers/ppp.c @@ -31,6 +31,12 @@ static size_t print_atcmd(void (*out)(char, void *), void *arg, va_list *ap) { return s.len; } +static void mg_ppp_reset(struct mg_tcpip_driver_ppp_data *dd) { + dd->script_index = 0; + dd->deadline = 0; + if (dd->reset) dd->reset(dd->uart); +} + static bool mg_ppp_atcmd_handle(struct mg_tcpip_if *ifp) { struct mg_tcpip_driver_ppp_data *dd = (struct mg_tcpip_driver_ppp_data *) ifp->driver_data; @@ -53,9 +59,7 @@ static bool mg_ppp_atcmd_handle(struct mg_tcpip_if *ifp) { if (is_timeout || is_overflow) { MG_ERROR(("AT error: %s, retrying...", is_timeout ? "timeout" : "overflow")); - dd->script_index = 0; - dd->deadline = mg_millis() + MG_PPP_AT_TIMEOUT; - if (dd->reset) dd->reset(dd->uart); + mg_ppp_reset(dd); return false; // FAIL: timeout } if ((c = dd->rx(dd->uart)) < 0) return false; // no data @@ -230,7 +234,8 @@ static void mg_ppp_handle_lcp(struct mg_tcpip_if *ifp, uint8_t *lcp, uint8_t ack[4] = {MG_PPP_LCP_CFG_TERM_ACK, id, 0, 4}; MG_DEBUG(("LCP termination request, acknowledging...")); mg_ppp_tx_frame(dd, MG_PPP_PROTO_LCP, ack, sizeof(ack)); - ifp->state = MG_TCPIP_STATE_DOWN; + mg_ppp_reset(dd); + ifp->state = MG_TCPIP_STATE_UP; if (dd->reset) dd->reset(dd->uart); } break; } @@ -252,7 +257,7 @@ static void mg_ppp_handle_ipcp(struct mg_tcpip_if *ifp, uint8_t *ipcp, MG_DEBUG(("got IPCP config request, acknowledging...")); if (len >= 10 && ipcp[4] == MG_PPP_IPCP_IPADDR) { uint8_t *ip = ipcp + 6; - MG_INFO(("host ip: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3])); + MG_DEBUG(("host ip: %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3])); } ipcp[0] = MG_PPP_IPCP_ACK; mg_ppp_tx_frame(dd, MG_PPP_PROTO_IPCP, ipcp, len); @@ -270,10 +275,11 @@ static void mg_ppp_handle_ipcp(struct mg_tcpip_if *ifp, uint8_t *ipcp, // NACK contains our "suggested" IP address, use it if (len >= 10 && ipcp[4] == MG_PPP_IPCP_IPADDR) { uint8_t *ip = ipcp + 6; - MG_INFO(("ipcp ack, ip: %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3])); + MG_DEBUG(("ipcp ack, ip: %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3])); ipcp[0] = MG_PPP_IPCP_REQ; mg_ppp_tx_frame(dd, MG_PPP_PROTO_IPCP, ipcp, len); ifp->ip = ifp->mask = MG_IPV4(ip[0], ip[1], ip[2], ip[3]); + ifp->state = MG_TCPIP_STATE_READY; } break; } diff --git a/src/net_builtin.c b/src/net_builtin.c index 3bdd3401..3a622ac9 100644 --- a/src/net_builtin.c +++ b/src/net_builtin.c @@ -900,14 +900,14 @@ static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t now) { bool expired_1000ms = mg_timer_expired(&ifp->timer_1000ms, 1000, now); ifp->now = now; -#if MG_ENABLE_TCPIP_PRINT_DEBUG_STATS if (expired_1000ms) { +#if MG_ENABLE_TCPIP_PRINT_DEBUG_STATS const char *names[] = {"down", "up", "req", "ip", "ready"}; MG_INFO(("Status: %s, IP: %M, rx:%u, tx:%u, dr:%u, er:%u", names[ifp->state], mg_print_ip4, &ifp->ip, ifp->nrecv, ifp->nsent, ifp->ndrop, ifp->nerr)); - } #endif + } // Handle gw ARP request timeout, order is important if (expired_1000ms && ifp->state == MG_TCPIP_STATE_IP) { ifp->state = MG_TCPIP_STATE_READY; // keep best-effort MAC