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