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 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 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 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 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 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 110 uint32_t fake_transceive(struct EseInterface *ese, const uint8_t *tx_buf, 111 uint32_t tx_len, uint8_t *rx_buf, uint32_t rx_len) { 112 uint32_t processed = 0; 113 if (!ese->pad[0] || !ese->pad[1]) { 114 ese_set_error(ese, kEseFakeHwErrorTranscieveWhileBusy); 115 return 0; 116 } 117 while (processed < tx_len) { 118 uint32_t sent = fake_transmit(ese, tx_buf, tx_len, 0); 119 if (sent == 0) { 120 if (ese_error(ese)) { 121 return 0; 122 } 123 ese_set_error(ese, kEseFakeHwErrorEmptyTransmit); 124 return 0; 125 } 126 processed += sent; 127 } 128 fake_transmit(ese, NULL, 0, 1); /* Complete. */ 129 if (fake_poll(ese, 0xad, 10, 0) != 1) { 130 ese_set_error(ese, kEseGlobalErrorPollTimedOut); 131 return 0; 132 } 133 /* A real implementation would have protocol errors to contend with. */ 134 processed = fake_receive(ese, rx_buf, rx_len, 1); 135 return processed; 136 } 137 138 static const struct EseOperations ops = { 139 .name = "eSE Fake Hardware", 140 .open = &fake_open, 141 .hw_receive = &fake_receive, 142 .hw_transmit = &fake_transmit, 143 .transceive = &fake_transceive, 144 .poll = &fake_poll, 145 .close = &fake_close, 146 .opts = NULL, 147 .errors = kErrorMessages, 148 .errors_count = sizeof(kErrorMessages), 149 }; 150 ESE_DEFINE_HW_OPS(ESE_HW_FAKE, ops); 151 152