Home | History | Annotate | Download | only in libese-hw
      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