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: Jérémie 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 */
phOsalNfc_GetMemory(uint32_t size)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 */
phOsalNfc_FreeMemory(void * pMem)71 void phOsalNfc_FreeMemory(void *pMem)
72 {
73 if(NULL != pMem)
74 free(pMem);
75 }
76
phOsalNfc_DbgString(const char * pString)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
phOsalNfc_DbgTrace(uint8_t data[],uint32_t size)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 */
phOsalNfc_RaiseException(phOsalNfc_ExceptionType_t eExceptionType,uint16_t reason)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 */
phOsalNfc_PrintData(const char * pString,uint32_t length,uint8_t * pBuffer,int verbosity)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