1 /** @file
2  * @brief Modem socket header file.
3  *
4  * Generic modem socket and packet size implementation for modem context
5  */
6 
7 /*
8  * Copyright (c) 2019-2020 Foundries.io
9  *
10  * SPDX-License-Identifier: Apache-2.0
11  */
12 
13 #ifndef ZEPHYR_INCLUDE_DRIVERS_MODEM_MODEM_SOCKET_H_
14 #define ZEPHYR_INCLUDE_DRIVERS_MODEM_MODEM_SOCKET_H_
15 
16 #include <zephyr/kernel.h>
17 #include <zephyr/net/net_ip.h>
18 #include <zephyr/net/socket.h>
19 
20 #include "sockets_internal.h"
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 __net_socket struct modem_socket {
27 	sa_family_t family;
28 	enum net_sock_type type;
29 	int ip_proto;
30 	struct sockaddr src;
31 	struct sockaddr dst;
32 
33 	/** The number identifying the socket handle inside the modem */
34 	int id;
35 
36 	/** The file descriptor identifying the socket in the fdtable */
37 	int sock_fd;
38 
39 	/** packet data */
40 	uint16_t packet_sizes[CONFIG_MODEM_SOCKET_PACKET_COUNT];
41 	uint16_t packet_count;
42 
43 	/** data ready semaphore */
44 	struct k_sem sem_data_ready;
45 	/** data ready poll signal */
46 	struct k_poll_signal sig_data_ready;
47 
48 	/** socket state */
49 	bool is_connected;
50 	bool is_waiting;
51 
52 	/** temporary socket data */
53 	void *data;
54 };
55 
56 struct modem_socket_config {
57 	struct modem_socket *sockets;
58 	size_t sockets_len;
59 
60 	/* beginning socket id (modems can set this to 0 or 1 as needed) */
61 	int base_socket_id;
62 
63 	/* dynamically assign id when modem socket is allocated */
64 	bool assign_id;
65 
66 	struct k_sem sem_lock;
67 
68 	const struct socket_op_vtable *vtable;
69 };
70 
71 /* return size of the first packet */
72 uint16_t modem_socket_next_packet_size(struct modem_socket_config *cfg, struct modem_socket *sock);
73 int modem_socket_packet_size_update(struct modem_socket_config *cfg, struct modem_socket *sock,
74 				    int new_total);
75 int modem_socket_get(struct modem_socket_config *cfg, int family, int type, int proto);
76 struct modem_socket *modem_socket_from_fd(struct modem_socket_config *cfg, int sock_fd);
77 struct modem_socket *modem_socket_from_id(struct modem_socket_config *cfg, int id);
78 struct modem_socket *modem_socket_from_newid(struct modem_socket_config *cfg);
79 void modem_socket_put(struct modem_socket_config *cfg, int sock_fd);
80 int modem_socket_poll(struct modem_socket_config *cfg, struct zsock_pollfd *fds, int nfds,
81 		      int msecs);
82 int modem_socket_poll_update(struct modem_socket *sock, struct zsock_pollfd *pfd,
83 			     struct k_poll_event **pev);
84 int modem_socket_poll_prepare(struct modem_socket_config *cfg, struct modem_socket *sock,
85 			      struct zsock_pollfd *pfd, struct k_poll_event **pev,
86 			      struct k_poll_event *pev_end);
87 void modem_socket_wait_data(struct modem_socket_config *cfg, struct modem_socket *sock);
88 void modem_socket_data_ready(struct modem_socket_config *cfg, struct modem_socket *sock);
89 
90 /**
91  * @brief Initialize modem socket config struct and associated modem sockets
92  *
93  * @param cfg The config to initialize
94  * @param sockets The array of sockets associated with the modem socket config
95  * @param sockets_len The length of the array of sockets associated with the modem socket config
96  * @param base_socket_id The lowest socket id supported by the modem
97  * @param assign_id Dynamically assign modem socket id when allocated using modem_socket_get()
98  * @param vtable Socket API implementation used by this config and associated sockets
99  *
100  * @return -EINVAL if any argument is invalid
101  * @return 0 if successful
102  */
103 int modem_socket_init(struct modem_socket_config *cfg, struct modem_socket *sockets,
104 		      size_t sockets_len, int base_socket_id, bool assign_id,
105 		      const struct socket_op_vtable *vtable);
106 
107 /**
108  * @brief Check if modem socket has been allocated
109  *
110  * @details A modem socket is allocated after a successful invocation of modem_socket_get, and
111  * released after a successful invocation of modem_socket_put.
112  *
113  * @note If socket id is automatically assigned, the socket id will be a value between
114  * base_socket_id and (base_socket_id + socket_len).
115  * Otherwise, the socket id will be assigned to (base_socket_id + socket_len) when allocated.
116  *
117  * @param cfg The modem socket config which the modem socket belongs to
118  * @param sock The modem socket which is checked
119  *
120  * @return true if the socket has been allocated
121  * @return false if the socket has not been allocated
122  */
123 bool modem_socket_is_allocated(const struct modem_socket_config *cfg,
124 			       const struct modem_socket *sock);
125 
126 /**
127  * @brief Check if modem socket id has been assigned
128  *
129  * @note An assigned modem socket will have an id between base_socket_id and
130  * (base_socket_id + socket_len).
131  *
132  * @param cfg The modem socket config which the modem socket belongs to
133  * @param sock The modem socket for which the id is checked
134  *
135  * @return true if the socket id is been assigned
136  * @return false if the socket has not been assigned
137  */
138 bool modem_socket_id_is_assigned(const struct modem_socket_config *cfg,
139 				 const struct modem_socket *sock);
140 
141 /**
142  * @brief Assign id to modem socket
143  *
144  * @param cfg The modem socket config which the modem socket belongs to
145  * @param sock The modem socket for which the id will be assigned
146  * @param id The id to assign to the modem socket
147  *
148  * @return -EPERM if id has been assigned previously
149  * @return -EINVAL if id is invalid
150  * @return 0 if successful
151  */
152 int modem_socket_id_assign(const struct modem_socket_config *cfg,
153 			   struct modem_socket *sock,
154 			   int id);
155 
156 #ifdef __cplusplus
157 }
158 #endif
159 
160 #endif /* ZEPHYR_INCLUDE_DRIVERS_MODEM_MODEM_SOCKET_H_ */
161