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