1010#include <net/socket.h>
1111#include <modem/modem_info.h>
1212#include <net/tls_credentials.h>
13+ #include <sys/ring_buffer.h>
1314#include "slm_util.h"
1415#include "slm_at_host.h"
1516#include "slm_at_tcp_proxy.h"
@@ -39,21 +40,25 @@ enum slm_tcp_proxy_at_cmd_type {
3940 AT_TCP_SERVER ,
4041 AT_TCP_CLIENT ,
4142 AT_TCP_SEND ,
43+ AT_TCP_RECV ,
4244 AT_TCP_PROXY_MAX
4345};
4446
4547/** forward declaration of cmd handlers **/
4648static int handle_at_tcp_server (enum at_cmd_type cmd_type );
4749static int handle_at_tcp_client (enum at_cmd_type cmd_type );
4850static int handle_at_tcp_send (enum at_cmd_type cmd_type );
51+ static int handle_at_tcp_recv (enum at_cmd_type cmd_type );
4952
5053/**@brief SLM AT Command list type. */
5154static slm_at_cmd_list_t m_tcp_proxy_at_list [AT_TCP_PROXY_MAX ] = {
5255 {AT_TCP_SERVER , "AT#XTCPSVR" , handle_at_tcp_server },
5356 {AT_TCP_CLIENT , "AT#XTCPCLI" , handle_at_tcp_client },
5457 {AT_TCP_SEND , "AT#XTCPSEND" , handle_at_tcp_send },
58+ {AT_TCP_RECV , "AT#XTCPRECV" , handle_at_tcp_recv },
5559};
5660
61+ RING_BUF_DECLARE (data_buf , CONFIG_AT_CMD_RESPONSE_MAX_LEN / 2 );
5762static u8_t data_hex [DATA_HEX_MAX_SIZE ];
5863static struct k_thread tcp_thread ;
5964static K_THREAD_STACK_DEFINE (tcp_thread_stack , THREAD_STACK_SIZE ) ;
@@ -344,6 +349,15 @@ static int do_tcp_send(const u8_t *data, int datalen)
344349 }
345350}
346351
352+ static int tcp_data_save (u8_t * data , u32_t length )
353+ {
354+ if (ring_buf_space_get (& data_buf ) < length ) {
355+ return -1 ; /* RX overrun */
356+ }
357+
358+ return ring_buf_put (& data_buf , data , length );
359+ }
360+
347361static void tcp_thread_func (void * p1 , void * p2 , void * p3 )
348362{
349363 int ret ;
@@ -387,11 +401,14 @@ static void tcp_thread_func(void *p1, void *p2, void *p3)
387401 }
388402 fds .fd = sock ;
389403 fds .events = POLLIN ;
404+ ring_buf_reset (& data_buf );
390405 while (true) {
391406 if (proxy .role == AT_TCP_ROLE_SERVER &&
392407 k_timer_status_get (& conn_timer ) > 0 ) {
393408 k_timer_stop (& conn_timer );
394409 LOG_INF ("Connecion timeout" );
410+ sprintf (rsp_buf , "#XTCPSVR: timeout\r\n" );
411+ rsp_send (rsp_buf , strlen (rsp_buf ));
395412 close (proxy .sock_peer );
396413 goto thread_entry ;
397414 }
@@ -418,30 +435,38 @@ static void tcp_thread_func(void *p1, void *p2, void *p3)
418435 if (slm_util_hex_check (data , ret )) {
419436 ret = slm_util_htoa (data , ret , data_hex ,
420437 DATA_HEX_MAX_SIZE );
421- if (ret > 0 ) {
438+ if (ret < 0 ) {
439+ LOG_ERR ("hex convert error: %d" , ret );
440+ continue ;
441+ }
442+ if (tcp_data_save (data_hex , ret ) < 0 ) {
422443 sprintf (rsp_buf ,
423- "#XTCPRECV: %d, %d\r\n" ,
424- DATATYPE_HEXADECIMAL , ret );
425- rsp_send (rsp_buf , strlen (rsp_buf ));
426- rsp_send (data_hex , ret );
427- rsp_send ("\r\n" , 2 );
444+ "#XTCPDATA: overrun\r\n" );
428445 } else {
429- LOG_ERR ("hex convert error: %d" , ret );
446+ sprintf (rsp_buf ,
447+ "#XTCPDATA: %d, %d\r\n" ,
448+ DATATYPE_HEXADECIMAL ,
449+ ret );
430450 }
451+ rsp_send (rsp_buf , strlen (rsp_buf ));
431452 } else {
432- sprintf (rsp_buf , "#XTCPRECV: %d, %d\r\n" ,
433- DATATYPE_PLAINTEXT , ret );
453+ if (tcp_data_save (data , ret ) < 0 ) {
454+ sprintf (rsp_buf ,
455+ "#XTCPDATA: overrun\r\n" );
456+ } else {
457+ sprintf (rsp_buf ,
458+ "#XTCPDATA: %d, %d\r\n" ,
459+ DATATYPE_PLAINTEXT , ret );
460+ }
434461 rsp_send (rsp_buf , strlen (rsp_buf ));
435- rsp_send (data , ret );
436- rsp_send ("\r\n" , 2 );
437462 }
438463 }
439464 }
440465}
441466
442467/**@brief handle AT#XTCPSVR commands
443468 * AT#XTCPSVR=<op>[,<port>[,[sec_tag]]
444- * AT#XTCPSVR? READ command not supported
469+ * AT#XTCPSVR?
445470 * AT#XTCPSVR=?
446471 */
447472static int handle_at_tcp_server (enum at_cmd_type cmd_type )
@@ -482,6 +507,15 @@ static int handle_at_tcp_server(enum at_cmd_type cmd_type)
482507 err = do_tcp_server_stop (0 );
483508 } break ;
484509
510+ case AT_CMD_TYPE_READ_COMMAND :
511+ if (proxy .role == AT_TCP_ROLE_SERVER ) {
512+ sprintf (rsp_buf , "#XTCPSVR: %d, %d\r\n" ,
513+ proxy .sock , proxy .sock_peer );
514+ rsp_send (rsp_buf , strlen (rsp_buf ));
515+ }
516+ err = 0 ;
517+ break ;
518+
485519 case AT_CMD_TYPE_TEST_COMMAND :
486520 sprintf (rsp_buf , "#XTCPSVR: (%d, %d),<port>,<sec_tag>\r\n" ,
487521 AT_SERVER_STOP , AT_SERVER_START );
@@ -498,7 +532,7 @@ static int handle_at_tcp_server(enum at_cmd_type cmd_type)
498532
499533/**@brief handle AT#XTCPCLI commands
500534 * AT#XTCPCLI=<op>[,<url>,<port>[,[sec_tag]]
501- * AT#XTCPCLI? READ command not supported
535+ * AT#XTCPCLI?
502536 * AT#XTCPCLI=?
503537 */
504538static int handle_at_tcp_client (enum at_cmd_type cmd_type )
@@ -547,6 +581,14 @@ static int handle_at_tcp_client(enum at_cmd_type cmd_type)
547581 err = do_tcp_client_disconnect (0 );
548582 } break ;
549583
584+ case AT_CMD_TYPE_READ_COMMAND :
585+ if (proxy .role == AT_TCP_ROLE_CLIENT ) {
586+ sprintf (rsp_buf , "#XTCPCLI: %d\r\n" , proxy .sock );
587+ rsp_send (rsp_buf , strlen (rsp_buf ));
588+ }
589+ err = 0 ;
590+ break ;
591+
550592 case AT_CMD_TYPE_TEST_COMMAND :
551593 sprintf (rsp_buf ,
552594 "#XTCPCLI: (%d, %d),<url>,<port>,<sec_tag>\r\n" ,
@@ -606,6 +648,38 @@ static int handle_at_tcp_send(enum at_cmd_type cmd_type)
606648 return err ;
607649}
608650
651+ /**@brief handle AT#XTCPRECV commands
652+ * AT#XTCPRECV
653+ * AT#XTCPRECV? READ command not supported
654+ * AT#XTCPRECV=? TEST command not supported
655+ */
656+ static int handle_at_tcp_recv (enum at_cmd_type cmd_type )
657+ {
658+ int err = - EINVAL ;
659+
660+ switch (cmd_type ) {
661+ case AT_CMD_TYPE_SET_COMMAND :
662+ {
663+ u32_t sz_send = 0 ;
664+
665+ if (ring_buf_is_empty (& data_buf ) == 0 ) {
666+ sz_send = ring_buf_get (& data_buf , rsp_buf ,
667+ sizeof (rsp_buf ));
668+ rsp_send (rsp_buf , sz_send );
669+ rsp_send ("\r\n" , 2 );
670+ }
671+ sprintf (rsp_buf , "#XTCPRECV: %d\r\n" , sz_send );
672+ rsp_send (rsp_buf , strlen (rsp_buf ));
673+ err = 0 ;
674+ } break ;
675+
676+ default :
677+ break ;
678+ }
679+
680+ return err ;
681+ }
682+
609683/**@brief API to handle TCP proxy AT commands
610684 */
611685int slm_at_tcp_proxy_parse (const char * at_cmd )
0 commit comments