Home | History | Annotate | Download | only in Linux_x86
      1 /*
      2  * Copyright (C) 2010 NXP Semiconductors
      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 /**
     18  * \file phOsalNfc.c
     19  * \brief OSAL Implementation for linux
     20  *
     21  * Project: Trusted NFC Linux Light
     22  *
     23  * $Date: 03 aug 2009
     24  * $Author: Jrmie Corbier
     25  * $Revision: 1.0
     26  *
     27  */
     28 
     29 #include <stddef.h>
     30 #include <stdlib.h>
     31 #include <stdio.h>
     32 #include <signal.h>
     33 #include <unistd.h>
     34 
     35 #include <phOsalNfc.h>
     36 
     37 #ifdef ANDROID
     38 #define LOG_TAG "NFC-HCI"
     39 
     40 #include <utils/Log.h>
     41 
     42 phOsalNfc_Exception_t phOsalNfc_Exception;
     43 #endif
     44 
     45 #ifdef DEBUG
     46 #define MAX_PRINT_BUFSIZE (0x450U)
     47 char phOsalNfc_DbgTraceBuffer[MAX_PRINT_BUFSIZE];
     48 #endif
     49 
     50 /*!
     51  * \brief Allocates memory.
     52  *        This function attempts to allocate \a size bytes on the heap and
     53  *        returns a pointer to the allocated block.
     54  *
     55  * \param size size of the memory block to be allocated on the heap.
     56  *
     57  * \return pointer to allocated memory block or NULL in case of error.
     58  */
     59 void *phOsalNfc_GetMemory(uint32_t size)
     60 {
     61    void *pMem = (void *)malloc(size);
     62    return pMem;
     63 }
     64 
     65 /*!
     66  * \brief Frees allocated memory block.
     67  *        This function deallocates memory region pointed to by \a pMem.
     68  *
     69  * \param pMem pointer to memory block to be freed.
     70  */
     71 void phOsalNfc_FreeMemory(void *pMem)
     72 {
     73    if(NULL !=  pMem)
     74       free(pMem);
     75 }
     76 
     77 void phOsalNfc_DbgString(const char *pString)
     78 {
     79 #ifdef DEBUG
     80    if(pString != NULL)
     81 #ifndef ANDROID
     82       printf(pString);
     83 #else
     84       LOGD("%s", pString);
     85 #endif
     86 #endif
     87 }
     88 
     89 void phOsalNfc_DbgTrace(uint8_t data[], uint32_t size)
     90 {
     91 #ifdef DEBUG
     92    uint32_t i;
     93 #ifdef ANDROID
     94    char buf[10];
     95 #endif
     96 
     97    if(size == 0)
     98       return;
     99 
    100 #ifndef ANDROID
    101    for(i = 0; i < size; i++)
    102    {
    103       if((i % 10) == 0)
    104          printf("\n\t\t\t");
    105       printf("%02X ", data[i]);
    106    }
    107    printf("\n\tBlock size is: %d\n", size);
    108 #else
    109    phOsalNfc_DbgTraceBuffer[0] = '\0';
    110    for(i = 0; i < size; i++)
    111    {
    112       if((i % 10) == 0)
    113       {
    114          LOGD("%s", phOsalNfc_DbgTraceBuffer);
    115          phOsalNfc_DbgTraceBuffer[0] = '\0';
    116       }
    117 
    118       snprintf(buf, 10, "%02X ", data[i]);
    119       strncat(phOsalNfc_DbgTraceBuffer, buf, 10);
    120    }
    121    LOGD("%s", phOsalNfc_DbgTraceBuffer);
    122    LOGD("Block size is: %d", size);
    123 #endif
    124 #endif
    125 }
    126 
    127 /*!
    128  * \brief Raises exception.
    129  *        This function raises an exception of type \a eExceptionType with
    130  *        reason \a reason to stack clients.
    131  *
    132  * \param eExceptionType exception type.
    133  * \param reason reason for this exception.
    134  *
    135  * \note Clients willing to catch exceptions are to handle the SIGABRT signal.
    136  *       On Linux, exception type and reason are passed to the signal handler as
    137  *       a pointer to a phOsalNfc_Exception_t structure.
    138  *       As sigqueue is not available in Android, exception information are
    139  *       stored in the phOsalNfc_Exception global.
    140  */
    141 void phOsalNfc_RaiseException(phOsalNfc_ExceptionType_t eExceptionType, uint16_t reason)
    142 {
    143     LOGD("phOsalNfc_RaiseException() called");
    144 
    145     if(eExceptionType == phOsalNfc_e_UnrecovFirmwareErr)
    146     {
    147         LOGE("HCI Timeout - Exception raised");
    148         LOGE("Force restart of NFC Service");
    149         abort();
    150     }
    151 }
    152 
    153 /*!
    154  * \brief display data bytes.
    155  *        This function displays data bytes for debug purpose
    156  * \param[in] pString pointer to string to be displayed.
    157  * \param[in] length number of bytes to be displayed.
    158  * \param[in] pBuffer pointer to data bytes to be displayed.
    159  *
    160  */
    161 void phOsalNfc_PrintData(const char *pString, uint32_t length, uint8_t *pBuffer,
    162         int verbosity)
    163 {
    164     char print_buffer[length * 3 + 1];
    165     unsigned int i;
    166 
    167     if (pString == NULL) {
    168         pString = "";
    169     }
    170     print_buffer[0] = '\0';
    171     for (i = 0; i < length; i++) {
    172         snprintf(&print_buffer[i*3], 4, " %02X", pBuffer[i]);
    173     }
    174 
    175     char llc[40] = "";
    176 
    177     if (verbosity >= 2) {
    178         uint8_t llc_header = 0;
    179         if (!strcmp(pString, "SEND") && length >= 2) {
    180             llc_header = pBuffer[1];
    181         } else if (!strcmp(pString, "RECV") && length >= 2) {
    182             llc_header = pBuffer[0];
    183         }
    184 
    185         if ((llc_header & 0xC0) == 0x80) {
    186             // I
    187             uint8_t ns = (llc_header & 0x38) >> 3;
    188             uint8_t nr = llc_header & 0x07;
    189             snprintf(&llc[0], sizeof(llc), "I %d (%d)", ns, nr);
    190         } else if ((llc_header & 0xE0) == 0xC0) {
    191             // S
    192             uint8_t t = (llc_header & 0x18) >> 3;
    193             uint8_t nr = llc_header & 0x07;
    194             char *type;
    195             switch (t) {
    196             case 0x00: type = "RR "; break;
    197             case 0x01: type = "REJ"; break;
    198             case 0x02: type = "RNR"; break;
    199             case 0x03: type = "SREJ"; break;
    200             default: type = "???"; break;
    201             }
    202             snprintf(&llc[0], sizeof(llc), "S %s (%d)", type, nr);
    203         } else if ((llc_header & 0xE0) == 0xE0) {
    204             // U
    205             snprintf(&llc[0], sizeof(llc), "U");
    206         } else if (length > 1) {
    207             snprintf(&llc[0], sizeof(llc), "???");
    208         }
    209     }
    210 
    211     LOGD("> %s:%s\t%s", pString, print_buffer, llc);
    212 }
    213