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 enum modem_pipe_state { 65 MODEM_PIPE_STATE_CLOSED = 0, 66 MODEM_PIPE_STATE_OPEN, 67 }; 68 69 struct modem_pipe { 70 void *data; 71 struct modem_pipe_api *api; 72 modem_pipe_api_callback callback; 73 void *user_data; 74 enum modem_pipe_state state; 75 struct k_mutex lock; 76 struct k_condvar condvar; 77 uint8_t receive_ready_pending : 1; 78 uint8_t transmit_idle_pending : 1; 79 }; 80 81 /** 82 * @brief Initialize a modem pipe 83 * 84 * @param pipe Pipe instance to initialize 85 * @param data Pipe data to bind to pipe instance 86 * @param api Pipe API implementation to bind to pipe instance 87 */ 88 void modem_pipe_init(struct modem_pipe *pipe, void *data, struct modem_pipe_api *api); 89 90 /** 91 * @endcond 92 */ 93 94 /** 95 * @brief Open pipe 96 * 97 * @param pipe Pipe instance 98 * 99 * @retval 0 if pipe was successfully opened or was already open 100 * @retval -errno code otherwise 101 */ 102 int modem_pipe_open(struct modem_pipe *pipe); 103 104 /** 105 * @brief Open pipe asynchronously 106 * 107 * @param pipe Pipe instance 108 * 109 * @note The MODEM_PIPE_EVENT_OPENED event is invoked immediately if pipe is 110 * already opened. 111 * 112 * @retval 0 if pipe open was called successfully or pipe was already open 113 * @retval -errno code otherwise 114 */ 115 int modem_pipe_open_async(struct modem_pipe *pipe); 116 117 /** 118 * @brief Attach pipe to callback 119 * 120 * @param pipe Pipe instance 121 * @param callback Callback called when pipe event occurs 122 * @param user_data Free to use user data passed with callback 123 * 124 * @note The MODEM_PIPE_EVENT_RECEIVE_READY event is invoked immediately if pipe has pending 125 * data ready to receive. 126 */ 127 void modem_pipe_attach(struct modem_pipe *pipe, modem_pipe_api_callback callback, void *user_data); 128 129 /** 130 * @brief Transmit data through pipe 131 * 132 * @param pipe Pipe to transmit through 133 * @param buf Destination for reveived data 134 * @param size Capacity of destination for recevied data 135 * 136 * @return Number of bytes placed in pipe 137 * 138 * @warning This call must be non-blocking 139 */ 140 int modem_pipe_transmit(struct modem_pipe *pipe, const uint8_t *buf, size_t size); 141 142 /** 143 * @brief Reveive data through pipe 144 * 145 * @param pipe Pipe to receive from 146 * @param buf Destination for reveived data 147 * @param size Capacity of destination for recevied data 148 * 149 * @return Number of bytes received from pipe if any 150 * @return -EPERM if pipe is closed 151 * @return -errno code on error 152 * 153 * @warning This call must be non-blocking 154 */ 155 int modem_pipe_receive(struct modem_pipe *pipe, uint8_t *buf, size_t size); 156 157 /** 158 * @brief Clear callback 159 * 160 * @param pipe Pipe instance 161 */ 162 void modem_pipe_release(struct modem_pipe *pipe); 163 164 /** 165 * @brief Close pipe 166 * 167 * @param pipe Pipe instance 168 * 169 * @retval 0 if pipe open was called closed or pipe was already closed 170 * @retval -errno code otherwise 171 */ 172 int modem_pipe_close(struct modem_pipe *pipe); 173 174 /** 175 * @brief Close pipe asynchronously 176 * 177 * @param pipe Pipe instance 178 * 179 * @note The MODEM_PIPE_EVENT_CLOSED event is invoked immediately if pipe is 180 * already closed. 181 * 182 * @retval 0 if pipe close was called successfully or pipe was already closed 183 * @retval -errno code otherwise 184 */ 185 int modem_pipe_close_async(struct modem_pipe *pipe); 186 187 /** 188 * @cond INTERNAL_HIDDEN 189 */ 190 191 /** 192 * @brief Notify user of pipe that it has opened 193 * 194 * @param pipe Pipe instance 195 * 196 * @note Invoked from instance which initialized the pipe instance 197 */ 198 void modem_pipe_notify_opened(struct modem_pipe *pipe); 199 200 /** 201 * @brief Notify user of pipe that it has closed 202 * 203 * @param pipe Pipe instance 204 * 205 * @note Invoked from instance which initialized the pipe instance 206 */ 207 void modem_pipe_notify_closed(struct modem_pipe *pipe); 208 209 /** 210 * @brief Notify user of pipe that data is ready to be received 211 * 212 * @param pipe Pipe instance 213 * 214 * @note Invoked from instance which initialized the pipe instance 215 */ 216 void modem_pipe_notify_receive_ready(struct modem_pipe *pipe); 217 218 /** 219 * @brief Notify user of pipe that pipe has no more data to transmit 220 * 221 * @param pipe Pipe instance 222 * 223 * @note Invoked from instance which initialized the pipe instance 224 */ 225 void modem_pipe_notify_transmit_idle(struct modem_pipe *pipe); 226 227 /** 228 * @endcond 229 */ 230 231 /** 232 * @} 233 */ 234 235 #ifdef __cplusplus 236 } 237 #endif 238 239 #endif /* ZEPHYR_MODEM_PIPE_ */ 240