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