Skip to content

Commit 1886fb4

Browse files
committed
fix(modem): Support for TCP-TRANSPORT mode
1 parent 7404792 commit 1886fb4

File tree

4 files changed

+81
-37
lines changed

4 files changed

+81
-37
lines changed

components/esp_modem/examples/modem_tcp_client/main/command/sock_dce.cpp

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
#include <charconv>
88
#include <sys/socket.h>
9-
#include <algorithm> // for std::find
109
#include "esp_vfs.h"
1110
#include "esp_vfs_eventfd.h"
1211

@@ -17,8 +16,10 @@ namespace sock_dce {
1716
constexpr auto const *TAG = "sock_dce";
1817

1918
// Definition of the static member variables
20-
std::vector<DCE*> DCE::dce_list{};
19+
std::vector<DCE *> DCE::dce_list{};
2120
bool DCE::network_init = false;
21+
int Responder::s_link_id = 0;
22+
SemaphoreHandle_t Responder::s_dte_mutex{};
2223

2324
// Constructor - add this DCE instance to the static list
2425
DCE::DCE(std::shared_ptr<esp_modem::DTE> dte_arg, const esp_modem_dce_config *config)
@@ -36,6 +37,7 @@ DCE::~DCE()
3637
}
3738
}
3839

40+
3941
bool DCE::perform_sock()
4042
{
4143
if (listen_sock == -1) {
@@ -81,13 +83,22 @@ bool DCE::perform_sock()
8183

8284
void DCE::perform_at(uint8_t *data, size_t len)
8385
{
84-
ESP_LOG_BUFFER_HEXDUMP(TAG, data, len, ESP_LOG_VERBOSE);
86+
std::string_view resp_sv((char *)data, len);
87+
at.check_urc(state, resp_sv);
88+
if (state == status::IDLE) {
89+
return;
90+
}
91+
ESP_LOG_BUFFER_HEXDUMP(TAG, data, len, ESP_LOG_INFO);
8592
switch (at.process_data(state, data, len)) {
8693
case Responder::ret::OK:
94+
ESP_LOGW(TAG, "GIVE data %d", at.link_id);
95+
xSemaphoreGive(at.s_dte_mutex);
8796
state = status::IDLE;
8897
signal.set(IDLE);
8998
return;
9099
case Responder::ret::FAIL:
100+
ESP_LOGW(TAG, "GIVE data %d", at.link_id);
101+
xSemaphoreGive(at.s_dte_mutex);
91102
state = status::FAILED;
92103
signal.set(IDLE);
93104
return;
@@ -102,10 +113,14 @@ void DCE::perform_at(uint8_t *data, size_t len)
102113
std::string_view response((char *)data, len);
103114
switch (at.check_async_replies(state, response)) {
104115
case Responder::ret::OK:
116+
ESP_LOGW(TAG, "GIVE command %d", at.link_id);
117+
xSemaphoreGive(at.s_dte_mutex);
105118
state = status::IDLE;
106119
signal.set(IDLE);
107120
return;
108121
case Responder::ret::FAIL:
122+
ESP_LOGW(TAG, "GIVE command %d", at.link_id);
123+
xSemaphoreGive(at.s_dte_mutex);
109124
state = status::FAILED;
110125
signal.set(IDLE);
111126
return;
@@ -124,7 +139,6 @@ void DCE::close_sock()
124139
close(sock);
125140
sock = -1;
126141
}
127-
close(data_ready_fd);
128142
dte->on_read(nullptr);
129143
const int retries = 5;
130144
int i = 0;
@@ -152,6 +166,9 @@ bool DCE::at_to_sock()
152166
close_sock();
153167
return false;
154168
}
169+
ESP_LOGI(TAG, "TAKE RECV %d", at.link_id);
170+
xSemaphoreTake(at.s_dte_mutex, portMAX_DELAY);
171+
ESP_LOGE(TAG, "TAKE RECV %d", at.link_id);
155172
state = status::RECEIVING;
156173
at.start_receiving(at.get_buf_len());
157174
return true;
@@ -160,8 +177,8 @@ bool DCE::at_to_sock()
160177
bool DCE::sock_to_at()
161178
{
162179
ESP_LOGD(TAG, "socket read: data available");
163-
if (!signal.wait(IDLE, 1000)) {
164-
ESP_LOGE(TAG, "Failed to get idle");
180+
if (!signal.wait(IDLE, 5000)) {
181+
ESP_LOGE(TAG, "Failed to get idle 2");
165182
close_sock();
166183
return false;
167184
}
@@ -170,6 +187,9 @@ bool DCE::sock_to_at()
170187
close_sock();
171188
return false;
172189
}
190+
ESP_LOGI(TAG, "TAKE SEND %d", at.link_id);
191+
xSemaphoreTake(at.s_dte_mutex, portMAX_DELAY);
192+
ESP_LOGE(TAG, "TAKE SEND %d", at.link_id);
173193
state = status::SENDING;
174194
int len = ::recv(sock, at.get_buf(), at.get_buf_len(), 0);
175195
if (len < 0) {
@@ -247,16 +267,18 @@ bool DCE::connect(std::string host, int port)
247267
{
248268
data_ready_fd = eventfd(0, EFD_SUPPORT_ISR);
249269
assert(data_ready_fd > 0);
250-
dte->on_read(nullptr);
251-
tcp_close();
252-
dte->on_read([this](uint8_t *data, size_t len) {
253-
read_callback(data, len);
254-
return esp_modem::command_result::TIMEOUT;
255-
});
270+
// dte->on_read(nullptr);
271+
// tcp_close();
272+
// dte->on_read([](uint8_t *data, size_t len) {
273+
// read_callback(data, len);
274+
// return esp_modem::command_result::TIMEOUT;
275+
// });
276+
ESP_LOGI(TAG, "TAKE CONNECT %d", at.link_id);
277+
xSemaphoreTake(at.s_dte_mutex, portMAX_DELAY);
278+
ESP_LOGE(TAG, "TAKE CONNECT %d", at.link_id);
256279
if (!at.start_connecting(host, port)) {
257280
ESP_LOGE(TAG, "Unable to start connecting");
258281
dte->on_read(nullptr);
259-
close(data_ready_fd);
260282
return false;
261283
}
262284
state = status::CONNECTING;
@@ -269,6 +291,8 @@ bool DCE::init()
269291
return true;
270292
}
271293
network_init = true;
294+
Responder::s_dte_mutex = xSemaphoreCreateBinary();
295+
xSemaphoreGive(at.s_dte_mutex);
272296
esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
273297
esp_vfs_eventfd_register(&config);
274298

@@ -312,6 +336,10 @@ bool DCE::init()
312336
esp_modem::Task::Delay(5000);
313337
}
314338
ESP_LOGI(TAG, "Got IP %s", ip_addr.c_str());
339+
dte->on_read([](uint8_t *data, size_t len) {
340+
read_callback(data, len);
341+
return esp_modem::command_result::TIMEOUT;
342+
});
315343
return true;
316344
}
317345

components/esp_modem/examples/modem_tcp_client/main/command/sock_dce.hpp

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class Responder {
3434
sock(s), data_ready_fd(ready_fd), dte(dte_arg) {}
3535
ret process_data(status state, uint8_t *data, size_t len);
3636
ret check_async_replies(status state, std::string_view &response);
37+
ret check_urc(status state, std::string_view &response);
3738

3839
void start_sending(size_t len);
3940
void start_receiving(size_t len);
@@ -63,13 +64,17 @@ class Responder {
6364
return total_len;
6465
}
6566

67+
int link_id{s_link_id++};
68+
static SemaphoreHandle_t s_dte_mutex;
6669
private:
70+
static int s_link_id;
6771
static constexpr size_t buffer_size = 512;
6872

6973
bool on_read(char *data, size_t len)
7074
{
7175
#ifndef CONFIG_EXAMPLE_CUSTOM_TCP_TRANSPORT
7276
::send(sock, data, len, 0);
77+
printf("sending %d\n", len);
7378
#else
7479
::memcpy(&buffer[actual_read], data, len);
7580
actual_read += len;
@@ -100,11 +105,6 @@ class Responder {
100105

101106
class DCE : public Module {
102107
public:
103-
// Constructor and destructor for managing dce_list
104-
// explicit GenericModule(std::shared_ptr<DTE> dte, std::unique_ptr<PdpContext> pdp):
105-
// dte(std::move(dte)), pdp(std::move(pdp)) {}
106-
// explicit GenericModule(std::shared_ptr<DTE> dte, );
107-
//
108108
DCE(std::shared_ptr<esp_modem::DTE> dte_arg, const esp_modem_dce_config *config);
109109
~DCE();
110110

@@ -169,6 +169,9 @@ class DCE : public Module {
169169
return 0;
170170
}
171171
at.clear_offsets();
172+
ESP_LOGI("TAG", "TAKE RECV %d", at.link_id);
173+
xSemaphoreTake(at.s_dte_mutex, portMAX_DELAY);
174+
ESP_LOGE("TAG", "TAKE RECV %d", at.link_id);
172175
state = status::RECEIVING;
173176
uint64_t data;
174177
read(data_ready_fd, &data, sizeof(data));
@@ -190,6 +193,9 @@ class DCE : public Module {
190193
if (!wait_to_idle(timeout_ms)) {
191194
return -1;
192195
}
196+
ESP_LOGI("TAG", "TAKE SEND %d", at.link_id);
197+
xSemaphoreTake(at.s_dte_mutex, portMAX_DELAY);
198+
ESP_LOGE("TAG", "TAKE SEND %d", at.link_id);
193199
state = status::SENDING;
194200
memcpy(at.get_buf(), buffer, len_to_send);
195201
ESP_LOG_BUFFER_HEXDUMP("dce", at.get_buf(), len, ESP_LOG_VERBOSE);
@@ -230,6 +236,14 @@ class DCE : public Module {
230236
}
231237
return -1;
232238
}
239+
static std::vector<DCE *> dce_list;
240+
static bool network_init;
241+
static void read_callback(uint8_t *data, size_t len)
242+
{
243+
for (auto dce : dce_list) {
244+
dce->perform_at(data, len);
245+
}
246+
}
233247
private:
234248
esp_modem::SignalGroup signal;
235249
void close_sock();
@@ -243,15 +257,6 @@ class DCE : public Module {
243257
int sock {-1};
244258
int listen_sock {-1};
245259
int data_ready_fd {-1};
246-
static std::vector<DCE*> dce_list;
247-
static bool network_init;
248-
static void read_callback(uint8_t *data, size_t len)
249-
{
250-
for (auto dce : dce_list) {
251-
dce->perform_at(data, len);
252-
}
253-
}
254-
255260
};
256261
std::unique_ptr<DCE> create(const esp_modem::dce_config *config, std::shared_ptr<esp_modem::DTE> dte);
257262
}

components/esp_modem/examples/modem_tcp_client/main/generate/sock_dce.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,9 @@ esp_modem::return_type name(ESP_MODEM_COMMAND_PARAMS(__VA_ARGS__));
147147
return 0;
148148
}
149149
at.clear_offsets();
150-
// TODO: MUTEX
150+
ESP_LOGI("TAG", "TAKE RECV %d", at.link_id);
151+
xSemaphoreTake(at.s_dte_mutex, portMAX_DELAY);
152+
ESP_LOGE("TAG", "TAKE RECV %d", at.link_id);
151153
state = status::RECEIVING;
152154
uint64_t data;
153155
read(data_ready_fd, &data, sizeof(data));
@@ -170,7 +172,9 @@ esp_modem::return_type name(ESP_MODEM_COMMAND_PARAMS(__VA_ARGS__));
170172
if (!wait_to_idle(timeout_ms)) {
171173
return -1;
172174
}
173-
// TODO: MUTEX
175+
ESP_LOGI("TAG", "TAKE SEND %d", at.link_id);
176+
xSemaphoreTake(at.s_dte_mutex, portMAX_DELAY);
177+
ESP_LOGE("TAG", "TAKE SEND %d", at.link_id);
174178
state = status::SENDING;
175179
memcpy(at.get_buf(), buffer, len_to_send);
176180
ESP_LOG_BUFFER_HEXDUMP("dce", at.get_buf(), len, ESP_LOG_VERBOSE);

components/esp_modem/examples/modem_tcp_client/main/modem_client.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#include "tcp_transport_at.h"
2525

2626
// #define BROKER_URL "test.mosquitto.org"
27-
#define BROKER_URL "192.168.0.39"
27+
#define BROKER_URL "broker.emqx.io"
2828
#define BROKER_PORT 1883
2929

3030

@@ -76,8 +76,6 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
7676
}
7777
}
7878

79-
// sock_dce::DCE::dce_list{};
80-
8179
static void perform(void* ctx);
8280

8381
extern "C" void app_main(void)
@@ -117,7 +115,8 @@ extern "C" void app_main(void)
117115

118116
xTaskCreate(perform, "perform", 4096, dce.get(), 4, nullptr);
119117

120-
// vTaskDelay(pdMS_TO_TICKS(15000));
118+
// vTaskDelay(pdMS_TO_TICKS(5000));
119+
// vTaskDelay(portMAX_DELAY);
121120
/* create another DCE to serve a new connection */
122121
auto dce1 = sock_dce::create(&dce_config, dte);
123122
if (!dce1->init()) {
@@ -127,6 +126,13 @@ extern "C" void app_main(void)
127126
xTaskCreate(perform, "perform", 4096, dce1.get(), 4, nullptr);
128127

129128
xEventGroupWaitBits(event_group, DCE0_DONE | DCE1_DONE, pdFALSE, pdTRUE, portMAX_DELAY);
129+
#ifdef CONFIG_EXAMPLE_CUSTOM_TCP_TRANSPORT
130+
// we release smart pointers, as this example does never exit
131+
// and in tcp-transport option we don't need a task to run
132+
// so we exit main and keep DCE's "running"
133+
dce.release();
134+
dce1.release();
135+
#endif
130136
}
131137

132138
static void perform(void* ctx)
@@ -137,18 +143,18 @@ static void perform(void* ctx)
137143
const int id = counter++;
138144
mqtt_client_id[12] += id; // assumes different client id per each thread
139145
esp_mqtt_client_config_t mqtt_config = {};
140-
mqtt_config.broker.address.port = BROKER_PORT + id;
146+
mqtt_config.broker.address.port = BROKER_PORT; // + id;
141147
mqtt_config.session.message_retransmit_timeout = 10000;
142148
mqtt_config.credentials.client_id = mqtt_client_id;
143149
#ifndef CONFIG_EXAMPLE_CUSTOM_TCP_TRANSPORT
144150
mqtt_config.broker.address.uri = "mqtt://127.0.0.1";
145151
dce->start_listening(BROKER_PORT + id);
146152
#else
147153
mqtt_config.broker.address.uri = "mqtt://" BROKER_URL;
148-
esp_transport_handle_t at = esp_transport_at_init(dce.get());
149-
esp_transport_handle_t ssl = esp_transport_tls_init(at);
154+
esp_transport_handle_t at = esp_transport_at_init(dce);
155+
// esp_transport_handle_t ssl = esp_transport_tls_init(at);
150156

151-
mqtt_config.network.transport = ssl;
157+
mqtt_config.network.transport = at;
152158
#endif
153159
esp_mqtt_client_handle_t mqtt_client = esp_mqtt_client_init(&mqtt_config);
154160
esp_mqtt_client_register_event(mqtt_client, static_cast<esp_mqtt_event_id_t>(ESP_EVENT_ANY_ID), mqtt_event_handler, nullptr);
@@ -174,4 +180,5 @@ static void perform(void* ctx)
174180
}
175181
#endif
176182
xEventGroupSetBits(event_group, id ? DCE0_DONE : DCE1_DONE);
183+
vTaskDelete(nullptr);
177184
}

0 commit comments

Comments
 (0)