src.dualinventive.com/dinet/sec-multi-proxy/libdi/include/di/can.h

181 lines
5.1 KiB
C
Executable File

/**
* @file include/di/can.h
* @defgroup can CAN Messaging Stack
* @brief DI CAN messaging stack
* @date Aug 25, 2015
* @author rheijden
* @copyright 2015 Dual Inventive Technology Centre B.V.
*
* DI CAN messaging stack
* @{
*/
#ifndef INCLUDE_DI_CAN_H_
#define INCLUDE_DI_CAN_H_
#include <stddef.h>
#include <stdint.h>
#include <di/types.h>
#include <di/array.h>
#include <di/semaphore.h>
#include <di/can/net.h>
#include <di/can/stat.h>
#include <di/can/frame.h>
#include <di/can/reqrep.h>
/** CAN subsystem context */
struct di_can_ctx {
di_bsem_t lock;
uint32_t nodeid; /**< Local nodeid */
uint8_t transaction; /**< Current transaction id */
uint16_t rt_seqnr; /**< Current Realtime message sequence number */
struct di_can_frame frame;
struct {
bool timesync_enabled; /**< Timesync when RAW DINET_TIME is received */
bool dst_id_filter_enabled; /**< Node destination ID filter (see di_can_msg_enable_dst_id_filter) */
di_bsem_t lock;
struct di_array pool;
struct di_array callback;
uint32_t timeout; /**< Garbage collection timeout of messages in assembly (milliseconds) */
struct {
bool is_blocking;
di_bsem_t any;
di_bsem_t raw;
di_bsem_t rpc;
di_bsem_t net;
di_bsem_t log;
size_t any_cnt;
size_t raw_cnt;
size_t rpc_cnt;
size_t net_cnt;
size_t log_cnt;
uint32_t timeout;
} recv;
} msg;
struct {
struct di_can_reqrep_item item;
} reqrep;
struct di_can_net net;
struct di_can_stat stat;
di_errno_t (*recv)(struct di_can_frame_rx *frame); /**< Platform specific CAN frame receive callback */
di_errno_t (*send)(const struct di_can_frame_tx *frame); /**< Platform specific CAN send callback */
void *private_data; /**< Application specific private data */
};
#include <di/can/callback.h>
#include <di/can/bitops.h>
#include <di/can/rpc.h>
#include <di/can/msg.h>
#include <di/can/str.h>
#include <di/can/raw.h>
#include <di/can/net.h>
#include <di/can/framing.h>
#include <di/can/lowlevel.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Initialize and verifies the CAN context
*/
di_errno_t di_can_init(struct di_can_ctx *ctx);
/**
* Set can nodeid based on uid hex-string (e.g di_device_uid_get)
*/
void di_can_set_nodeid(struct di_can_ctx *ctx, const char *uid);
/**
* Set di_can_ctx private_data for application
*/
void di_can_set_private_data(struct di_can_ctx *ctx, void *private_data);
/**
* Get private_data for application
*/
void *di_can_get_private_data(struct di_can_ctx *ctx);
/**
* Send can message, this function returns
* the di_can_msg back to the msg pool.
* A message needs to be requested from the message pool with
* @ref di_can_msg_alloc
* * The Source Node ID is read from ctx->nodeid when src_id == DI_CAN_NODEID_UNSET
* (must be set with @ref di_can_set_nodeid).
* * If msg->broadcast is true then the Destination Node ID is set to @ref DI_CAN_NODEID_BROADCAST
* @param msg Message to send
* @retval DNOK when send succeeded !DNOK otherwise.
* @note When !DNOK is returned the application is responsible to free the message or try to send again
*/
di_errno_t di_can_send(struct di_can_msg **msg);
/**
* Send data as DI-CAN message
* @param ctx CAN driver context
* @param dst_id Destination ID
* @param msgtype Message type
* @param ttype Transfertype
* @param dtype Datatype
* @param ptype Payload type
* @param data Data
* @param size Size of data in bytes
* @warning When something goes wrong on send the message is implicit freed
*/
di_errno_t di_can_send_data(struct di_can_ctx *ctx,
uint32_t dst_id, enum di_can_msgtype msgtype,
enum di_can_transfertype ttype,
uint16_t dtype, enum di_can_ptypes ptype, const void *data, size_t size);
/**
* Send broadcast message
* @warning When something goes wrong on send the message is implicit freed
* @note The canid is not modified and needs to be prepared before
*/
di_errno_t di_can_send_broadcast(struct di_can_msg **msg);
/**
* Send reply where payload of reply is already written
* @note Reply message is always freed
*/
di_errno_t di_can_send_reply(struct di_can_msg **rep, const struct di_can_msg *req);
/**
* Send di_errno reply where payload of reply is already written
* @note Reply message is always freed
*/
di_errno_t di_can_send_errno_reply(const struct di_can_msg *req, const di_errno_t err);
/**
* Send can message as empty reply
* @note It modifies the canid and write TRANSFERTYPE to REP.
* And it set the message size field to zero.
*/
di_errno_t di_can_send_empty_reply(const struct di_can_msg *req);
/**
* Receive (assembled) can message, with matching canid fields:
* * @ref DI_CAN_GET_MSGTYPE
* * @ref DI_CAN_GET_DATATYPE
* @param ctx CAN driver context
* @param type Message type to receive
* @return NULL if no packet is ready
*/
struct di_can_msg *di_can_recv(struct di_can_ctx *ctx, enum di_can_msgtype type);
/**
* Reassamble di_can_frame_rx into di_can_msg.
* This function needs to be called at least every ~50 milliseconds
*/
di_errno_t di_can_reassemble(struct di_can_ctx *ctx);
#ifdef __cplusplus
}
#endif
/** @} */
#endif /* INCLUDE_DI_CAN_H_ */