|
25 | 25 | #define SECURITY_PROFILE_PREFIX_LENGTH 11 |
26 | 26 | #define HTTPS_SECURITY_PROFILE_NUMBER '3' |
27 | 27 |
|
28 | | -#define HTTP_SEND "AT+SQNHTTPSND=0,%u,\"%s\",%lu" |
| 28 | +#define HTTP_SEND "AT+SQNHTTPSND=0,%u,\"%s\",%lu,\"\",\"%s\"" |
29 | 29 | #define HTTP_RECEIVE "AT+SQNHTTPRCV=0,%lu" |
30 | | -#define HTTP_QUERY "AT+SQNHTTPQRY=0,%u,\"%s\"" |
| 30 | +#define HTTP_QUERY "AT+SQNHTTPQRY=0,%u,\"%s\",\"%s\"" |
31 | 31 |
|
32 | 32 | #define HTTP_RING_URC "SQNHTTPRING" |
33 | 33 |
|
@@ -63,39 +63,60 @@ HttpClientClass HttpClient = HttpClientClass::instance(); |
63 | 63 | * Issues an AT command to the LTE modem. |
64 | 64 | * |
65 | 65 | * @param endpoint Destination of payload, part after host name in URL. |
66 | | - * @param buffer Payload to send. |
67 | | - * @param buffer_size Size of payload. |
| 66 | + * @param data Payload to send. |
| 67 | + * @param data_length Length of payload. |
68 | 68 | * @param method POST(0) or PUT(1). |
| 69 | + * @param header Optional header. |
| 70 | + * @param header_length Length of header. |
69 | 71 | */ |
70 | 72 | static HttpResponse sendData(const char* endpoint, |
71 | | - const uint8_t* buffer, |
72 | | - const uint32_t buffer_size, |
73 | | - const uint8_t method) { |
| 73 | + const uint8_t* data, |
| 74 | + const uint32_t data_length, |
| 75 | + const uint8_t method, |
| 76 | + const uint8_t* header = NULL, |
| 77 | + const uint32_t header_length = 0) { |
74 | 78 |
|
75 | 79 | HttpResponse http_response = {0, 0}; |
76 | 80 |
|
77 | 81 | // Setup and transmit SEND command before sending the data |
78 | | - const uint32_t digits_in_data_length = trunc(log10(buffer_size)) + 1; |
| 82 | + const uint32_t digits_in_data_length = trunc(log10(data_length)) + 1; |
| 83 | + |
| 84 | + const uint32_t command_length = strlen(HTTP_SEND) + strlen(endpoint) + |
| 85 | + digits_in_data_length + header_length; |
| 86 | + |
| 87 | + // Append +1 for NULL termination |
| 88 | + char command[command_length + 1]; |
| 89 | + |
| 90 | + // Append +1 for NULL termination |
| 91 | + snprintf(command, |
| 92 | + command_length + 1, |
| 93 | + HTTP_SEND, |
| 94 | + method, |
| 95 | + endpoint, |
| 96 | + (unsigned long)data_length, |
| 97 | + header == NULL ? "" : (const char*)header); |
| 98 | + |
| 99 | + SequansController.writeBytes((uint8_t*)command, command_length, true); |
| 100 | + |
| 101 | + // Only send the data payload if there is any |
| 102 | + if (data_length > 0) { |
| 103 | + |
| 104 | + if (!SequansController.waitForByte(HTTP_SEND_START_CHARACTER, |
| 105 | + HTTP_TIMEOUT)) { |
| 106 | + Log.error("Timed out whilst waiting on delivering the HTTP " |
| 107 | + "payload. Is the " |
| 108 | + "server online?"); |
| 109 | + return http_response; |
| 110 | + } |
79 | 111 |
|
80 | | - char command[strlen(HTTP_SEND) + strlen(endpoint) + digits_in_data_length]; |
81 | | - sprintf(command, HTTP_SEND, method, endpoint, (unsigned long)buffer_size); |
82 | | - SequansController.writeBytes((uint8_t*)command, strlen(command), true); |
| 112 | + // Wait some before delivering the payload. The modem might hang if we |
| 113 | + // deliver it too quickly |
| 114 | + delay(100); |
83 | 115 |
|
84 | | - if (!SequansController.waitForByte(HTTP_SEND_START_CHARACTER, |
85 | | - HTTP_TIMEOUT)) { |
86 | | - Log.error( |
87 | | - "Timed out whilst waiting on delivering the HTTP payload. Is the " |
88 | | - "server online?"); |
89 | | - return http_response; |
| 116 | + // Now we deliver the payload |
| 117 | + SequansController.writeBytes(data, data_length); |
90 | 118 | } |
91 | 119 |
|
92 | | - // Wait some before delivering the payload. The modem might hang if we |
93 | | - // deliver it too quickly |
94 | | - delay(100); |
95 | | - |
96 | | - // Now we deliver the payload |
97 | | - SequansController.writeBytes(buffer, buffer_size); |
98 | | - |
99 | 120 | char http_response_buffer[HTTP_RESPONSE_MAX_LENGTH] = ""; |
100 | 121 | char http_status_code_buffer[HTTP_RESPONSE_STATUS_CODE_LENGTH + 1] = ""; |
101 | 122 | char data_size_buffer[HTTP_RESPONSE_DATA_SIZE_LENGTH] = ""; |
@@ -141,18 +162,30 @@ static HttpResponse sendData(const char* endpoint, |
141 | 162 | * |
142 | 163 | * @param endpoint Destination of retrieve, part after host name in URL. |
143 | 164 | * @param method GET(0), HEAD(1) or DELETE(2). |
| 165 | + * @param header Optional header. |
| 166 | + * @param header_length Length of header. |
144 | 167 | */ |
145 | | -static HttpResponse queryData(const char* endpoint, const uint8_t method) { |
| 168 | +static HttpResponse queryData(const char* endpoint, |
| 169 | + const uint8_t method, |
| 170 | + const uint8_t* header, |
| 171 | + const uint32_t header_length) { |
146 | 172 |
|
147 | 173 | HttpResponse http_response = {0, 0}; |
148 | 174 |
|
149 | | - // Fix for bringing the modem out of idling and prevent timeout whilst |
150 | | - // waiting for modem response during the next AT command |
151 | | - SequansController.writeCommand("AT"); |
152 | | - |
153 | 175 | // Set up and send the query |
154 | | - char command[strlen(HTTP_QUERY) + strlen(endpoint)]; |
155 | | - sprintf(command, HTTP_QUERY, method, endpoint); |
| 176 | + const uint32_t command_length = strlen(HTTP_QUERY) + strlen(endpoint) + |
| 177 | + header_length; |
| 178 | + |
| 179 | + // Append +1 for NULL termination |
| 180 | + char command[command_length + 1]; |
| 181 | + |
| 182 | + snprintf(command, |
| 183 | + command_length + 1, |
| 184 | + HTTP_QUERY, |
| 185 | + method, |
| 186 | + endpoint, |
| 187 | + header == NULL ? "" : (const char*)header); |
| 188 | + |
156 | 189 | SequansController.writeCommand(command); |
157 | 190 |
|
158 | 191 | char http_response_buffer[HTTP_RESPONSE_MAX_LENGTH] = ""; |
@@ -243,35 +276,70 @@ bool HttpClientClass::configure(const char* host, |
243 | 276 | } |
244 | 277 |
|
245 | 278 | HttpResponse HttpClientClass::post(const char* endpoint, |
246 | | - const uint8_t* buffer, |
247 | | - const uint32_t buffer_size) { |
248 | | - return sendData(endpoint, buffer, buffer_size, HTTP_POST_METHOD); |
| 279 | + const uint8_t* data_buffer, |
| 280 | + const uint32_t data_length, |
| 281 | + const uint8_t* header_buffer, |
| 282 | + const uint32_t header_length) { |
| 283 | + return sendData(endpoint, |
| 284 | + data_buffer, |
| 285 | + data_length, |
| 286 | + HTTP_POST_METHOD, |
| 287 | + header_buffer, |
| 288 | + header_length); |
249 | 289 | } |
250 | 290 |
|
251 | | -HttpResponse HttpClientClass::post(const char* endpoint, const char* message) { |
252 | | - return post(endpoint, (uint8_t*)message, strlen(message)); |
| 291 | +HttpResponse HttpClientClass::post(const char* endpoint, |
| 292 | + const char* data, |
| 293 | + const char* header) { |
| 294 | + return post(endpoint, |
| 295 | + (uint8_t*)data, |
| 296 | + strlen(data), |
| 297 | + (uint8_t*)header, |
| 298 | + strlen(header)); |
253 | 299 | } |
254 | 300 |
|
255 | 301 | HttpResponse HttpClientClass::put(const char* endpoint, |
256 | | - const uint8_t* buffer, |
257 | | - const uint32_t buffer_size) { |
258 | | - return sendData(endpoint, buffer, buffer_size, HTTP_PUT_METHOD); |
| 302 | + const uint8_t* data_buffer, |
| 303 | + const uint32_t data_length, |
| 304 | + const uint8_t* header_buffer, |
| 305 | + const uint32_t header_length) { |
| 306 | + return sendData(endpoint, |
| 307 | + data_buffer, |
| 308 | + data_length, |
| 309 | + HTTP_PUT_METHOD, |
| 310 | + header_buffer, |
| 311 | + header_length); |
259 | 312 | } |
260 | 313 |
|
261 | | -HttpResponse HttpClientClass::put(const char* endpoint, const char* message) { |
262 | | - return put(endpoint, (uint8_t*)message, strlen(message)); |
| 314 | +HttpResponse HttpClientClass::put(const char* endpoint, |
| 315 | + const char* message, |
| 316 | + const char* header) { |
| 317 | + return put(endpoint, |
| 318 | + (uint8_t*)message, |
| 319 | + strlen(message), |
| 320 | + (uint8_t*)header, |
| 321 | + strlen(header)); |
263 | 322 | } |
264 | 323 |
|
265 | | -HttpResponse HttpClientClass::get(const char* endpoint) { |
266 | | - return queryData(endpoint, HTTP_GET_METHOD); |
| 324 | +HttpResponse HttpClientClass::get(const char* endpoint, const char* header) { |
| 325 | + return queryData(endpoint, |
| 326 | + HTTP_GET_METHOD, |
| 327 | + (uint8_t*)header, |
| 328 | + strlen(header)); |
267 | 329 | } |
268 | 330 |
|
269 | | -HttpResponse HttpClientClass::head(const char* endpoint) { |
270 | | - return queryData(endpoint, HTTP_HEAD_METHOD); |
| 331 | +HttpResponse HttpClientClass::head(const char* endpoint, const char* header) { |
| 332 | + return queryData(endpoint, |
| 333 | + HTTP_HEAD_METHOD, |
| 334 | + (uint8_t*)header, |
| 335 | + strlen(header)); |
271 | 336 | } |
272 | 337 |
|
273 | | -HttpResponse HttpClientClass::del(const char* endpoint) { |
274 | | - return queryData(endpoint, HTTP_DELETE_METHOD); |
| 338 | +HttpResponse HttpClientClass::del(const char* endpoint, const char* header) { |
| 339 | + return queryData(endpoint, |
| 340 | + HTTP_DELETE_METHOD, |
| 341 | + (uint8_t*)header, |
| 342 | + strlen(header)); |
275 | 343 | } |
276 | 344 |
|
277 | 345 | int16_t HttpClientClass::readBody(char* buffer, const uint32_t buffer_size) { |
|
0 commit comments