1313
1414// We only use profile 0 to keep things simple we also stick with spId 3
1515// which we dedicate to HTTPS
16- #define HTTP_CONFIGURE " AT+SQNHTTPCFG=0,\" %s\" ,%u,0,\"\" ,\"\" ,%u,120,1 ,3"
16+ #define HTTP_CONFIGURE " AT+SQNHTTPCFG=0,\" %s\" ,%u,0,\"\" ,\"\" ,%u,120,,3"
1717
18- // Command without any data in it (with quotation marks): 36 bytes
19- // Max length of doman name: 127 bytes
18+ // Command without any data in it (with quotation marks): 35 bytes
19+ // Max length of domain name: 127 bytes
2020// Max length of port number: 5 bytes (0-65535)
2121// TLS enabled: 1 byte
2222// Termination: 1 byte
23- // This results in 36 + 127 + 5 + 1 + 1 = 170
24- #define HTTP_CONFIGURE_SIZE 170
23+ // This results in 35 + 127 + 5 + 1 + 1 = 169
24+ #define HTTP_CONFIGURE_SIZE 169
2525
2626#define HTTPS_SECURITY_PROFILE_NUMBER 3
2727
@@ -75,14 +75,17 @@ HttpClientClass HttpClient = HttpClientClass::instance();
7575 * @param method POST(0) or PUT(1).
7676 * @param header Optional header.
7777 * @param header_length Length of header.
78+ * @param timeout_ms Timeout in milliseconds for the transmission.
7879 */
79- static HttpResponse sendData (const char * endpoint,
80- const uint8_t * data,
81- const uint32_t data_length,
82- const uint8_t method,
83- const uint8_t * header = NULL ,
84- const uint32_t header_length = 0 ,
85- const char * content_type = " " ) {
80+ static HttpResponse
81+ sendData (const char * endpoint,
82+ const uint8_t * data,
83+ const uint32_t data_length,
84+ const uint8_t method,
85+ const uint8_t * header = NULL ,
86+ const uint32_t header_length = 0 ,
87+ const char * content_type = " " ,
88+ const uint32_t timeout_ms = HTTP_DEFAULT_TIMEOUT_MS) {
8689
8790 LedCtrl.on (Led::CON, true );
8891
@@ -102,17 +105,33 @@ static HttpResponse sendData(const char* endpoint,
102105 char command[command_length + 1 ];
103106
104107 // Append +1 for NULL termination
105- snprintf (command,
106- command_length + 1 ,
107- HTTP_SEND,
108- method,
109- endpoint,
110- (unsigned long )data_length,
111- content_type,
112- header == NULL ? " " : (const char *)header);
108+ int bytes_written = snprintf (command,
109+ command_length,
110+ HTTP_SEND,
111+ method,
112+ endpoint,
113+ (unsigned long )data_length,
114+ content_type,
115+ header == NULL ? " " : (const char *)header);
116+ if (bytes_written < 0 ) {
117+ Log.errorf (
118+ " Failed to write HTTP send command, snprintf returned %d\r\n " ,
119+ bytes_written);
120+ return HttpResponse{0 , 0 };
121+ }
122+
123+ if (bytes_written >= (int )command_length) {
124+ Log.errorf (" Failed to write HTTP send command, snprintf returned %d "
125+ " but command length is %d\r\n " ,
126+ bytes_written,
127+ command_length);
128+ return HttpResponse{0 , 0 };
129+ }
130+
131+ command[bytes_written + 1 ] = ' \0 ' ;
113132
114133 LedCtrl.on (Led::DATA, true );
115- SequansController.writeBytes ((uint8_t *)command, command_length , true );
134+ SequansController.writeBytes ((uint8_t *)command, bytes_written , true );
116135
117136 // Only send the data payload if there is any
118137 if (data_length > 0 ) {
@@ -134,7 +153,7 @@ static HttpResponse sendData(const char* endpoint,
134153 _delay_ms (100 );
135154
136155 // Now we deliver the payload
137- SequansController.writeBytes (data, data_length);
156+ SequansController.writeBytes (data, data_length, true );
138157 }
139158
140159 char http_response_buffer[HTTP_RESPONSE_MAX_LENGTH] = " " ;
@@ -144,7 +163,8 @@ static HttpResponse sendData(const char* endpoint,
144163 // Now we wait for the URC
145164 if (!SequansController.waitForURC (HTTP_RING_URC,
146165 http_response_buffer,
147- sizeof (http_response_buffer))) {
166+ sizeof (http_response_buffer),
167+ timeout_ms)) {
148168 LedCtrl.off (Led::CON, true );
149169 LedCtrl.off (Led::DATA, true );
150170 Log.warn (" Did not get HTTP response before timeout\r\n " );
@@ -190,11 +210,13 @@ static HttpResponse sendData(const char* endpoint,
190210 * @param method GET(0), HEAD(1) or DELETE(2).
191211 * @param header Optional header.
192212 * @param header_length Length of header.
213+ * @param timeout_ms Timeout in milliseconds for the query.
193214 */
194215static HttpResponse queryData (const char * endpoint,
195216 const uint8_t method,
196217 const uint8_t * header,
197- const uint32_t header_length) {
218+ const uint32_t header_length,
219+ const uint32_t timeout_ms) {
198220
199221 LedCtrl.on (Led::CON, true );
200222
@@ -211,12 +233,29 @@ static HttpResponse queryData(const char* endpoint,
211233 // Append +1 for NULL termination
212234 char command[command_length + 1 ];
213235
214- snprintf (command,
215- command_length + 1 ,
216- HTTP_QUERY,
217- method,
218- endpoint,
219- header == NULL ? " " : (const char *)header);
236+ int bytes_written = snprintf (command,
237+ command_length,
238+ HTTP_QUERY,
239+ method,
240+ endpoint,
241+ header == NULL ? " " : (const char *)header);
242+
243+ if (bytes_written < 0 ) {
244+ Log.errorf (
245+ " Failed to write HTTP query command, snprintf returned %d\r\n " ,
246+ bytes_written);
247+ return HttpResponse{0 , 0 };
248+ }
249+
250+ if (bytes_written >= (int )command_length) {
251+ Log.errorf (" Failed to write HTTP query command, snprintf returned %d "
252+ " but command length is %d\r\n " ,
253+ bytes_written,
254+ command_length);
255+ return HttpResponse{0 , 0 };
256+ }
257+
258+ command[bytes_written + 1 ] = ' \0 ' ;
220259
221260 LedCtrl.on (Led::DATA, true );
222261 SequansController.writeCommand (command);
@@ -227,7 +266,8 @@ static HttpResponse queryData(const char* endpoint,
227266
228267 if (!SequansController.waitForURC (HTTP_RING_URC,
229268 http_response_buffer,
230- sizeof (http_response_buffer))) {
269+ sizeof (http_response_buffer),
270+ timeout_ms)) {
231271 Log.warn (" Did not get HTTP response before timeout\r\n " );
232272
233273 LedCtrl.off (Led::DATA, true );
@@ -288,7 +328,8 @@ HttpResponse HttpClientClass::post(const char* endpoint,
288328 const uint32_t data_length,
289329 const uint8_t * header_buffer,
290330 const uint32_t header_length,
291- const ContentType content_type) {
331+ const ContentType content_type,
332+ const uint32_t timeout_ms) {
292333
293334 // The content type within the Sequans modem is classified by a single
294335 // character (+1 for NULL termination)
@@ -332,63 +373,80 @@ HttpResponse HttpClientClass::post(const char* endpoint,
332373 HTTP_POST_METHOD,
333374 header_buffer,
334375 header_length,
335- content_type_buffer);
376+ content_type_buffer,
377+ timeout_ms);
336378}
337379
338380HttpResponse HttpClientClass::post (const char * endpoint,
339381 const char * data,
340382 const char * header,
341- const ContentType content_type) {
383+ const ContentType content_type,
384+ const uint32_t timeout_ms) {
342385 return post (endpoint,
343386 (uint8_t *)data,
344387 strlen (data),
345388 (uint8_t *)header,
346389 header == NULL ? 0 : strlen (header),
347- content_type);
390+ content_type,
391+ timeout_ms);
348392}
349393
350394HttpResponse HttpClientClass::put (const char * endpoint,
351395 const uint8_t * data_buffer,
352396 const uint32_t data_length,
353397 const uint8_t * header_buffer,
354- const uint32_t header_length) {
398+ const uint32_t header_length,
399+ const uint32_t timeout_ms) {
355400 return sendData (endpoint,
356401 data_buffer,
357402 data_length,
358403 HTTP_PUT_METHOD,
359404 header_buffer,
360- header_length);
405+ header_length,
406+ " " ,
407+ timeout_ms);
361408}
362409
363410HttpResponse HttpClientClass::put (const char * endpoint,
364411 const char * message,
365- const char * header) {
412+ const char * header,
413+ const uint32_t timeout_ms) {
366414 return put (endpoint,
367415 (uint8_t *)message,
368416 strlen (message),
369417 (uint8_t *)header,
370- header == NULL ? 0 : strlen (header));
418+ header == NULL ? 0 : strlen (header),
419+ timeout_ms);
371420}
372421
373- HttpResponse HttpClientClass::get (const char * endpoint, const char * header) {
422+ HttpResponse HttpClientClass::get (const char * endpoint,
423+ const char * header,
424+ const uint32_t timeout_ms) {
374425 return queryData (endpoint,
375426 HTTP_GET_METHOD,
376427 (uint8_t *)header,
377- strlen (header));
428+ strlen (header),
429+ timeout_ms);
378430}
379431
380- HttpResponse HttpClientClass::head (const char * endpoint, const char * header) {
432+ HttpResponse HttpClientClass::head (const char * endpoint,
433+ const char * header,
434+ const uint32_t timeout_ms) {
381435 return queryData (endpoint,
382436 HTTP_HEAD_METHOD,
383437 (uint8_t *)header,
384- strlen (header));
438+ strlen (header),
439+ timeout_ms);
385440}
386441
387- HttpResponse HttpClientClass::del (const char * endpoint, const char * header) {
442+ HttpResponse HttpClientClass::del (const char * endpoint,
443+ const char * header,
444+ const uint32_t timeout_ms) {
388445 return queryData (endpoint,
389446 HTTP_DELETE_METHOD,
390447 (uint8_t *)header,
391- strlen (header));
448+ strlen (header),
449+ timeout_ms);
392450}
393451
394452int16_t HttpClientClass::readBody (char * buffer, const uint32_t buffer_size) {
0 commit comments