@@ -442,70 +442,101 @@ struct net_pkt *esp_prepare_pkt(struct esp_data *dev, struct net_buf *src,
442442 */
443443#define MIN_IPD_LEN (sizeof("+IPD,I,0E") - 1)
444444#define MAX_IPD_LEN (sizeof("+IPD,I,4294967295E") - 1)
445- MODEM_CMD_DIRECT_DEFINE (on_cmd_ipd )
446- {
447- char * endptr , end , ipd_buf [MAX_IPD_LEN + 1 ];
448- int data_offset , data_len , ret ;
449- size_t match_len , frags_len ;
450- struct esp_socket * sock ;
451- struct esp_data * dev ;
452- struct net_pkt * pkt ;
453- uint8_t link_id ;
454445
455- dev = CONTAINER_OF (data , struct esp_data , cmd_handler_data );
446+ static int cmd_ipd_parse_hdr (struct net_buf * buf , uint16_t len ,
447+ uint8_t * link_id ,
448+ int * data_offset , int * data_len ,
449+ char * end )
450+ {
451+ char * endptr , ipd_buf [MAX_IPD_LEN + 1 ];
452+ size_t frags_len ;
453+ size_t match_len ;
456454
457- frags_len = net_buf_frags_len (data -> rx_buf );
455+ frags_len = net_buf_frags_len (buf );
458456
459457 /* Wait until minimum cmd length is available */
460458 if (frags_len < MIN_IPD_LEN ) {
461- ret = - EAGAIN ;
462- goto out ;
459+ return - EAGAIN ;
463460 }
464461
465462 match_len = net_buf_linearize (ipd_buf , MAX_IPD_LEN ,
466- data -> rx_buf , 0 , MAX_IPD_LEN );
463+ buf , 0 , MAX_IPD_LEN );
467464
468465 ipd_buf [match_len ] = 0 ;
469466 if (ipd_buf [len ] != ',' || ipd_buf [len + 2 ] != ',' ) {
470467 LOG_ERR ("Invalid IPD: %s" , log_strdup (ipd_buf ));
471- ret = len ;
472- goto out ;
468+ return - EBADMSG ;
473469 }
474470
475- link_id = ipd_buf [len + 1 ] - '0' ;
476- sock = esp_socket_from_link_id (dev , link_id );
477- if (sock == NULL ) {
478- LOG_ERR ("No socket for link %d" , link_id );
479- ret = len ;
480- goto out ;
471+ * link_id = ipd_buf [len + 1 ] - '0' ;
472+
473+ * data_len = strtol (& ipd_buf [len + 3 ], & endptr , 10 );
474+
475+ if (endptr == & ipd_buf [len + 3 ] ||
476+ (* endptr == 0 && match_len >= MAX_IPD_LEN )) {
477+ LOG_ERR ("Invalid IPD len: %s" , log_strdup (ipd_buf ));
478+ return - EBADMSG ;
479+ } else if (* endptr == 0 ) {
480+ return - EAGAIN ;
481481 }
482482
483+ * end = * endptr ;
484+ * data_offset = (endptr - ipd_buf ) + 1 ;
485+
486+ return 0 ;
487+ }
488+
489+ static int cmd_ipd_check_hdr_end (struct esp_socket * sock , char actual )
490+ {
491+ char expected ;
492+
483493 /* When using passive mode, the +IPD command ends with \r\n */
484494 if (ESP_PROTO_PASSIVE (sock -> ip_proto )) {
485- end = '\r' ;
495+ expected = '\r' ;
486496 } else {
487- end = ':' ;
497+ expected = ':' ;
488498 }
489499
490- data_len = strtol (& ipd_buf [len + 3 ], & endptr , 10 );
491- if (endptr == & ipd_buf [len + 3 ] ||
492- (* endptr == 0 && match_len >= MAX_IPD_LEN )) {
493- /* Invalid */
494- LOG_ERR ("Invalid IPD len: %s" , log_strdup (ipd_buf ));
495- ret = len ;
496- goto out ;
497- } else if (* endptr == 0 ) {
498- ret = - EAGAIN ;
499- goto out ;
500- } else if (* endptr != end ) {
501- LOG_ERR ("Invalid cmd end 0x%02x, expected 0x%02x" , * endptr ,
502- end );
503- ret = len ;
504- goto out ;
500+ if (expected != actual ) {
501+ LOG_ERR ("Invalid cmd end 0x%02x, expected 0x%02x" , actual ,
502+ expected );
503+ return - EBADMSG ;
505504 }
506505
507- * endptr = 0 ;
508- data_offset = strlen (ipd_buf ) + 1 ;
506+ return 0 ;
507+ }
508+
509+ MODEM_CMD_DIRECT_DEFINE (on_cmd_ipd )
510+ {
511+ struct esp_data * dev = CONTAINER_OF (data , struct esp_data ,
512+ cmd_handler_data );
513+ struct esp_socket * sock ;
514+ int data_offset , data_len ;
515+ struct net_pkt * pkt ;
516+ uint8_t link_id ;
517+ char cmd_end ;
518+ int err ;
519+
520+ err = cmd_ipd_parse_hdr (data -> rx_buf , len , & link_id , & data_offset ,
521+ & data_len , & cmd_end );
522+ if (err ) {
523+ if (err == - EAGAIN ) {
524+ return - EAGAIN ;
525+ }
526+
527+ return len ;
528+ }
529+
530+ sock = esp_socket_from_link_id (dev , link_id );
531+ if (!sock ) {
532+ LOG_ERR ("No socket for link %d" , link_id );
533+ return len ;
534+ }
535+
536+ err = cmd_ipd_check_hdr_end (sock , cmd_end );
537+ if (err ) {
538+ return len ;
539+ }
509540
510541 /*
511542 * When using passive TCP, the data itself is not included in the +IPD
@@ -514,22 +545,18 @@ MODEM_CMD_DIRECT_DEFINE(on_cmd_ipd)
514545 if (ESP_PROTO_PASSIVE (sock -> ip_proto )) {
515546 sock -> bytes_avail = data_len ;
516547 k_work_submit_to_queue (& dev -> workq , & sock -> recvdata_work );
517- ret = data_offset ;
518- goto out ;
548+ return data_offset ;
519549 }
520550
521551 /* Do we have the whole message? */
522- if (data_offset + data_len > frags_len ) {
523- ret = - EAGAIN ;
524- goto out ;
552+ if (data_offset + data_len > net_buf_frags_len (data -> rx_buf )) {
553+ return - EAGAIN ;
525554 }
526555
527- ret = data_offset + data_len ; /* Skip */
528-
529556 if ((sock -> flags & (ESP_SOCK_CONNECTED | ESP_SOCK_CLOSE_PENDING )) !=
530557 ESP_SOCK_CONNECTED ) {
531- LOG_DBG ("Received data on closed link %d" , link_id );
532- goto out ;
558+ LOG_DBG ("Received data on closed link %d" , sock -> link_id );
559+ return data_offset + data_len ;
533560 }
534561
535562 pkt = esp_prepare_pkt (dev , data -> rx_buf , data_offset , data_len );
@@ -546,8 +573,7 @@ MODEM_CMD_DIRECT_DEFINE(on_cmd_ipd)
546573submit_work :
547574 k_work_submit_to_queue (& dev -> workq , & sock -> recv_work );
548575
549- out :
550- return ret ;
576+ return data_offset + data_len ;
551577}
552578
553579MODEM_CMD_DEFINE (on_cmd_busy_sending )
0 commit comments