C++程序  |  215行  |  5.49 KB

/*
 * Copyright (C) 2010 NXP Semiconductors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * \file phOsalNfc.c
 * \brief OSAL Implementation for linux
 *
 * Project: Trusted NFC Linux Light
 *
 * $Date: 03 aug 2009
 * $Author: Jérémie Corbier
 * $Revision: 1.0
 *
 */

#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>

#include <phOsalNfc.h>

#ifdef ANDROID
#define LOG_TAG "NFC-HCI"

#include <utils/Log.h>

phOsalNfc_Exception_t phOsalNfc_Exception;
#endif

#ifdef DEBUG
#define MAX_PRINT_BUFSIZE (0x450U)
char phOsalNfc_DbgTraceBuffer[MAX_PRINT_BUFSIZE];
#endif

void phLibNfc_Mgt_Recovery();

/*!
 * \brief Allocates memory.
 *        This function attempts to allocate \a size bytes on the heap and
 *        returns a pointer to the allocated block.
 *
 * \param size size of the memory block to be allocated on the heap.
 *
 * \return pointer to allocated memory block or NULL in case of error.
 */
void *phOsalNfc_GetMemory(uint32_t size)
{
   void *pMem = (void *)malloc(size);
   return pMem;
}

/*!
 * \brief Frees allocated memory block.
 *        This function deallocates memory region pointed to by \a pMem.
 *
 * \param pMem pointer to memory block to be freed.
 */
void phOsalNfc_FreeMemory(void *pMem)
{
   if(NULL !=  pMem)
      free(pMem);
}

void phOsalNfc_DbgString(const char *pString)
{
#ifdef DEBUG
   if(pString != NULL)
#ifndef ANDROID
      printf(pString);
#else
      ALOGD("%s", pString);
#endif
#endif
}

void phOsalNfc_DbgTrace(uint8_t data[], uint32_t size)
{
#ifdef DEBUG
   uint32_t i;
#ifdef ANDROID
   char buf[10];
#endif

   if(size == 0)
      return;

#ifndef ANDROID
   for(i = 0; i < size; i++)
   {
      if((i % 10) == 0)
         printf("\n\t\t\t");
      printf("%02X ", data[i]);
   }
   printf("\n\tBlock size is: %d\n", size);
#else
   phOsalNfc_DbgTraceBuffer[0] = '\0';
   for(i = 0; i < size; i++)
   {
      if((i % 10) == 0)
      {
         ALOGD("%s", phOsalNfc_DbgTraceBuffer);
         phOsalNfc_DbgTraceBuffer[0] = '\0';
      }

      snprintf(buf, 10, "%02X ", data[i]);
      strncat(phOsalNfc_DbgTraceBuffer, buf, 10);
   }
   ALOGD("%s", phOsalNfc_DbgTraceBuffer);
   ALOGD("Block size is: %d", size);
#endif
#endif
}

/*!
 * \brief Raises exception.
 *        This function raises an exception of type \a eExceptionType with
 *        reason \a reason to stack clients.
 *
 * \param eExceptionType exception type.
 * \param reason reason for this exception.
 *
 * \note Clients willing to catch exceptions are to handle the SIGABRT signal.
 *       On Linux, exception type and reason are passed to the signal handler as
 *       a pointer to a phOsalNfc_Exception_t structure.
 *       As sigqueue is not available in Android, exception information are
 *       stored in the phOsalNfc_Exception global.
 */
void phOsalNfc_RaiseException(phOsalNfc_ExceptionType_t eExceptionType, uint16_t reason)
{
    if(eExceptionType == phOsalNfc_e_UnrecovFirmwareErr)
    {
        ALOGE("HCI Timeout - Exception raised - Force restart of NFC service");
        phLibNfc_Mgt_Recovery();
        abort();
    } else {
        ALOGD("phOsalNfc_RaiseException() called");
    }
}

/*!
 * \brief display data bytes.
 *        This function displays data bytes for debug purpose
 * \param[in] pString pointer to string to be displayed.
 * \param[in] length number of bytes to be displayed.
 * \param[in] pBuffer pointer to data bytes to be displayed.
 *
 */
void phOsalNfc_PrintData(const char *pString, uint32_t length, uint8_t *pBuffer,
        int verbosity)
{
    char print_buffer[length * 3 + 1];
    unsigned int i;

    if (pString == NULL) {
        pString = "";
    }
    print_buffer[0] = '\0';
    for (i = 0; i < length; i++) {
        snprintf(&print_buffer[i*3], 4, " %02X", pBuffer[i]);
    }

    char llc[40] = "";

    if (verbosity >= 2) {
        uint8_t llc_header = 0;
        if (!strcmp(pString, "SEND") && length >= 2) {
            llc_header = pBuffer[1];
        } else if (!strcmp(pString, "RECV") && length >= 2) {
            llc_header = pBuffer[0];
        }

        if ((llc_header & 0xC0) == 0x80) {
            // I
            uint8_t ns = (llc_header & 0x38) >> 3;
            uint8_t nr = llc_header & 0x07;
            snprintf(&llc[0], sizeof(llc), "I %d (%d)", ns, nr);
        } else if ((llc_header & 0xE0) == 0xC0) {
            // S
            uint8_t t = (llc_header & 0x18) >> 3;
            uint8_t nr = llc_header & 0x07;
            char *type;
            switch (t) {
            case 0x00: type = "RR "; break;
            case 0x01: type = "REJ"; break;
            case 0x02: type = "RNR"; break;
            case 0x03: type = "SREJ"; break;
            default: type = "???"; break;
            }
            snprintf(&llc[0], sizeof(llc), "S %s (%d)", type, nr);
        } else if ((llc_header & 0xE0) == 0xE0) {
            // U
            snprintf(&llc[0], sizeof(llc), "U");
        } else if (length > 1) {
            snprintf(&llc[0], sizeof(llc), "???");
        }
    }

    ALOGD("> %s:%s\t%s", pString, print_buffer, llc);
}