blob: 759365a1efd588bb6b8dbb7dd79452062c0ce5ba [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ESE_HW_API_H_
#define ESE_HW_API_H_ 1
#include "ese_sg.h"
#include <ese/sysdeps.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Pulls the hardware declarations in to scope for the current file
* to make use of.
*/
#define __ESE_INCLUDE_HW(name) \
extern const struct EseOperations * name## _ops
struct EseInterface;
/* ese_hw_receive_op_t: receives a buffer from the hardware.
* Args:
* - struct EseInterface *: session handle.
* - uint8_t *: pointer to the buffer to receive data into.
* - uint32_t: maximum length of the data to receive.
* - int: 1 or 0 indicating if it is a complete transaction. This allows the underlying
* implementation to batch reads if needed by the underlying wire protocol or if
* the hardware needs to be signalled explicitly.
*
* Returns:
* - uint32_t: bytes received.
*/
typedef uint32_t (ese_hw_receive_op_t)(struct EseInterface *, uint8_t *, uint32_t, int);
/* ese_hw_transmit_op_t: transmits a buffer over the hardware.
* Args:
* - struct EseInterface *: session handle.
* - uint8_t *: pointer to the buffer to transmit.
* - uint32_t: length of the data to transmit.
* - int: 1 or 0 indicating if it is a complete transaction.
*
* Returns:
* - uint32_t: bytes transmitted.
*/
typedef uint32_t (ese_hw_transmit_op_t)(struct EseInterface *, const uint8_t *, uint32_t, int);
/* ese_hw_reset_op_t: resets the hardware in case of communication desynchronization.
* Args:
* - struct EseInterface *: session handle.
*
* Returns:
* - int: -1 on error, 0 on success.
*/
typedef int (ese_hw_reset_op_t)(struct EseInterface *);
/* ese_transceive_sg_op_t: fully contained transmission and receive operation.
*
* Must provide an implementation of the wire protocol necessary to transmit
* and receive an application payload to and from the eSE. Normally, this
* implementation is built on the hw_{receive,transmit} operations also
* provided and often requires the poll operation below.
*
* Args:
* - struct EseInterface *: session handle.
* - const EseSgBuffer *: array of buffers to transmit
* - uint32_t: number of buffers to send
* - const EseSgBuffer *: array of buffers to receive into
* - uint32_t: number of buffers to receive to
*
* Returns:
* - uint32_t: bytes received.
*/
typedef uint32_t (ese_transceive_op_t)(
struct EseInterface *, const struct EseSgBuffer *, uint32_t, struct EseSgBuffer *, uint32_t);
/* ese_poll_op_t: waits for the hardware to be ready to send data.
*
* Args:
* - struct EseInterface *: session handle.
* - uint8_t: byte to wait for. E.g., a start of frame byte.
* - float: time in seconds to wait.
* - int: whether to complete a transaction when polling іs complete.
*
* Returns:
* - int: On error or timeout, -1.
* On success, 1 or 0 depending on if the found byte was consumed.
*/
typedef int (ese_poll_op_t)(struct EseInterface *, uint8_t, float, int);
/* ese_hw_open_op_t: prepares the hardware for use.
*
* This function should prepare the hardware for use and attach
* any implementation specific state to the EseInterface handle such
* that it is accessible in the other calls.
*
* Args:
* - struct EseInterface *: freshly initialized session handle.
* - void *: implementation specific pointer from the libese client.
*
* Returns:
* - int: < 0 on error, 0 on success.
*/
typedef int (ese_open_op_t)(struct EseInterface *, void *);
/* ese_hw_close_op_t: releases the hardware in use.
*
* This function should free any dynamic memory and release
* the claimed hardware.
*
* Args:
* - struct EseInterface *: freshly initialized session handle.
*
* Returns:
* - Nothing.
*/
typedef void (ese_close_op_t)(struct EseInterface *);
#define __ESE_INITIALIZER(TYPE) \
{ \
.ops = TYPE## _ops, \
.error = { \
.is_err = false, \
.code = 0, \
.message = NULL, \
}, \
.pad = { 0 }, \
}
#define __ese_init(_ptr, TYPE) {\
(_ptr)->ops = TYPE## _ops; \
(_ptr)->pad[0] = 0; \
(_ptr)->error.is_err = false; \
(_ptr)->error.code = 0; \
(_ptr)->error.message = (const char *)NULL; \
}
struct EseOperations {
const char *name;
/* Used to prepare any implementation specific internal data and
* state needed for robust communication.
*/
ese_open_op_t *open;
/* Used to receive raw data from the ese. */
ese_hw_receive_op_t *hw_receive;
/* Used to transmit raw data to the ese. */
ese_hw_transmit_op_t *hw_transmit;
/* Used to perform a power reset on the device. */
ese_hw_reset_op_t *hw_reset;
/* Wire-specific protocol polling for readiness. */
ese_poll_op_t *poll;
/* Wire-specific protocol for transmitting and receiving
* application data to the eSE. By default, this may point to
* a generic implementation, like teq1_transceive, which uses
* the hw_* ops above.
*/
ese_transceive_op_t *transceive;
/* Cleans up any required state: file descriptors or heap allocations. */
ese_close_op_t *close;
/* Operational options */
const void *opts;
/* Operation error messages. */
const char **errors;
uint32_t errors_count;
};
/* Maximum private stack storage on the interface instance. */
#define ESE_INTERFACE_STATE_PAD 16
struct EseInterface {
const struct EseOperations * ops;
struct {
bool is_err;
int code;
const char *message;
} error;
/* Reserved to avoid heap allocation requirement. */
uint8_t pad[ESE_INTERFACE_STATE_PAD];
};
/*
* Provided by libese to manage exposing usable errors up the stack to the
* libese user.
*/
void ese_set_error(struct EseInterface *ese, int code);
/*
* Global error enums.
*/
enum EseGlobalError {
kEseGlobalErrorNoTransceive = -1,
kEseGlobalErrorPollTimedOut = -2,
};
#define ESE_DEFINE_HW_OPS(name, obj) \
const struct EseOperations * name##_ops = &obj
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* ESE_HW_API_H_ */