1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ESE_HW_API_H_
18 #define ESE_HW_API_H_ 1
19 
20 #include "../../../libese-sysdeps/include/ese/sysdeps.h"
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 /*
26  * Pulls the hardware declarations in to scope for the current file
27  * to make use of.
28  */
29 #define __ESE_INCLUDE_HW(name) \
30   extern const struct EseOperations * name## _ops
31 
32 
33 struct EseInterface;
34 
35 /* ese_hw_receive_op_t: receives a buffer from the hardware.
36  * Args:
37  * - struct EseInterface *: session handle.
38  * - uint8_t *: pointer to the buffer to receive data into.
39  * - uint32_t: maximum length of the data to receive.
40  * - int: 1 or 0 indicating if it is a complete transaction. This allows the underlying
41  *       implementation to batch reads if needed by the underlying wire protocol or if
42  *       the hardware needs to be signalled explicitly.
43  *
44  * Returns:
45  * - uint32_t: bytes received.
46  */
47 typedef uint32_t (ese_hw_receive_op_t)(struct EseInterface *, uint8_t *, uint32_t, int);
48 /* ese_hw_transmit_op_t: transmits a buffer over the hardware.
49  * Args:
50  * - struct EseInterface *: session handle.
51  * - uint8_t *: pointer to the buffer to transmit.
52  * - uint32_t: length of the data to transmit.
53  * - int: 1 or 0 indicating if it is a complete transaction.
54  *
55  * Returns:
56  * - uint32_t: bytes transmitted.
57  */
58 typedef uint32_t (ese_hw_transmit_op_t)(struct EseInterface *, const uint8_t *, uint32_t, int);
59 /* ese_hw_reset_op_t: resets the hardware in case of communication desynchronization.
60  * Args:
61  * - struct EseInterface *: session handle.
62  *
63  * Returns:
64  * - int: -1 on error, 0 on success.
65  */
66 typedef int (ese_hw_reset_op_t)(struct EseInterface *);
67 /* ese_transceive_op_t:  fully contained transmission and receive operation.
68  *
69  * Must provide an implementation of the wire protocol necessary to transmit
70  * and receive an application payload to and from the eSE.  Normally, this
71  * implementation is built on the hw_{receive,transmit} operations also
72  * provided and often requires the poll operation below.
73  *
74  * Args:
75  * - struct EseInterface *: session handle.
76  * - const uint8_t *: pointer to the buffer to transmit.
77  * - uint32_t: length of the data to transmit.
78  * - uint8_t *: pointer to the buffer to receive into.
79  * - uint32_t: maximum length of the data to receive.
80  *
81  * Returns:
82  * - uint32_t: bytes received.
83  */
84 typedef uint32_t (ese_transceive_op_t)(struct EseInterface *, const uint8_t *, uint32_t, uint8_t *, uint32_t);
85 /* ese_poll_op_t: waits for the hardware to be ready to send data.
86  *
87  * Args:
88  * - struct EseInterface *: session handle.
89  * - uint8_t: byte to wait for. E.g., a start of frame byte.
90  * - float: time in seconds to wait.
91  * - int: whether to complete a transaction when polling іs complete.
92  *
93  * Returns:
94  * - int: On error or timeout, -1.
95  *        On success, 1 or 0 depending on if the found byte was consumed.
96  */
97 typedef int (ese_poll_op_t)(struct EseInterface *, uint8_t, float, int);
98 /* ese_hw_open_op_t: prepares the hardware for use.
99  *
100  * This function should prepare the hardware for use and attach
101  * any implementation specific state to the EseInterface handle such
102  * that it is accessible in the other calls.
103  *
104  * Args:
105  * - struct EseInterface *: freshly initialized session handle.
106  * - void *: implementation specific pointer from the libese client.
107  *
108  * Returns:
109  * - int: < 0 on error, 0 on success.
110  */
111 typedef int (ese_open_op_t)(struct EseInterface *, void *);
112 /* ese_hw_close_op_t: releases the hardware in use.
113  *
114  * This function should free any dynamic memory and release
115  * the claimed hardware.
116  *
117  * Args:
118  * - struct EseInterface *: freshly initialized session handle.
119  *
120  * Returns:
121  * - Nothing.
122  */
123 typedef void (ese_close_op_t)(struct EseInterface *);
124 
125 #define __ESE_INITIALIZER(TYPE) \
126 { \
127   .ops = TYPE## _ops, \
128   .pad =  { 0 }, \
129 }
130 
131 #define __ese_init(_ptr, TYPE) {\
132   _ptr->ops = TYPE## _ops; \
133   _ptr->pad[0] = 0; \
134 }
135 
136 struct EseOperations {
137   const char *const name;
138   /* Used to prepare any implementation specific internal data and
139    * state needed for robust communication.
140    */
141   ese_open_op_t *const open;
142   /* Used to receive raw data from the ese. */
143   ese_hw_receive_op_t *const hw_receive;
144   /* Used to transmit raw data to the ese. */
145   ese_hw_transmit_op_t *const hw_transmit;
146   /* Used to perform a power reset on the device. */
147   ese_hw_reset_op_t *const hw_reset;
148   /* Wire-specific protocol polling for readiness. */
149   ese_poll_op_t *const poll;
150   /* Wire-specific protocol for transmitting and receiving
151    * application data to the eSE. By default, this may point to
152    * a generic implementation, like teq1_transceive, which uses
153    * the hw_* ops above.
154    */
155   ese_transceive_op_t *const transceive;
156   /* Cleans up any required state: file descriptors or heap allocations. */
157   ese_close_op_t *const close;
158 
159   /* Operational options */
160   const void *const opts;
161 
162   /* Operation error messages. */
163   const char **errors;
164   const uint32_t errors_count;
165 };
166 
167 /* Maximum private stack storage on the interface instance. */
168 #define ESE_INTERFACE_STATE_PAD 16
169 struct EseInterface {
170   const struct EseOperations * ops;
171   struct {
172     bool is_err;
173     int code;
174     const char *message;
175   } error;
176   /* Reserved to avoid heap allocation requirement. */
177   uint8_t pad[ESE_INTERFACE_STATE_PAD];
178 };
179 
180 /*
181  * Provided by libese to manage exposing usable errors up the stack to the
182  * libese user.
183  */
184 void ese_set_error(struct EseInterface *ese, int code);
185 
186 /*
187  * Global error enums.
188  */
189 enum EseGlobalError {
190   kEseGlobalErrorNoTransceive = -1,
191   kEseGlobalErrorPollTimedOut = -2,
192 };
193 
194 #define ESE_DEFINE_HW_OPS(name, obj) \
195   const struct EseOperations * name##_ops = &obj
196 
197 
198 #ifdef __cplusplus
199 }  /* extern "C" */
200 #endif
201 #endif  /* ESE_HW_API_H_ */
202