blob: 124af5d42694411956a95bff1a0c3ba4d4f4f850 [file] [log] [blame]
/*
* Copyright (c) 2022 Trackunit Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/types.h>
#include <zephyr/kernel.h>
#ifndef ZEPHYR_MODEM_PIPE_
#define ZEPHYR_MODEM_PIPE_
#ifdef __cplusplus
extern "C" {
#endif
struct modem_pipe;
typedef int (*modem_pipe_api_open)(void *data);
typedef int (*modem_pipe_api_transmit)(void *data, const uint8_t *buf, size_t size);
typedef int (*modem_pipe_api_receive)(void *data, uint8_t *buf, size_t size);
typedef int (*modem_pipe_api_close)(void *data);
struct modem_pipe_api {
modem_pipe_api_open open;
modem_pipe_api_transmit transmit;
modem_pipe_api_receive receive;
modem_pipe_api_close close;
};
enum modem_pipe_state {
MODEM_PIPE_STATE_CLOSED = 0,
MODEM_PIPE_STATE_OPEN,
};
enum modem_pipe_event {
MODEM_PIPE_EVENT_OPENED = 0,
MODEM_PIPE_EVENT_RECEIVE_READY,
MODEM_PIPE_EVENT_CLOSED,
};
typedef void (*modem_pipe_api_callback)(struct modem_pipe *pipe, enum modem_pipe_event event,
void *user_data);
struct modem_pipe {
void *data;
struct modem_pipe_api *api;
modem_pipe_api_callback callback;
void *user_data;
enum modem_pipe_state state;
struct k_mutex lock;
struct k_condvar condvar;
bool receive_ready_pending;
};
/**
* @brief Initialize a modem pipe
*
* @param pipe Pipe instance to initialize
* @param data Pipe data to bind to pipe instance
* @param api Pipe API implementation to bind to pipe instance
*/
void modem_pipe_init(struct modem_pipe *pipe, void *data, struct modem_pipe_api *api);
/**
* @brief Open pipe
*
* @param pipe Pipe instance
*
* @retval 0 if pipe was successfully opened or was already open
* @retval -errno code otherwise
*/
int modem_pipe_open(struct modem_pipe *pipe);
/**
* @brief Open pipe asynchronously
*
* @param pipe Pipe instance
*
* @note The MODEM_PIPE_EVENT_OPENED event is invoked immediately if pipe is
* already opened.
*
* @retval 0 if pipe open was called successfully or pipe was already open
* @retval -errno code otherwise
*/
int modem_pipe_open_async(struct modem_pipe *pipe);
/**
* @brief Attach pipe to callback
*
* @param pipe Pipe instance
* @param callback Callback called when pipe event occurs
* @param user_data Free to use user data passed with callback
*
* @note The MODEM_PIPE_EVENT_RECEIVE_READY event is invoked immediately if pipe has pending
* data ready to receive.
*/
void modem_pipe_attach(struct modem_pipe *pipe, modem_pipe_api_callback callback, void *user_data);
/**
* @brief Transmit data through pipe
*
* @param pipe Pipe to transmit through
* @param buf Destination for reveived data
* @param size Capacity of destination for recevied data
*
* @return Number of bytes placed in pipe
*
* @warning This call must be non-blocking
*/
int modem_pipe_transmit(struct modem_pipe *pipe, const uint8_t *buf, size_t size);
/**
* @brief Reveive data through pipe
*
* @param pipe Pipe to receive from
* @param buf Destination for reveived data
* @param size Capacity of destination for recevied data
*
* @return Number of bytes received from pipe if any
* @return -EPERM if pipe is closed
* @return -errno code on error
*
* @warning This call must be non-blocking
*/
int modem_pipe_receive(struct modem_pipe *pipe, uint8_t *buf, size_t size);
/**
* @brief Clear callback
*
* @param pipe Pipe instance
*/
void modem_pipe_release(struct modem_pipe *pipe);
/**
* @brief Close pipe
*
* @param pipe Pipe instance
*
* @retval 0 if pipe open was called closed or pipe was already closed
* @retval -errno code otherwise
*/
int modem_pipe_close(struct modem_pipe *pipe);
/**
* @brief Close pipe asynchronously
*
* @param pipe Pipe instance
*
* @note The MODEM_PIPE_EVENT_CLOSED event is invoked immediately if pipe is
* already closed.
*
* @retval 0 if pipe close was called successfully or pipe was already closed
* @retval -errno code otherwise
*/
int modem_pipe_close_async(struct modem_pipe *pipe);
/**
* @brief Notify user of pipe that it has opened
*
* @param pipe Pipe instance
*
* @note Invoked from instance which initialized the pipe instance
*/
void modem_pipe_notify_opened(struct modem_pipe *pipe);
/**
* @brief Notify user of pipe that it has closed
*
* @param pipe Pipe instance
*
* @note Invoked from instance which initialized the pipe instance
*/
void modem_pipe_notify_closed(struct modem_pipe *pipe);
/**
* @brief Notify user of pipe that data is ready to be received
*
* @param pipe Pipe instance
*
* @note Invoked from instance which initialized the pipe instance
*/
void modem_pipe_notify_receive_ready(struct modem_pipe *pipe);
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_MODEM_PIPE_ */