@@ -85,9 +85,11 @@ static struct sm_socket {
8585 int family ; /* Socket address family */
8686 int fd ; /* Socket descriptor. */
8787 uint16_t cid ; /* PDP Context ID, 0: primary; 1~10: secondary */
88+ uint16_t local_port ; /* Explicitly bound local port. */
8889 int send_flags ; /* Send flags */
8990 bool send_cb_set : 1 ; /* Send callback set */
9091 bool connected : 1 ; /* Connected flag. */
92+ bool listen : 1 ; /* Listen flag for TCP server sockets. */
9193 struct sm_async_poll async_poll ; /* Async poll info. */
9294 struct sm_send_ntf send_ntf ; /* Send notification info. */
9395} socks [SM_MAX_SOCKET_COUNT ];
@@ -122,9 +124,11 @@ static void init_socket(struct sm_socket *socket)
122124 socket -> family = NRF_AF_UNSPEC ;
123125 socket -> fd = INVALID_SOCKET ;
124126 socket -> cid = 0 ;
127+ socket -> local_port = 0 ;
125128 socket -> send_flags = 0 ;
126129 socket -> send_cb_set = false;
127130 socket -> connected = false;
131+ socket -> listen = false;
128132 socket -> send_ntf = (struct sm_send_ntf ){0 };
129133 socket -> async_poll = (struct sm_async_poll ){0 };
130134}
@@ -222,6 +226,10 @@ static void auto_reception(struct sm_socket *sock)
222226 if (sock == NULL ) {
223227 return ;
224228 }
229+ if (sock -> listen ) {
230+ return ;
231+ }
232+
225233 if (sock -> connected || sock -> type == NRF_SOCK_RAW ) {
226234 err = do_recv (sock , 0 , NRF_MSG_DONTWAIT ,
227235 sock -> async_poll .adr_hex ? AT_SOCKET_MODE_HEX
@@ -510,10 +518,6 @@ static int do_socket_open(struct sm_socket *sock)
510518 ret = nrf_socket (sock -> family , NRF_SOCK_DGRAM , NRF_IPPROTO_UDP );
511519 proto = NRF_IPPROTO_UDP ;
512520 } else if (sock -> type == NRF_SOCK_RAW ) {
513- if (sock -> role != NRF_SO_SEC_ROLE_CLIENT ) {
514- LOG_ERR ("Raw socket: Role must be client" );
515- return - EINVAL ;
516- }
517521 ret = nrf_socket (sock -> family , NRF_SOCK_RAW , NRF_IPPROTO_RAW );
518522 proto = NRF_IPPROTO_IP ;
519523 } else {
@@ -612,18 +616,6 @@ static int do_secure_socket_open(struct sm_socket *sock, int peer_verify)
612616 ret = - errno ;
613617 goto error ;
614618 }
615- /* Set up (D)TLS server role if applicable */
616- if (sock -> role == AT_SOCKET_ROLE_SERVER ) {
617- int tls_role = NRF_SO_SEC_ROLE_SERVER ;
618-
619- ret = nrf_setsockopt (sock -> fd , NRF_SOL_SECURE , NRF_SO_SEC_ROLE , & tls_role ,
620- sizeof (int ));
621- if (ret ) {
622- LOG_ERR ("nrf_setsockopt(%d) error: %d" , NRF_SO_SEC_ROLE , - errno );
623- ret = - errno ;
624- goto error ;
625- }
626- }
627619
628620 rsp_send ("\r\n#XSSOCKET: %d,%d,%d\r\n" , sock -> fd , sock -> type , proto );
629621
@@ -702,6 +694,10 @@ static int at_sockopt_to_sockopt(enum at_sockopt at_option, int *level, int *opt
702694 * level = NRF_SOL_SOCKET ;
703695 * option = NRF_SO_RAI ;
704696 break ;
697+ case AT_SO_TCP_SRV_SESSTIMEO :
698+ * level = NRF_IPPROTO_TCP ;
699+ * option = NRF_SO_TCP_SRV_SESSTIMEO ;
700+ break ;
705701
706702 default :
707703 LOG_WRN ("Unsupported option: %d" , at_option );
@@ -879,7 +875,7 @@ static int sec_sockopt_get(struct sm_socket *sock, enum at_sec_sockopt at_option
879875 return ret ;
880876}
881877
882- int bind_to_local_addr (struct sm_socket * sock , uint16_t port )
878+ static int bind_to_local_addr (struct sm_socket * sock , uint16_t port )
883879{
884880 int ret ;
885881
@@ -938,6 +934,7 @@ int bind_to_local_addr(struct sm_socket *sock, uint16_t port)
938934 return - EINVAL ;
939935 }
940936
937+ sock -> local_port = port ;
941938 return 0 ;
942939}
943940
@@ -1158,7 +1155,7 @@ static int do_recvfrom(struct sm_socket *sock, int timeout, int flags,
11581155{
11591156 int ret ;
11601157 struct net_sockaddr remote ;
1161- net_socklen_t addrlen = sizeof (struct nrf_sockaddr );
1158+ net_socklen_t addrlen = sizeof (struct net_sockaddr );
11621159 struct timeval tmo = {.tv_sec = timeout };
11631160
11641161 ret = nrf_setsockopt (sock -> fd , NRF_SOL_SOCKET , NRF_SO_RCVTIMEO , & tmo , sizeof (tmo ));
@@ -1339,15 +1336,6 @@ STATIC int handle_at_secure_socket(enum at_parser_cmd_type cmd_type,
13391336 if (err ) {
13401337 goto error ;
13411338 }
1342- /** Peer verification level for TLS connection.
1343- * - 0 - none
1344- * - 1 - optional
1345- * - 2 - required
1346- * If not set, socket will use defaults (none for servers,
1347- * required for clients)
1348- */
1349- uint16_t peer_verify ;
1350-
13511339 err = at_parser_num_get (parser , 2 , & sock -> type );
13521340 if (err ) {
13531341 goto error ;
@@ -1356,19 +1344,14 @@ STATIC int handle_at_secure_socket(enum at_parser_cmd_type cmd_type,
13561344 if (err ) {
13571345 goto error ;
13581346 }
1359- if (sock -> role == AT_SOCKET_ROLE_SERVER ) {
1360- peer_verify = ZSOCK_TLS_PEER_VERIFY_NONE ;
1361- } else if (sock -> role == AT_SOCKET_ROLE_CLIENT ) {
1362- peer_verify = ZSOCK_TLS_PEER_VERIFY_REQUIRED ;
1363- } else {
1364- err = - EINVAL ;
1365- goto error ;
1366- }
13671347 sock -> sec_tag = SEC_TAG_TLS_INVALID ;
13681348 err = at_parser_num_get (parser , 4 , & sock -> sec_tag );
13691349 if (err ) {
13701350 goto error ;
13711351 }
1352+
1353+ uint16_t peer_verify = ZSOCK_TLS_PEER_VERIFY_REQUIRED ;
1354+
13721355 if (param_count > 5 ) {
13731356 err = at_parser_num_get (parser , 5 , & peer_verify );
13741357 if (err ) {
@@ -1649,10 +1632,6 @@ STATIC int handle_at_connect(enum at_parser_cmd_type cmd_type, struct at_parser
16491632 if (sock == NULL ) {
16501633 return - EINVAL ;
16511634 }
1652- if (sock -> role != AT_SOCKET_ROLE_CLIENT ) {
1653- LOG_ERR ("Invalid role" );
1654- return - EOPNOTSUPP ;
1655- }
16561635 err = util_string_get (parser , 2 , url , & size );
16571636 if (err ) {
16581637 return err ;
@@ -1957,6 +1936,160 @@ STATIC int handle_at_recvfrom(enum at_parser_cmd_type cmd_type, struct at_parser
19571936 return err ;
19581937}
19591938
1939+ static int do_listen (struct sm_socket * sock )
1940+ {
1941+ int ret ;
1942+
1943+ if (sock -> type != NRF_SOCK_STREAM || sock -> local_port == 0 ||
1944+ sock -> sec_tag != SEC_TAG_TLS_INVALID ) {
1945+ return - EOPNOTSUPP ;
1946+ }
1947+
1948+ /* Set the socket to non-blocking mode, so accept() won't block. */
1949+ ret = nrf_fcntl (sock -> fd , NRF_F_SETFL , NRF_O_NONBLOCK );
1950+ if (ret ) {
1951+ LOG_ERR ("nrf_fcntl() failed: %d" , - errno );
1952+ return - errno ;
1953+ }
1954+
1955+ /* nRF modem ignores the backlog parameter. Backlog in modem is fixed to 2. */
1956+ ret = nrf_listen (sock -> fd , 2 );
1957+ if (ret ) {
1958+ LOG_ERR ("nrf_listen() failed: %d" , - errno );
1959+ return - errno ;
1960+ }
1961+
1962+ sock -> listen = true;
1963+
1964+ return 0 ;
1965+ }
1966+
1967+ SM_AT_CMD_CUSTOM (xlisten , "AT#XLISTEN" , handle_at_listen );
1968+ STATIC int handle_at_listen (enum at_parser_cmd_type cmd_type , struct at_parser * parser , uint32_t )
1969+ {
1970+ int err = - EINVAL ;
1971+ int fd ;
1972+
1973+ struct sm_socket * sock = NULL ;
1974+
1975+ switch (cmd_type ) {
1976+ case AT_PARSER_CMD_TYPE_SET :
1977+ err = at_parser_num_get (parser , 1 , & fd );
1978+ if (err ) {
1979+ return err ;
1980+ }
1981+ sock = find_socket (fd );
1982+ if (sock == NULL ) {
1983+ return - EINVAL ;
1984+ }
1985+ err = do_listen (sock );
1986+ break ;
1987+
1988+ case AT_PARSER_CMD_TYPE_READ :
1989+ for (int i = 0 ; i < SM_MAX_SOCKET_COUNT ; i ++ ) {
1990+ if (socks [i ].fd != INVALID_SOCKET && socks [i ].listen ) {
1991+ rsp_send ("\r\n#XLISTEN: %d,%d,%d\r\n" , socks [i ].fd , socks [i ].cid ,
1992+ socks [i ].local_port );
1993+ }
1994+ }
1995+ err = 0 ;
1996+ break ;
1997+
1998+ case AT_PARSER_CMD_TYPE_TEST :
1999+ rsp_send ("\r\n#XLISTEN: <handle>\r\n" );
2000+ err = 0 ;
2001+ break ;
2002+
2003+ default :
2004+ break ;
2005+ }
2006+
2007+ return err ;
2008+ }
2009+
2010+ static int do_accept (struct sm_socket * sock )
2011+ {
2012+ int ret ;
2013+ struct net_sockaddr remote ;
2014+ net_socklen_t addrlen = sizeof (struct net_sockaddr );
2015+ char peer_addr [NRF_INET6_ADDRSTRLEN ] = {0 };
2016+ uint16_t peer_port = 0 ;
2017+
2018+ if (sock -> type != NRF_SOCK_STREAM || !sock -> listen ) {
2019+ return - EOPNOTSUPP ;
2020+ }
2021+
2022+ ret = nrf_accept (sock -> fd , (struct nrf_sockaddr * )& remote , (nrf_socklen_t * )& addrlen );
2023+ if (ret < 0 ) {
2024+ LOG_ERR ("nrf_accept() failed: %d" , - errno );
2025+ return - errno ;
2026+ }
2027+
2028+ struct sm_socket * new_sock = find_avail_socket ();
2029+ if (new_sock == NULL ) {
2030+ LOG_ERR ("Max socket count reached, closing accepted socket" );
2031+ nrf_close (ret );
2032+ return - EINVAL ;
2033+ }
2034+ init_socket (new_sock );
2035+ new_sock -> fd = ret ;
2036+ new_sock -> family = remote .sa_family ;
2037+ new_sock -> type = NRF_SOCK_STREAM ;
2038+ new_sock -> role = AT_SOCKET_ROLE_CLIENT ;
2039+ new_sock -> cid = sock -> cid ;
2040+ new_sock -> connected = true;
2041+
2042+ util_get_peer_addr (& remote , peer_addr , & peer_port );
2043+ rsp_send ("\r\n#XACCEPT: %d,%d,\"%s\",%d\r\n" , new_sock -> fd , new_sock -> cid , peer_addr ,
2044+ peer_port );
2045+
2046+ /* Update poll events for xapoll and automatic data reception */
2047+ new_sock -> async_poll .adr_flags = poll_ctx .adr_flags ;
2048+ new_sock -> async_poll .adr_hex = poll_ctx .adr_hex ;
2049+ new_sock -> async_poll .xapoll_events_requested = poll_ctx .xapoll_events_requested ;
2050+ update_poll_events (new_sock ,
2051+ NRF_POLLIN | NRF_POLLOUT | NRF_POLLERR | NRF_POLLHUP | NRF_POLLNVAL ,
2052+ true);
2053+
2054+ /* Restore POLLIN for listening socket. */
2055+ update_poll_events (sock , NRF_POLLIN , true);
2056+
2057+ return 0 ;
2058+ }
2059+
2060+ SM_AT_CMD_CUSTOM (xaccept , "AT#XACCEPT" , handle_at_accept );
2061+ STATIC int handle_at_accept (enum at_parser_cmd_type cmd_type , struct at_parser * parser , uint32_t )
2062+ {
2063+ int err = - EINVAL ;
2064+ int fd ;
2065+
2066+ struct sm_socket * sock = NULL ;
2067+
2068+ switch (cmd_type ) {
2069+ case AT_PARSER_CMD_TYPE_SET :
2070+ err = at_parser_num_get (parser , 1 , & fd );
2071+ if (err ) {
2072+ return err ;
2073+ }
2074+ sock = find_socket (fd );
2075+ if (sock == NULL ) {
2076+ return - EINVAL ;
2077+ }
2078+ err = do_accept (sock );
2079+ break ;
2080+
2081+ case AT_PARSER_CMD_TYPE_TEST :
2082+ rsp_send ("\r\n#XACCEPT: <handle>\r\n" );
2083+ err = 0 ;
2084+ break ;
2085+
2086+ default :
2087+ break ;
2088+ }
2089+
2090+ return err ;
2091+ }
2092+
19602093SM_AT_CMD_CUSTOM (xgetaddrinfo , "AT#XGETADDRINFO" , handle_at_getaddrinfo );
19612094STATIC int handle_at_getaddrinfo (enum at_parser_cmd_type cmd_type , struct at_parser * parser ,
19622095 uint32_t param_count )
0 commit comments