2020
2121LOG_MODULE_REGISTER (sm_httpc , CONFIG_SM_LOG_LEVEL );
2222
23- #define HTTP_RECV_BUF_SIZE 2048
23+ #define HTTP_RECV_BUF_SIZE 2049 /* 2048 bytes + null terminator for string ops */
2424#define HTTP_URL_MAX_LEN 512
2525#define HTTP_HOST_MAX_LEN 256
2626#define HTTP_PATH_MAX_LEN 256
@@ -82,6 +82,7 @@ struct http_request {
8282 int64_t timeout_timestamp ; /* Idle timeout deadline; reset on each send/receive */
8383 struct modem_pipe * pipe ; /* AT pipe that created this request */
8484 bool manual_mode ; /* Manual mode: body not auto-received, host pulls chunks */
85+ bool hex_rx ; /* Deliver response body as ASCII hex string */
8586 int bytes_sent ; /* Response-body bytes sent to the host */
8687 bool connection_close ; /* Server sent "Connection: close" header */
8788};
@@ -481,7 +482,22 @@ static void http_send_headers_complete(struct http_request *req)
481482 req -> content_length );
482483}
483484
484- /* Send data URC followed by raw bytes */
485+ static void http_data_send_hex (struct modem_pipe * pipe , const uint8_t * buf , size_t len )
486+ {
487+ char hex_buf [257 ];
488+ size_t chunk = (sizeof (hex_buf ) - 1 ) / 2 ;
489+ size_t done = 0 ;
490+
491+ while (done < len ) {
492+ size_t n = MIN (chunk , len - done );
493+ size_t sz = bin2hex (buf + done , n , hex_buf , sizeof (hex_buf ));
494+
495+ data_send (pipe , hex_buf , sz );
496+ done += n ;
497+ }
498+ }
499+
500+ /* Send data URC followed by raw bytes or hex string */
485501static void http_send_data (struct http_request * req , const uint8_t * data , int len )
486502{
487503 if (len <= 0 ) {
@@ -490,7 +506,11 @@ static void http_send_data(struct http_request *req, const uint8_t *data, int le
490506
491507 urc_send_to (req -> pipe , "\r\n#XHTTPCDATA: %d,%d,%d\r\n" , req -> fd , req -> bytes_sent , len );
492508 req -> bytes_sent += len ;
493- data_send (req -> pipe , data , len );
509+ if (req -> hex_rx ) {
510+ http_data_send_hex (req -> pipe , data , (size_t )len );
511+ } else {
512+ data_send (req -> pipe , data , len );
513+ }
494514}
495515
496516/*
@@ -1049,7 +1069,10 @@ static int http_datamode_callback(uint8_t op, const uint8_t *data, int len, uint
10491069 return 0 ;
10501070}
10511071
1052- /* AT#XHTTPCREQ - Start an HTTP/HTTPS request (async) */
1072+ /**
1073+ * Start an asynchronous HTTP or HTTPS request on a connected AT socket.
1074+ * Returns OK immediately; headers arrive as #XHTTPCHEAD and body as #XHTTPCDATA/#XHTTPCSTAT.
1075+ */
10531076SM_AT_CMD_CUSTOM (xhttpcreq , "AT#XHTTPCREQ" , handle_at_httpcreq );
10541077STATIC int handle_at_httpcreq (enum at_parser_cmd_type cmd_type , struct at_parser * parser ,
10551078 uint32_t param_count )
@@ -1124,7 +1147,6 @@ STATIC int handle_at_httpcreq(enum at_parser_cmd_type cmd_type, struct at_parser
11241147 return - EINVAL ;
11251148 }
11261149
1127- int body_len = 0 ;
11281150 int next_param_idx = 4 ; /* Next parameter index after method */
11291151
11301152 /* Parse optional <auto_reception> flag */
@@ -1141,22 +1163,34 @@ STATIC int handle_at_httpcreq(enum at_parser_cmd_type cmd_type, struct at_parser
11411163 /* If parse fails (string param), leave next_param_idx unchanged. */
11421164 }
11431165
1166+ /* Parse optional <format> flag */
1167+ int format = 0 ; /* default: binary */
1168+
1169+ if (param_count > next_param_idx ) {
1170+ if (at_parser_num_get (parser , next_param_idx , & format ) == 0 ) {
1171+ if (format != 0 && format != 1 ) {
1172+ http_close_request (req );
1173+ return - EINVAL ;
1174+ }
1175+ next_param_idx ++ ;
1176+ }
1177+ }
1178+
11441179 /* Parse optional body length (data mode for POST/PUT).
11451180 * The parameter slot is always consumed when an integer is present
11461181 * so that extra headers start at a consistent index regardless of method.
11471182 */
1148- if (param_count > next_param_idx ) {
1149- int tmp = 0 ;
1183+ int body_len = 0 ;
11501184
1151- if (at_parser_num_get (parser , next_param_idx , & tmp ) == 0 ) {
1185+ if (param_count > next_param_idx ) {
1186+ if (at_parser_num_get (parser , next_param_idx , & body_len ) == 0 ) {
11521187 if (method == HTTP_POST || method == HTTP_PUT ) {
1153- body_len = tmp ;
11541188 if (body_len < 0 ) {
11551189 LOG_ERR ("Invalid body_len: %d" , body_len );
11561190 http_close_request (req );
11571191 return - EINVAL ;
11581192 }
1159- } else if (tmp != 0 ) {
1193+ } else if (body_len != 0 ) {
11601194 LOG_ERR ("body_len must be 0 for method %d" , method );
11611195 http_close_request (req );
11621196 return - EINVAL ;
@@ -1227,6 +1261,8 @@ STATIC int handle_at_httpcreq(enum at_parser_cmd_type cmd_type, struct at_parser
12271261 LOG_INF ("HTTP %d: Manual mode enabled" , req -> fd );
12281262 }
12291263
1264+ req -> hex_rx = (bool )format ;
1265+
12301266 /* Parse URL */
12311267 err = http_parse_url_components (url , url_len , req );
12321268 if (err ) {
@@ -1276,7 +1312,7 @@ STATIC int handle_at_httpcreq(enum at_parser_cmd_type cmd_type, struct at_parser
12761312
12771313 case AT_PARSER_CMD_TYPE_TEST :
12781314 rsp_send ("\r\n#XHTTPCREQ: <handle>,<url>,<method>"
1279- "[,<auto_reception>[,<body_len>[,<header>]...]]\r\n" );
1315+ "[,<auto_reception>[,<format>[,< body_len>[,<header>]...] ]]\r\n" );
12801316
12811317 err = 0 ;
12821318 break ;
@@ -1330,7 +1366,11 @@ static int pull_data(int socket_fd, int pull_len)
13301366 req -> timeout_timestamp = k_uptime_get () + HTTP_RESPONSE_TIMEOUT_MS ;
13311367 rsp_send ("\r\n#XHTTPCDATA: %d,%d,%d\r\n" , req -> fd , req -> bytes_sent , send_len );
13321368 req -> bytes_sent += send_len ;
1333- data_send (req -> pipe , req -> recv_buf , send_len );
1369+ if (req -> hex_rx ) {
1370+ http_data_send_hex (req -> pipe , req -> recv_buf , (size_t )send_len );
1371+ } else {
1372+ data_send (req -> pipe , req -> recv_buf , send_len );
1373+ }
13341374 req -> recv_buf_len -= send_len ;
13351375 if (req -> recv_buf_len > 0 ) {
13361376 memmove (req -> recv_buf , req -> recv_buf + send_len , req -> recv_buf_len );
@@ -1366,7 +1406,11 @@ static int pull_data(int socket_fd, int pull_len)
13661406 req -> timeout_timestamp = k_uptime_get () + HTTP_RESPONSE_TIMEOUT_MS ;
13671407 rsp_send ("\r\n#XHTTPCDATA: %d,%d,%d\r\n" , req -> fd , req -> bytes_sent , ret );
13681408 req -> bytes_sent += ret ;
1369- data_send (req -> pipe , req -> recv_buf , ret );
1409+ if (req -> hex_rx ) {
1410+ http_data_send_hex (req -> pipe , req -> recv_buf , (size_t )ret );
1411+ } else {
1412+ data_send (req -> pipe , req -> recv_buf , ret );
1413+ }
13701414 last_sent = ret ;
13711415
13721416check_complete :
0 commit comments