• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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  * Minimal functions that only validate arguments.
17  */
18 
19 #include "../libese/include/ese/ese.h"
20 
21 enum EseFakeHwError {
22   kEseFakeHwErrorEarlyClose,
23   kEseFakeHwErrorReceiveDuringTransmit,
24   kEseFakeHwErrorInvalidReceiveSize,
25   kEseFakeHwErrorTransmitDuringReceive,
26   kEseFakeHwErrorInvalidTransmitSize,
27   kEseFakeHwErrorTranscieveWhileBusy,
28   kEseFakeHwErrorEmptyTransmit,
29   kEseFakeHwErrorMax,
30 };
31 
32 static const char *kErrorMessages[] = {
33     "Interface closed without finishing transmission.",
34     "Receive called without completing transmission.",
35     "Invalid receive buffer supplied with non-zero length.",
36     "Transmit called without completing reception.",
37     "Invalid transmit buffer supplied with non-zero length.",
38     "Transceive called while other I/O in process.",
39     "Transmitted no data.", /* Can reach this by setting tx_len = 0. */
40 };
41 
fake_open(struct EseInterface * ese,void * hw_opts)42 static int fake_open(struct EseInterface *ese,
43                      void *hw_opts __attribute__((unused))) {
44   ese->pad[0] = 1; /* rx complete */
45   ese->pad[1] = 1; /* tx complete */
46   return 0;
47 }
48 
fake_close(struct EseInterface * ese)49 static void fake_close(struct EseInterface *ese) {
50   if (!ese->pad[0] || !ese->pad[1]) {
51     /* Set by caller. ese->error.is_error = 1; */
52     ese_set_error(ese, kEseFakeHwErrorEarlyClose);
53     return;
54   }
55 }
56 
fake_receive(struct EseInterface * ese,uint8_t * buf,uint32_t len,int complete)57 static uint32_t fake_receive(struct EseInterface *ese, uint8_t *buf,
58                              uint32_t len, int complete) {
59   if (!ese->pad[1]) {
60     ese_set_error(ese, kEseFakeHwErrorReceiveDuringTransmit);
61     return -1;
62   }
63   ese->pad[0] = complete;
64   if (!buf && len) {
65     ese_set_error(ese, kEseFakeHwErrorInvalidReceiveSize);
66     return -1;
67   }
68   if (!len) {
69     return 0;
70   }
71   return len;
72 }
73 
fake_transmit(struct EseInterface * ese,const uint8_t * buf,uint32_t len,int complete)74 static uint32_t fake_transmit(struct EseInterface *ese, const uint8_t *buf,
75                               uint32_t len, int complete) {
76   if (!ese->pad[0]) {
77     ese_set_error(ese, kEseFakeHwErrorTransmitDuringReceive);
78     return -1;
79   }
80   ese->pad[1] = complete;
81   if (!buf && len) {
82     ese_set_error(ese, kEseFakeHwErrorInvalidTransmitSize);
83     return -1;
84   }
85   if (!len) {
86     return 0;
87   }
88   return len;
89 }
90 
fake_poll(struct EseInterface * ese,uint8_t poll_for,float timeout,int complete)91 static int fake_poll(struct EseInterface *ese, uint8_t poll_for, float timeout,
92                      int complete) {
93   /* Poll begins a receive-train so transmit needs to be completed. */
94   if (!ese->pad[1]) {
95     ese_set_error(ese, kEseFakeHwErrorReceiveDuringTransmit);
96     return -1;
97   }
98   if (timeout == 0.0f) {
99     /* Instant timeout. */
100     return 0;
101   }
102   /* Only expect one value to work. */
103   if (poll_for == 0xad) {
104     return 1;
105   }
106   ese->pad[0] = complete;
107   return 0;
108 }
109 
fake_transceive(struct EseInterface * ese,const struct EseSgBuffer * tx_bufs,uint32_t tx_seg,struct EseSgBuffer * rx_bufs,uint32_t rx_seg)110 uint32_t fake_transceive(struct EseInterface *ese,
111                          const struct EseSgBuffer *tx_bufs, uint32_t tx_seg,
112                          struct EseSgBuffer *rx_bufs, uint32_t rx_seg) {
113   uint32_t processed = 0;
114   uint32_t offset = 0;
115   struct EseSgBuffer *rx_buf = rx_bufs;
116   const struct EseSgBuffer *tx_buf = tx_bufs;
117 
118   if (!ese->pad[0] || !ese->pad[1]) {
119     ese_set_error(ese, kEseFakeHwErrorTranscieveWhileBusy);
120     return 0;
121   }
122   while (tx_buf < tx_bufs + tx_seg) {
123     uint32_t sent =
124         fake_transmit(ese, tx_buf->base + offset, tx_buf->len - offset, 0);
125     if (sent != tx_buf->len - offset) {
126       offset = tx_buf->len - sent;
127       processed += sent;
128       continue;
129     }
130     if (sent == 0) {
131       if (ese_error(ese)) {
132         return 0;
133       }
134       ese_set_error(ese, kEseFakeHwErrorEmptyTransmit);
135       return 0;
136     }
137     tx_buf++;
138     offset = 0;
139     processed += sent;
140   }
141   fake_transmit(ese, NULL, 0, 1); /* Complete. */
142   if (fake_poll(ese, 0xad, 10, 0) != 1) {
143     ese_set_error(ese, kEseGlobalErrorPollTimedOut);
144     return 0;
145   }
146   /* This reads the full RX buffer rather than a protocol specified amount. */
147   processed = 0;
148   while (rx_buf < rx_bufs + rx_seg) {
149     processed += fake_receive(ese, rx_buf->base, rx_buf->len, 1);
150   }
151   return processed;
152 }
153 
154 static const struct EseOperations ops = {
155     .name = "eSE Fake Hardware",
156     .open = &fake_open,
157     .hw_receive = &fake_receive,
158     .hw_transmit = &fake_transmit,
159     .transceive = &fake_transceive,
160     .poll = &fake_poll,
161     .close = &fake_close,
162     .opts = NULL,
163     .errors = kErrorMessages,
164     .errors_count = sizeof(kErrorMessages),
165 };
166 ESE_DEFINE_HW_OPS(ESE_HW_FAKE, ops);
167 
168