@@ -776,6 +776,223 @@ void test_xconnect_operation(void)
776776 send_at_command ("AT#XCLOSE=1\r\n" );
777777}
778778
779+ /*
780+ * Test: Socket listen operation via AT command
781+ * - Command: AT#XLISTEN=<handle>\r\n
782+ * - Tests: Putting a TCP socket into listening mode
783+ */
784+ void test_xlisten_operation (void )
785+ {
786+ const char * response ;
787+ const char * cgpaddr_resp = "+CGPADDR: 0,\"10.0.0.1\",\"\"\r\nOK\r\n" ;
788+
789+ /* Create TCP server socket first */
790+ __cmock_nrf_socket_ExpectAndReturn (NRF_AF_INET , NRF_SOCK_STREAM , NRF_IPPROTO_TCP , 5 );
791+ __cmock_nrf_setsockopt_ExpectAnyArgsAndReturn (0 ); /* SO_SNDTIMEO */
792+ __cmock_nrf_setsockopt_ExpectAnyArgsAndReturn (0 ); /* SO_POLLCB */
793+ send_at_command ("AT#XSOCKET=1,1,1\r\n" ); /* family=1, type=1, role=1 (server) */
794+ response = get_captured_response ();
795+ TEST_ASSERT_TRUE (strstr (response , "#XSOCKET: 5,1,6" ) != NULL );
796+ clear_captured_response ();
797+
798+ /* Bind to port 8080 before listening */
799+ __cmock_nrf_modem_at_cmd_CMockExpectAnyArgsAndReturn (__LINE__ , 0 );
800+ __cmock_nrf_modem_at_cmd_CMockReturnMemThruPtr_buf (__LINE__ , (void * )cgpaddr_resp ,
801+ strlen (cgpaddr_resp ) + 1 );
802+ __cmock_nrf_modem_at_cmd_CMockIgnoreArg_len (__LINE__ );
803+ __cmock_nrf_modem_at_cmd_CMockIgnoreArg_fmt (__LINE__ );
804+ __cmock_zsock_inet_pton_ExpectAnyArgsAndReturn (1 );
805+ __cmock_nrf_inet_pton_ExpectAnyArgsAndReturn (1 );
806+ __cmock_nrf_bind_ExpectAndReturn (5 , NULL , sizeof (struct nrf_sockaddr_in ), 0 );
807+ __cmock_nrf_bind_IgnoreArg_address ();
808+ __cmock_nrf_bind_IgnoreArg_address_len ();
809+ send_at_command ("AT#XBIND=5,8080\r\n" );
810+ response = get_captured_response ();
811+ TEST_ASSERT_TRUE (strstr (response , "OK" ) != NULL );
812+ clear_captured_response ();
813+
814+ /* Mock fcntl to set non-blocking mode and listen */
815+ __cmock_nrf_fcntl_ExpectAndReturn (5 , NRF_F_SETFL , NRF_O_NONBLOCK , 0 );
816+ __cmock_nrf_listen_ExpectAndReturn (5 , 2 , 0 ); /* backlog=2 (fixed in modem) */
817+
818+ /* Execute listen command */
819+ send_at_command ("AT#XLISTEN=5\r\n" );
820+
821+ /* Verify successful listen response */
822+ response = get_captured_response ();
823+ if (strstr (response , "OK" ) == NULL ) {
824+ printf ("XLISTEN response: %s\n" , response );
825+ }
826+ TEST_ASSERT_TRUE (strstr (response , "OK" ) != NULL );
827+
828+ /* Close socket */
829+ __cmock_nrf_close_ExpectAndReturn (5 , 0 );
830+ send_at_command ("AT#XCLOSE=5\r\n" );
831+ }
832+
833+ /*
834+ * Test: AT#XLISTEN? (READ command type)
835+ * - Verifies READ command lists all listening sockets
836+ */
837+ void test_xlisten_read_command (void )
838+ {
839+ const char * response ;
840+ const char * cgpaddr_resp = "+CGPADDR: 0,\"10.0.0.1\",\"\"\r\nOK\r\n" ;
841+
842+ /* Create TCP server socket */
843+ __cmock_nrf_socket_ExpectAndReturn (NRF_AF_INET , NRF_SOCK_STREAM , NRF_IPPROTO_TCP , 3 );
844+ __cmock_nrf_setsockopt_ExpectAnyArgsAndReturn (0 );
845+ __cmock_nrf_setsockopt_ExpectAnyArgsAndReturn (0 );
846+ send_at_command ("AT#XSOCKET=1,1,1\r\n" );
847+ clear_captured_response ();
848+
849+ /* Bind to port 9000 */
850+ __cmock_nrf_modem_at_cmd_CMockExpectAnyArgsAndReturn (__LINE__ , 0 );
851+ __cmock_nrf_modem_at_cmd_CMockReturnMemThruPtr_buf (__LINE__ , (void * )cgpaddr_resp ,
852+ strlen (cgpaddr_resp ) + 1 );
853+ __cmock_nrf_modem_at_cmd_CMockIgnoreArg_len (__LINE__ );
854+ __cmock_nrf_modem_at_cmd_CMockIgnoreArg_fmt (__LINE__ );
855+ __cmock_zsock_inet_pton_ExpectAnyArgsAndReturn (1 );
856+ __cmock_nrf_inet_pton_ExpectAnyArgsAndReturn (1 );
857+ __cmock_nrf_bind_ExpectAndReturn (3 , NULL , sizeof (struct nrf_sockaddr_in ), 0 );
858+ __cmock_nrf_bind_IgnoreArg_address ();
859+ __cmock_nrf_bind_IgnoreArg_address_len ();
860+ send_at_command ("AT#XBIND=3,9000\r\n" );
861+ clear_captured_response ();
862+
863+ /* Put socket in listening mode */
864+ __cmock_nrf_fcntl_ExpectAndReturn (3 , NRF_F_SETFL , NRF_O_NONBLOCK , 0 );
865+ __cmock_nrf_listen_ExpectAndReturn (3 , 2 , 0 );
866+ send_at_command ("AT#XLISTEN=3\r\n" );
867+ clear_captured_response ();
868+
869+ /* Execute read command */
870+ send_at_command ("AT#XLISTEN?\r\n" );
871+
872+ /* Verify response contains listening socket details */
873+ response = get_captured_response ();
874+ /* Format: #XLISTEN: <handle>,<cid>,<local_port> */
875+ TEST_ASSERT_TRUE (strstr (response , "#XLISTEN: 3,0,9000" ) != NULL );
876+ TEST_ASSERT_TRUE (strstr (response , "OK" ) != NULL );
877+
878+ /* Close socket */
879+ __cmock_nrf_close_ExpectAndReturn (3 , 0 );
880+ send_at_command ("AT#XCLOSE=3\r\n" );
881+ }
882+
883+ /*
884+ * Test: AT#XLISTEN with socket that is not bound
885+ * - Should fail because socket must be bound before listen
886+ */
887+ void test_xlisten_not_bound (void )
888+ {
889+ const char * response ;
890+
891+ /* Create TCP server socket but don't bind it */
892+ __cmock_nrf_socket_ExpectAndReturn (NRF_AF_INET , NRF_SOCK_STREAM , NRF_IPPROTO_TCP , 2 );
893+ __cmock_nrf_setsockopt_ExpectAnyArgsAndReturn (0 );
894+ __cmock_nrf_setsockopt_ExpectAnyArgsAndReturn (0 );
895+ send_at_command ("AT#XSOCKET=1,1,1\r\n" );
896+ clear_captured_response ();
897+
898+ /* Try to listen without binding - should fail */
899+ send_at_command ("AT#XLISTEN=2\r\n" );
900+
901+ /* Verify error response */
902+ response = get_captured_response ();
903+ TEST_ASSERT_TRUE (strstr (response , "ERROR" ) != NULL );
904+
905+ /* Close socket */
906+ __cmock_nrf_close_ExpectAndReturn (2 , 0 );
907+ send_at_command ("AT#XCLOSE=2\r\n" );
908+ }
909+
910+ /*
911+ * Test: Socket accept operation via AT command
912+ * - Command: AT#XACCEPT=<handle>\r\n
913+ * - Tests: Accepting an incoming connection on a listening socket
914+ */
915+ void test_xaccept_operation (void )
916+ {
917+ const char * response ;
918+ const char * cgpaddr_resp = "+CGPADDR: 0,\"10.0.0.1\",\"\"\r\nOK\r\n" ;
919+
920+ /* Create TCP server socket */
921+ __cmock_nrf_socket_ExpectAndReturn (NRF_AF_INET , NRF_SOCK_STREAM , NRF_IPPROTO_TCP , 1 );
922+ __cmock_nrf_setsockopt_ExpectAnyArgsAndReturn (0 );
923+ __cmock_nrf_setsockopt_ExpectAnyArgsAndReturn (0 );
924+ send_at_command ("AT#XSOCKET=1,1,1\r\n" );
925+ clear_captured_response ();
926+
927+ /* Bind to port 7000 */
928+ __cmock_nrf_modem_at_cmd_CMockExpectAnyArgsAndReturn (__LINE__ , 0 );
929+ __cmock_nrf_modem_at_cmd_CMockReturnMemThruPtr_buf (__LINE__ , (void * )cgpaddr_resp ,
930+ strlen (cgpaddr_resp ) + 1 );
931+ __cmock_nrf_modem_at_cmd_CMockIgnoreArg_len (__LINE__ );
932+ __cmock_nrf_modem_at_cmd_CMockIgnoreArg_fmt (__LINE__ );
933+ __cmock_zsock_inet_pton_ExpectAnyArgsAndReturn (1 );
934+ __cmock_nrf_inet_pton_ExpectAnyArgsAndReturn (1 );
935+ __cmock_nrf_bind_ExpectAndReturn (1 , NULL , sizeof (struct nrf_sockaddr_in ), 0 );
936+ __cmock_nrf_bind_IgnoreArg_address ();
937+ __cmock_nrf_bind_IgnoreArg_address_len ();
938+ send_at_command ("AT#XBIND=1,7000\r\n" );
939+ clear_captured_response ();
940+
941+ /* Put socket in listening mode */
942+ __cmock_nrf_fcntl_ExpectAndReturn (1 , NRF_F_SETFL , NRF_O_NONBLOCK , 0 );
943+ __cmock_nrf_listen_ExpectAndReturn (1 , 2 , 0 );
944+ send_at_command ("AT#XLISTEN=1\r\n" );
945+ clear_captured_response ();
946+
947+ /* Mock successful accept - returns new socket fd=7 */
948+ __cmock_nrf_accept_ExpectAnyArgsAndReturn (7 );
949+ __cmock_zsock_inet_ntop_ExpectAnyArgsAndReturn ("192.168.1.100" ); /* util_get_peer_addr */
950+ __cmock_nrf_setsockopt_ExpectAnyArgsAndReturn (0 ); /* POLLCB for new socket */
951+ __cmock_nrf_setsockopt_ExpectAnyArgsAndReturn (0 ); /* POLLCB restore for listening socket */
952+
953+ /* Execute accept command */
954+ send_at_command ("AT#XACCEPT=1\r\n" );
955+
956+ /* Verify successful accept response */
957+ /* Format: #XACCEPT: <new_handle>,<cid>,"<peer_addr>",<peer_port> */
958+ response = get_captured_response ();
959+ TEST_ASSERT_TRUE (strstr (response , "#XACCEPT: 7,0," ) != NULL );
960+ TEST_ASSERT_TRUE (strstr (response , "OK" ) != NULL );
961+
962+ /* Close sockets */
963+ __cmock_nrf_close_ExpectAndReturn (7 , 0 );
964+ send_at_command ("AT#XCLOSE=7\r\n" );
965+ __cmock_nrf_close_ExpectAndReturn (1 , 0 );
966+ send_at_command ("AT#XCLOSE=1\r\n" );
967+ }
968+
969+ /*
970+ * Test: AT#XACCEPT with socket that is not listening
971+ * - Should fail because socket must be in listening mode
972+ */
973+ void test_xaccept_not_listening (void )
974+ {
975+ const char * response ;
976+
977+ /* Create TCP client socket (not server) */
978+ __cmock_nrf_socket_ExpectAndReturn (NRF_AF_INET , NRF_SOCK_STREAM , NRF_IPPROTO_TCP , 4 );
979+ __cmock_nrf_setsockopt_ExpectAnyArgsAndReturn (0 );
980+ __cmock_nrf_setsockopt_ExpectAnyArgsAndReturn (0 );
981+ send_at_command ("AT#XSOCKET=1,1,0\r\n" ); /* role=0 (client) */
982+ clear_captured_response ();
983+
984+ /* Try to accept on a client socket - should fail */
985+ send_at_command ("AT#XACCEPT=4\r\n" );
986+
987+ /* Verify error response */
988+ response = get_captured_response ();
989+ TEST_ASSERT_TRUE (strstr (response , "ERROR" ) != NULL );
990+
991+ /* Close socket */
992+ __cmock_nrf_close_ExpectAndReturn (4 , 0 );
993+ send_at_command ("AT#XCLOSE=4\r\n" );
994+ }
995+
779996/*
780997 * Test: Send data via AT#XSEND with unformatted string
781998 * - Command: AT#XSEND=<handle>,<mode>,<flags>,"<data>"\r\n
@@ -2486,7 +2703,6 @@ void test_xssocket_read_operation(void)
24862703 __cmock_nrf_setsockopt_ExpectAnyArgsAndReturn (0 ); /* SO_SNDTIMEO */
24872704 __cmock_nrf_setsockopt_ExpectAnyArgsAndReturn (0 ); /* SO_SEC_TAG_LIST */
24882705 __cmock_nrf_setsockopt_ExpectAnyArgsAndReturn (0 ); /* SO_SEC_PEER_VERIFY */
2489- __cmock_nrf_setsockopt_ExpectAnyArgsAndReturn (0 ); /* SO_SEC_ROLE */
24902706 __cmock_nrf_setsockopt_ExpectAnyArgsAndReturn (0 ); /* SO_POLLCB */
24912707 send_at_command ("AT#XSSOCKET=2,1,1,42\r\n" );
24922708 response = get_captured_response ();
@@ -2657,26 +2873,11 @@ void test_xssocket_ipv4_tcp_server(void)
26572873 * 1. SO_SNDTIMEO (SOL_SOCKET)
26582874 * 2. SO_SEC_TAG_LIST (SOL_SECURE)
26592875 * 3. SO_SEC_PEER_VERIFY (SOL_SECURE)
2660- * 4. SO_SEC_ROLE (SOL_SECURE) - server only, verified below
2661- * 5. SO_POLLCB (SOL_SOCKET)
2876+ * 4. SO_POLLCB (SOL_SOCKET)
26622877 */
26632878 __cmock_nrf_setsockopt_ExpectAnyArgsAndReturn (0 ); /* SO_SNDTIMEO */
26642879 __cmock_nrf_setsockopt_ExpectAnyArgsAndReturn (0 ); /* SO_SEC_TAG_LIST */
26652880 __cmock_nrf_setsockopt_ExpectAnyArgsAndReturn (0 ); /* SO_SEC_PEER_VERIFY */
2666-
2667- /* Verify SO_SEC_ROLE is set to server (value 1) */
2668- int expected_role = 1 ; /* NRF_SO_SEC_ROLE_SERVER */
2669-
2670- __cmock_nrf_setsockopt_ExpectWithArrayAndReturn (
2671- 0 , /* socket fd */
2672- NRF_SOL_SECURE , /* level */
2673- NRF_SO_SEC_ROLE , /* option_name */
2674- & expected_role , /* option_value */
2675- 1 , /* option_value array size */
2676- sizeof (int ), /* option_len */
2677- 0 /* return value */
2678- );
2679-
26802881 __cmock_nrf_setsockopt_ExpectAnyArgsAndReturn (0 ); /* SO_POLLCB */
26812882
26822883 /* Send AT command: family=1(IPv4), type=1(STREAM), role=1(server), sec_tag=42 */
0 commit comments