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