1 /******************************************************************************
2  *
3  *  Copyright 2018-2020,2022 NXP
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /*
20  * DAL spi port implementation for linux
21  *
22  * Project: Trusted ESE Linux
23  *
24  */
25 #define LOG_TAG "NxpEseHal"
26 #include <EseTransportFactory.h>
27 #include <NxpTimer.h>
28 #include <errno.h>
29 #include <ese_config.h>
30 #include <ese_logs.h>
31 #include <fcntl.h>
32 #include <log/log.h>
33 #include <phEseStatus.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <sys/ioctl.h>
37 #include <unistd.h>
38 
39 /*!
40  * \brief Normal mode header length
41  */
42 #define NORMAL_MODE_HEADER_LEN 3
43 /*!
44  * \brief Normal mode header offset
45  */
46 #define NORMAL_MODE_LEN_OFFSET 2
47 /*!
48  * \brief Start of frame marker
49  */
50 #define SEND_PACKET_SOF 0x5A
51 /*!
52  * \brief To enable SPI interface for ESE communication
53  */
54 #define SPI_ENABLED 1
55 
56 spTransport gpTransportObj;
57 
58 static phPalEse_NxpTimer_t gNxpTimer;
59 
60 /*******************************************************************************
61 **
62 ** Function         phPalEse_close
63 **
64 ** Description      Closes PN547 device
65 **
66 ** Parameters       pDevHandle - device handle
67 **
68 ** Returns          None
69 **
70 *******************************************************************************/
phPalEse_close(void * pDevHandle)71 void phPalEse_close(void* pDevHandle) {
72   if (NULL != pDevHandle) {
73     gpTransportObj->Close(pDevHandle);
74   }
75   gpTransportObj = NULL;
76   return;
77 }
78 
79 /*******************************************************************************
80 **
81 ** Function         phPalEse_open_and_configure
82 **
83 ** Description      Open and configure ESE device
84 **
85 ** Parameters       pConfig     - hardware information
86 **
87 ** Returns          ESE status:
88 **                  ESESTATUS_SUCCESS            - open_and_configure operation
89 *success
90 **                  ESESTATUS_INVALID_DEVICE     - device open operation failure
91 **
92 *******************************************************************************/
phPalEse_open_and_configure(pphPalEse_Config_t pConfig)93 ESESTATUS phPalEse_open_and_configure(pphPalEse_Config_t pConfig) {
94   ESESTATUS status = ESESTATUS_FAILED;
95   if (ESESTATUS_SUCCESS != phPalEse_ConfigTransport()) return ESESTATUS_FAILED;
96   status = gpTransportObj->OpenAndConfigure(pConfig);
97   return status;
98 }
99 
100 /*******************************************************************************
101 **
102 ** Function         phPalEse_ConfigTransport
103 **
104 ** Description      Configure Transport channel based on transport type provided
105 **                  in config file
106 **
107 ** Returns          ESESTATUS_SUCCESS If transport channel is configured
108 **                  ESESTATUS_FAILED If transport channel configuration failed
109 **
110 *******************************************************************************/
phPalEse_ConfigTransport()111 ESESTATUS phPalEse_ConfigTransport() {
112   unsigned long transportType = UNKNOWN;
113 
114   transportType = EseConfig::getUnsigned(NAME_NXP_TRANSPORT, UNKNOWN);
115   ALOGD("phPalEse_ConfigTransport transport type %ld", transportType);
116   gpTransportObj = transportFactory.getTransport((transportIntf)transportType);
117   if (gpTransportObj == nullptr) {
118     return ESESTATUS_FAILED;
119   }
120   return ESESTATUS_SUCCESS;
121 }
122 
123 /*******************************************************************************
124 **
125 ** Function         phPalEse_read
126 **
127 ** Description      Reads requested number of bytes from pn547 device into given
128 *buffer
129 **
130 ** Parameters       pDevHandle       - valid device handle
131 **                  pBuffer          - buffer for read data
132 **                  nNbBytesToRead   - number of bytes requested to be read
133 **
134 ** Returns          numRead   - number of successfully read bytes
135 **                  -1        - read operation failure
136 **
137 *******************************************************************************/
phPalEse_read(void * pDevHandle,uint8_t * pBuffer,int nNbBytesToRead)138 int phPalEse_read(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToRead) {
139   int ret = -1;
140   ret = gpTransportObj->Read(pDevHandle, pBuffer, nNbBytesToRead);
141   return ret;
142 }
143 
144 /*******************************************************************************
145 **
146 ** Function         phPalEse_write
147 **
148 ** Description      Writes requested number of bytes from given buffer into
149 *pn547 device
150 **
151 ** Parameters       pDevHandle       - valid device handle
152 **                  pBuffer          - buffer for read data
153 **                  nNbBytesToWrite  - number of bytes requested to be written
154 **
155 ** Returns          numWrote   - number of successfully written bytes
156 **                  -1         - write operation failure
157 **
158 *******************************************************************************/
phPalEse_write(void * pDevHandle,uint8_t * pBuffer,int nNbBytesToWrite)159 int phPalEse_write(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToWrite) {
160   int numWrote = 0;
161 
162   if (NULL == pDevHandle) {
163     return -1;
164   }
165   numWrote = gpTransportObj->Write(pDevHandle, pBuffer, nNbBytesToWrite);
166   return numWrote;
167 }
168 
169 /*******************************************************************************
170 **
171 ** Function         phPalEse_ioctl
172 **
173 ** Description      Exposed ioctl by p61 spi driver
174 **
175 ** Parameters       pDevHandle     - valid device handle
176 **                  level          - reset level
177 **
178 ** Returns           0   - ioctl operation success
179 **                  -1   - ioctl operation failure
180 **
181 *******************************************************************************/
phPalEse_ioctl(phPalEse_ControlCode_t eControlCode,void * pDevHandle,long level)182 ESESTATUS phPalEse_ioctl(phPalEse_ControlCode_t eControlCode, void* pDevHandle,
183                          long level) {
184   ESESTATUS ret = ESESTATUS_FAILED;
185   NXP_LOG_ESE_D("phPalEse_spi_ioctl(), ioctl %x , level %lx", eControlCode,
186                 level);
187   if (GET_CHIP_OS_VERSION() == OS_VERSION_4_0) {
188     if (NULL == pDevHandle) {
189       return ESESTATUS_IOCTL_FAILED;
190     }
191   }
192   if (pDevHandle == NULL) {
193     phPalEse_ConfigTransport();
194   }
195   ret = gpTransportObj->Ioctl(eControlCode, pDevHandle, level);
196   if (pDevHandle == NULL) {
197     phPalEse_close(pDevHandle);
198   }
199 
200   return ret;
201 }
202 /*******************************************************************************
203 **
204 ** Function         phPalEse_BusyWait
205 **
206 ** Description      This function  suspends execution of the calling thread for
207 **                  total_time usecs(max extra delay 1 usecs) with busy wait.
208 **                  Use this only for short delays (less than 500 microsecs)
209 **
210 ** Returns          None
211 **
212 *******************************************************************************/
213 
phPalEse_BusyWait(long total_time)214 void phPalEse_BusyWait(long total_time /* usecs*/) {
215   struct timespec ts1, ts2;
216   clock_gettime(CLOCK_MONOTONIC, &ts1);
217   long elapsed_time = 0;  // microseconds
218   do {
219     clock_gettime(CLOCK_MONOTONIC, &ts2);
220     elapsed_time = 1e+6 * ts2.tv_sec + 1e-3 * ts2.tv_nsec -
221                    (1e+6 * ts1.tv_sec + 1e-3 * ts1.tv_nsec);
222   } while (elapsed_time < total_time);
223 }
224 
225 /*******************************************************************************
226 **
227 ** Function         phPalEse_print_packet
228 **
229 ** Description      Print packet
230 **
231 ** Returns          None
232 **
233 *******************************************************************************/
phPalEse_print_packet(const char * pString,const uint8_t * p_data,uint16_t len)234 void phPalEse_print_packet(const char* pString, const uint8_t* p_data,
235                            uint16_t len) {
236   if (ese_log_level < NXPESE_LOGLEVEL_DEBUG) return;  // debug logs disabled
237 
238   uint32_t i;
239   char print_buffer[len * 3 + 1];
240 
241   memset(print_buffer, 0, sizeof(print_buffer));
242   for (i = 0; i < len; i++) {
243     snprintf(&print_buffer[i * 2], 3, "%02X", p_data[i]);
244   }
245   if (0 == memcmp(pString, "SEND", 0x04)) {
246     NXP_LOG_ESE_D("NxpEseDataX len = %3d > %s", len, print_buffer);
247   } else if (0 == memcmp(pString, "RECV", 0x04)) {
248     NXP_LOG_ESE_D("NxpEseDataR len = %3d > %s", len, print_buffer);
249   }
250   return;
251 }
252 
253 /*******************************************************************************
254 **
255 ** Function         phPalEse_sleep
256 **
257 ** Description      This function  suspends execution of the calling thread for
258 **                  (at least) usec microseconds
259 **
260 ** Returns          None
261 **
262 *******************************************************************************/
phPalEse_sleep(long usec)263 void phPalEse_sleep(long usec) {
264   usleep(usec);
265   return;
266 }
267 
268 /*******************************************************************************
269 **
270 ** Function         phPalEse_memset
271 **
272 ** Description
273 **
274 ** Returns          None
275 **
276 *******************************************************************************/
277 
phPalEse_memset(void * buff,int val,size_t len)278 void* phPalEse_memset(void* buff, int val, size_t len) {
279   return memset(buff, val, len);
280 }
281 
282 /*******************************************************************************
283 **
284 ** Function         phPalEse_memcpy
285 **
286 ** Description
287 **
288 ** Returns          None
289 **
290 *******************************************************************************/
291 
phPalEse_memcpy(void * dest,const void * src,size_t len)292 void* phPalEse_memcpy(void* dest, const void* src, size_t len) {
293   return memcpy(dest, src, len);
294 }
295 
296 /*******************************************************************************
297 **
298 ** Function         phPalEse_memalloc
299 **
300 ** Description
301 **
302 ** Returns          None
303 **
304 *******************************************************************************/
305 
phPalEse_memalloc(uint32_t size)306 void* phPalEse_memalloc(uint32_t size) { return malloc(size); }
307 
308 /*******************************************************************************
309 **
310 ** Function         phPalEse_calloc
311 **
312 ** Description
313 **
314 ** Returns          None
315 **
316 *******************************************************************************/
317 
phPalEse_calloc(size_t datatype,size_t size)318 void* phPalEse_calloc(size_t datatype, size_t size) {
319   return calloc(datatype, size);
320 }
321 
322 /*******************************************************************************
323 **
324 ** Function         phPalEse_free
325 **
326 ** Description
327 **
328 ** Returns          None
329 **
330 *******************************************************************************/
phPalEse_free(void * ptr)331 void phPalEse_free(void* ptr) {
332   if (ptr != NULL) {
333     free(ptr);
334     ptr = NULL;
335   }
336   return;
337 }
338 /*******************************************************************************
339 **
340 ** Function         phPalEse_initTimer
341 **
342 ** Description      Initializes phPalEse_NxpTimer_t global struct
343 **
344 ** Returns          None
345 **
346 *******************************************************************************/
347 
phPalEse_initTimer()348 void phPalEse_initTimer() {
349   bool is_kpi_enabled =
350       EseConfig::getUnsigned(NAME_SE_KPI_MEASUREMENT_ENABLED, 0);
351   gNxpTimer.is_enabled = (is_kpi_enabled != 0) ? true : false;
352   if (!gNxpTimer.is_enabled) return;
353 
354   gNxpTimer.tx_timer = new NxpTimer("TX");
355   gNxpTimer.rx_timer = new NxpTimer("RX");
356 }
357 /*******************************************************************************
358 **
359 ** Function         phPalEse_getTimer
360 **
361 ** Description      Get handle to phPalEse_NxpTimer_t global struct variable
362 **
363 ** Returns          pointer to phPalEse_NxpTimer_t struct variable
364 **
365 *******************************************************************************/
366 
phPalEse_getTimer()367 const phPalEse_NxpTimer_t* phPalEse_getTimer() { return &gNxpTimer; }
368 /*******************************************************************************
369 **
370 ** Function         phPalEse_startTimer
371 **
372 ** Description      Wrapper function to start the given timer
373 **
374 ** Returns          None
375 **
376 *******************************************************************************/
377 
phPalEse_startTimer(NxpTimer * timer)378 void phPalEse_startTimer(NxpTimer* timer) {
379   if (!gNxpTimer.is_enabled) return;
380 
381   timer->startTimer();
382 }
383 /*******************************************************************************
384 **
385 ** Function         phPalEse_stopTimer
386 **
387 ** Description      Wrapper function to stop the given timer
388 **
389 ** Returns          None
390 **
391 *******************************************************************************/
392 
phPalEse_stopTimer(NxpTimer * timer)393 void phPalEse_stopTimer(NxpTimer* timer) {
394   if (!gNxpTimer.is_enabled) return;
395 
396   timer->stopTimer();
397 }
398 /*******************************************************************************
399 **
400 ** Function         phPalEse_timerDuration
401 **
402 ** Description      Wrapper function to get total time (usecs) recorded by the
403 **                  given timer
404 **
405 ** Returns          total time (in usecs) recorded by the timer
406 **
407 *******************************************************************************/
408 
phPalEse_timerDuration(NxpTimer * timer)409 unsigned long phPalEse_timerDuration(NxpTimer* timer) {
410   if (!gNxpTimer.is_enabled) return 0;
411 
412   return timer->totalDuration();
413 }
414 /*******************************************************************************
415 **
416 ** Function         phPalEse_resetTimer
417 **
418 ** Description      Function to reset both timers in gNxpTimer object
419 **
420 ** Returns          None
421 **
422 *******************************************************************************/
423 
phPalEse_resetTimer()424 void phPalEse_resetTimer() {
425   if (!gNxpTimer.is_enabled) return;
426 
427   gNxpTimer.tx_timer->resetTimer();
428   gNxpTimer.rx_timer->resetTimer();
429 }
430 
431 /*******************************************************************************
432 **
433 ** Function         phPalEse_deInitTimer
434 **
435 ** Description      Wrapper function to de-construct the timer objects
436 **
437 ** Returns          None
438 **
439 *******************************************************************************/
440 
phPalEse_deInitTimer()441 void phPalEse_deInitTimer() {
442   if (!gNxpTimer.is_enabled) return;
443 
444   delete gNxpTimer.tx_timer;
445   gNxpTimer.tx_timer = nullptr;
446 
447   delete gNxpTimer.rx_timer;
448   gNxpTimer.rx_timer = nullptr;
449 
450   gNxpTimer.is_enabled = false;
451 }
452