4848
4949/* Offloading context related to nRF socket. */
5050static struct nrf_sock_ctx {
51- int nrf_fd ; /* nRF socket descriptior. */
51+ int nrf_fd ; /* nRF socket descriptor. */
52+ int zvfs_fd ; /* ZVFS socket descriptor. */
5253 struct k_mutex * lock ; /* Mutex associated with the socket. */
5354 struct k_poll_signal poll ; /* poll() signal. */
55+ struct socket_ncs_sendcb sendcb ; /* Send callback. */
5456} offload_ctx [NRF_MODEM_MAX_SOCKET_COUNT ];
5557
5658static K_MUTEX_DEFINE (ctx_lock );
@@ -62,7 +64,7 @@ static bool offload_disabled;
6264/* TLS offloading disabled only. */
6365static bool tls_offload_disabled ;
6466
65- static struct nrf_sock_ctx * allocate_ctx (int nrf_fd )
67+ static struct nrf_sock_ctx * allocate_ctx (int nrf_fd , int zvfs_fd )
6668{
6769 struct nrf_sock_ctx * ctx = NULL ;
6870
@@ -72,6 +74,7 @@ static struct nrf_sock_ctx *allocate_ctx(int nrf_fd)
7274 if (offload_ctx [i ].nrf_fd == -1 ) {
7375 ctx = & offload_ctx [i ];
7476 ctx -> nrf_fd = nrf_fd ;
77+ ctx -> zvfs_fd = zvfs_fd ;
7578 break ;
7679 }
7780 }
@@ -87,10 +90,23 @@ static void release_ctx(struct nrf_sock_ctx *ctx)
8790
8891 ctx -> nrf_fd = -1 ;
8992 ctx -> lock = NULL ;
93+ ctx -> zvfs_fd = -1 ;
94+ memset (& ctx -> sendcb , 0 , sizeof (ctx -> sendcb ));
9095
9196 k_mutex_unlock (& ctx_lock );
9297}
9398
99+ static struct nrf_sock_ctx * find_ctx (int fd )
100+ {
101+ for (size_t i = 0 ; i < ARRAY_SIZE (offload_ctx ); i ++ ) {
102+ if (offload_ctx [i ].nrf_fd == fd ) {
103+ return & offload_ctx [i ];
104+ }
105+ }
106+
107+ return NULL ;
108+ }
109+
94110static void z_to_nrf_ipv4 (const struct sockaddr * z_in ,
95111 struct nrf_sockaddr_in * nrf_out )
96112{
@@ -219,6 +235,9 @@ static int z_to_nrf_optname(int z_in_level, int z_in_optname,
219235 case SO_RAI :
220236 * nrf_out_optname = NRF_SO_RAI ;
221237 break ;
238+ case SO_SENDCB :
239+ * nrf_out_optname = NRF_SO_SENDCB ;
240+ break ;
222241 default :
223242 retval = -1 ;
224243 break ;
@@ -377,7 +396,7 @@ static int nrf9x_socket_offload_accept(void *obj, struct sockaddr *addr,
377396 goto error ;
378397 }
379398
380- ctx = allocate_ctx (new_sd );
399+ ctx = allocate_ctx (new_sd , fd );
381400 if (ctx == NULL ) {
382401 errno = ENOMEM ;
383402 goto error ;
@@ -475,16 +494,40 @@ static int nrf9x_socket_offload_connect(void *obj, const struct sockaddr *addr,
475494 return retval ;
476495}
477496
497+ static void sendcb (const struct nrf_modem_sendcb_params * nrf_params )
498+ {
499+ struct nrf_sock_ctx * ctx ;
500+ struct socket_ncs_sendcb_params params ;
501+
502+ ctx = find_ctx (nrf_params -> fd );
503+ if (!ctx || !ctx -> sendcb .callback ) {
504+ return ;
505+ }
506+
507+ /* The user is interested in the zvfs_fd, not nrf_fd. */
508+ params .fd = ctx -> zvfs_fd ;
509+ params .bytes_sent = nrf_params -> bytes_sent ;
510+ params .status = (nrf_params -> status == 0 ) ? 0 : EAGAIN ;
511+
512+ /* User callback. */
513+ ctx -> sendcb .callback (& params );
514+ }
515+
478516static int nrf9x_socket_offload_setsockopt (void * obj , int level , int optname ,
479517 const void * optval , socklen_t optlen )
480518{
481- int sd = OBJ_TO_SD (obj );
519+
520+ struct nrf_sock_ctx * ctx = OBJ_TO_CTX (obj );
521+ int sd = ctx -> nrf_fd ;
482522 int retval ;
483523 int nrf_level = level ;
484524 int nrf_optname ;
485525 struct nrf_timeval nrf_timeo = { 0 };
486526 void * nrf_optval = (void * )optval ;
487527 nrf_socklen_t nrf_optlen = optlen ;
528+ static struct nrf_modem_sendcb offload_sendcb = {
529+ .callback = sendcb ,
530+ };
488531
489532 if ((level == SOL_SOCKET ) && (optname == SO_BINDTODEVICE )) {
490533 if (IS_ENABLED (CONFIG_NET_SOCKETS_OFFLOAD_DISPATCHER )) {
@@ -513,6 +556,15 @@ static int nrf9x_socket_offload_setsockopt(void *obj, int level, int optname,
513556 }
514557 } else if ((level == SOL_TLS ) && (optname == TLS_SESSION_CACHE )) {
515558 nrf_optlen = sizeof (int );
559+ } else if ((level == SOL_SOCKET ) && (optname == SO_SENDCB )) {
560+ /* Register the user callback in the socket context. */
561+ if (optval != NULL ) {
562+ ctx -> sendcb = * (struct socket_ncs_sendcb * )optval ;
563+ nrf_optval = & offload_sendcb ;
564+ nrf_optlen = sizeof (struct socket_ncs_sendcb );
565+ } else {
566+ memset (& ctx -> sendcb , 0 , sizeof (ctx -> sendcb ));
567+ }
516568 }
517569
518570 retval = nrf_setsockopt (sd , nrf_level , nrf_optname , nrf_optval ,
@@ -857,17 +909,6 @@ static int nrf9x_socket_offload_fcntl(int fd, int cmd, va_list args)
857909 return retval ;
858910}
859911
860- static struct nrf_sock_ctx * find_ctx (int fd )
861- {
862- for (size_t i = 0 ; i < ARRAY_SIZE (offload_ctx ); i ++ ) {
863- if (offload_ctx [i ].nrf_fd == fd ) {
864- return & offload_ctx [i ];
865- }
866- }
867-
868- return NULL ;
869- }
870-
871912static void pollcb (struct nrf_pollfd * pollfd )
872913{
873914 struct nrf_sock_ctx * ctx ;
@@ -1095,7 +1136,7 @@ static int nrf9x_socket_create(int family, int type, int proto)
10951136 return -1 ;
10961137 }
10971138
1098- ctx = allocate_ctx (sd );
1139+ ctx = allocate_ctx (sd , fd );
10991140 if (ctx == NULL ) {
11001141 errno = ENOMEM ;
11011142 nrf_close (sd );
0 commit comments