我这边的 ESP32 平台软件,实现了命令行(CLI)、telnet、http server。平时开发 IoT 软件的时候,可以通过 telnet 到设备,进行命令行的操作,定位问题,维护和调试设备。
IoT 设备给到用户后,设备通过 4G 上网,并通过 MQTT 与云平台连接。如果能够通过 MQTT 通道,实现远程的 telnet / web 访问,对设备的维护和故障定位非常有帮助。
我移植了开源的 MQTT_VPN 项目,但发现该项目不太稳定,经常会出现 exception 的问题。这些问题大都和 lwip 的协议有关。查看该项目的 issue,有用户报告类似的问题,但该项目已经好几年不维护了。
只能自己动手,做了一些定位,通过修改下面的代码解决:
struct mqtt_if_data *mqtt_if_add(esp_mqtt_client_handle_t cl, char *topic_prefix)
{
...
...
netif_add(&data->netif, NULL, NULL, NULL, data, mqtt_if_init, ip_input); -> 把 ip_input 修改为 tcpip_input
...
}
在 ESP32 的 freeRTOS 环境下,tcpip_input() 是通过消息队列的方式把报文发往 lwip 的 tcp/ip 协议栈,这种方式是线程安全的。而 ip_input() 直接调用 tcp/ip 协议栈的代码处理,这种方法在非操作系统环境是可以的,但在操作系统环境中是不安全的。