1 /* 2 * Copyright (c) 2022 Trackunit Corporation 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #include <zephyr/types.h> 8 #include <zephyr/kernel.h> 9 10 #ifndef ZEPHYR_MODEM_PIPE_ 11 #define ZEPHYR_MODEM_PIPE_ 12 13 #ifdef __cplusplus 14 extern "C" { 15 #endif 16 17 /** 18 * @brief Modem Pipe 19 * @defgroup modem_pipe Modem Pipe 20 * @ingroup modem 21 * @{ 22 */ 23 24 /** Modem pipe event */ 25 enum modem_pipe_event { 26 MODEM_PIPE_EVENT_OPENED = 0, 27 MODEM_PIPE_EVENT_RECEIVE_READY, 28 MODEM_PIPE_EVENT_TRANSMIT_IDLE, 29 MODEM_PIPE_EVENT_CLOSED, 30 }; 31 32 /** 33 * @cond INTERNAL_HIDDEN 34 */ 35 36 struct modem_pipe; 37 38 /** 39 * @endcond 40 */ 41 42 typedef void (*modem_pipe_api_callback)(struct modem_pipe *pipe, enum modem_pipe_event event, 43 void *user_data); 44 45 /** 46 * @cond INTERNAL_HIDDEN 47 */ 48 49 typedef int (*modem_pipe_api_open)(void *data); 50 51 typedef int (*modem_pipe_api_transmit)(void *data, const uint8_t *buf, size_t size); 52 53 typedef int (*modem_pipe_api_receive)(void *data, uint8_t *buf, size_t size); 54 55 typedef int (*modem_pipe_api_close)(void *data); 56 57 struct modem_pipe_api { 58 modem_pipe_api_open open; 59 modem_pipe_api_transmit transmit; 60 modem_pipe_api_receive receive; 61 modem_pipe_api_close close; 62 }; 63 64 struct modem_pipe { 65 void *data; 66 const struct modem_pipe_api *api; 67 modem_pipe_api_callback callback; 68 void *user_data; 69 struct k_spinlock spinlock; 70 struct k_event event; 71 }; 72 73 /** 74 * @brief Initialize a modem pipe 75 * 76 * @param pipe Pipe instance to initialize 77 * @param data Pipe data to bind to pipe instance 78 * @param api Pipe API implementation to bind to pipe instance 79 */ 80 void modem_pipe_init(struct modem_pipe *pipe, void *data, const struct modem_pipe_api *api); 81 82 /** 83 * @endcond 84 */ 85 86 /** 87 * @brief Open pipe 88 * 89 * @param pipe Pipe instance 90 * @param timeout Timeout waiting for pipe to open 91 * 92 * @retval 0 if pipe was successfully opened or was already open 93 * @retval -errno code otherwise 94 * 95 * @warning Be cautious when using this synchronous version of the call. 96 * It may block the calling thread, which in the case of the system workqueue 97 * can result in a deadlock until this call times out waiting for the pipe to be open. 98 */ 99 int modem_pipe_open(struct modem_pipe *pipe, k_timeout_t timeout); 100 101 /** 102 * @brief Open pipe asynchronously 103 * 104 * @param pipe Pipe instance 105 * 106 * @note The MODEM_PIPE_EVENT_OPENED event is invoked immediately if pipe is 107 * already opened. 108 * 109 * @retval 0 if pipe open was called successfully or pipe was already open 110 * @retval -errno code otherwise 111 */ 112 int modem_pipe_open_async(struct modem_pipe *pipe); 113 114 /** 115 * @brief Attach pipe to callback 116 * 117 * @param pipe Pipe instance 118 * @param callback Callback called when pipe event occurs 119 * @param user_data Free to use user data passed with callback 120 * 121 * @note The MODEM_PIPE_EVENT_RECEIVE_READY event is invoked immediately if pipe has pending 122 * data ready to receive. 123 */ 124 void modem_pipe_attach(struct modem_pipe *pipe, modem_pipe_api_callback callback, void *user_data); 125 126 /** 127 * @brief Transmit data through pipe 128 * 129 * @param pipe Pipe to transmit through 130 * @param buf Data to transmit 131 * @param size Number of bytes to transmit 132 * 133 * @retval Number of bytes placed in pipe 134 * @retval -EPERM if pipe is closed 135 * @retval -errno code on error 136 * 137 * @warning This call must be non-blocking 138 */ 139 int modem_pipe_transmit(struct modem_pipe *pipe, const uint8_t *buf, size_t size); 140 141 /** 142 * @brief Receive data through pipe 143 * 144 * @param pipe Pipe to receive from 145 * @param buf Destination for received data; must not be already in use in a modem module. 146 * @param size Capacity of destination for received data 147 * 148 * @retval Number of bytes received from pipe 149 * @retval -EPERM if pipe is closed 150 * @retval -errno code on error 151 * 152 * @warning This call must be non-blocking 153 */ 154 int modem_pipe_receive(struct modem_pipe *pipe, uint8_t *buf, size_t size); 155 156 /** 157 * @brief Clear callback 158 * 159 * @param pipe Pipe instance 160 */ 161 void modem_pipe_release(struct modem_pipe *pipe); 162 163 /** 164 * @brief Close pipe 165 * 166 * @param pipe Pipe instance 167 * @param timeout Timeout waiting for pipe to close 168 * 169 * @retval 0 if pipe open was called closed or pipe was already closed 170 * @retval -errno code otherwise 171 * 172 * @warning Be cautious when using this synchronous version of the call. 173 * It may block the calling thread, which in the case of the system workqueue 174 * can result in a deadlock until this call times out waiting for the pipe to be closed. 175 */ 176 int modem_pipe_close(struct modem_pipe *pipe, k_timeout_t timeout); 177 178 /** 179 * @brief Close pipe asynchronously 180 * 181 * @param pipe Pipe instance 182 * 183 * @note The MODEM_PIPE_EVENT_CLOSED event is invoked immediately if pipe is 184 * already closed. 185 * 186 * @retval 0 if pipe close was called successfully or pipe was already closed 187 * @retval -errno code otherwise 188 */ 189 int modem_pipe_close_async(struct modem_pipe *pipe); 190 191 /** 192 * @cond INTERNAL_HIDDEN 193 */ 194 195 /** 196 * @brief Notify user of pipe that it has opened 197 * 198 * @param pipe Pipe instance 199 * 200 * @note Invoked from instance which initialized the pipe instance 201 */ 202 void modem_pipe_notify_opened(struct modem_pipe *pipe); 203 204 /** 205 * @brief Notify user of pipe that it has closed 206 * 207 * @param pipe Pipe instance 208 * 209 * @note Invoked from instance which initialized the pipe instance 210 */ 211 void modem_pipe_notify_closed(struct modem_pipe *pipe); 212 213 /** 214 * @brief Notify user of pipe that data is ready to be received 215 * 216 * @param pipe Pipe instance 217 * 218 * @note Invoked from instance which initialized the pipe instance 219 */ 220 void modem_pipe_notify_receive_ready(struct modem_pipe *pipe); 221 222 /** 223 * @brief Notify user of pipe that pipe has no more data to transmit 224 * 225 * @param pipe Pipe instance 226 * 227 * @note Invoked from instance which initialized the pipe instance 228 */ 229 void modem_pipe_notify_transmit_idle(struct modem_pipe *pipe); 230 231 /** 232 * @endcond 233 */ 234 235 /** 236 * @} 237 */ 238 239 #ifdef __cplusplus 240 } 241 #endif 242 243 #endif /* ZEPHYR_MODEM_PIPE_ */ 244