1 /******************************************************************************
2  *
3  *  Copyright (C) 2017 ST Microelectronics S.A.
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 #define LOG_TAG "NfcNciHalWrapper"
20 #include <cutils/properties.h>
21 #include <errno.h>
22 #include <hardware/nfc.h>
23 #include <string.h>
24 #include "android_logmsg.h"
25 #include "halcore.h"
26 
27 extern void HalCoreCallback(void* context, uint32_t event, const void* d,
28                             size_t length);
29 extern bool I2cOpenLayer(void* dev, HAL_CALLBACK callb, HALHANDLE* pHandle);
30 extern void I2cCloseLayer();
31 
32 typedef struct {
33   struct nfc_nci_device nci_device;  // nci_device must be first struct member
34   // below declarations are private variables within HAL
35   nfc_stack_callback_t* p_cback;
36   nfc_stack_data_callback_t* p_data_cback;
37   HALHANDLE hHAL;
38 } st21nfc_dev_t;
39 
40 typedef enum {
41   HAL_WRAPPER_STATE_CLOSED,
42   HAL_WRAPPER_STATE_OPEN,
43   HAL_WRAPPER_STATE_OPEN_CPLT,
44   HAL_WRAPPER_STATE_NFC_ENABLE_ON,
45   HAL_WRAPPER_STATE_READY
46 } hal_wrapper_state_e;
47 
48 static void halWrapperDataCallback(uint16_t data_len, uint8_t* p_data);
49 static void halWrapperCallback(uint8_t event, uint8_t event_status);
50 
51 nfc_stack_callback_t* mHalWrapperCallback = NULL;
52 nfc_stack_data_callback_t* mHalWrapperDataCallback = NULL;
53 hal_wrapper_state_e mHalWrapperState = HAL_WRAPPER_STATE_CLOSED;
54 HALHANDLE mHalHandle = NULL;
55 
hal_wrapper_open(st21nfc_dev_t * dev,nfc_stack_callback_t * p_cback,nfc_stack_data_callback_t * p_data_cback,HALHANDLE * pHandle)56 bool hal_wrapper_open(st21nfc_dev_t* dev, nfc_stack_callback_t* p_cback,
57                       nfc_stack_data_callback_t* p_data_cback,
58                       HALHANDLE* pHandle) {
59   bool result;
60 
61   STLOG_HAL_D("%s", __func__);
62 
63   mHalWrapperState = HAL_WRAPPER_STATE_OPEN;
64 
65   mHalWrapperCallback = p_cback;
66   mHalWrapperDataCallback = p_data_cback;
67 
68   dev->p_data_cback = halWrapperDataCallback;
69   dev->p_cback = halWrapperCallback;
70 
71   result = I2cOpenLayer(dev, HalCoreCallback, pHandle);
72 
73   if (!result || !(*pHandle)) {
74     return -1;  // We are doomed, stop it here, NOW !
75   }
76 
77   mHalHandle = *pHandle;
78 
79   return 1;
80 }
81 
hal_wrapper_close(int call_cb)82 int hal_wrapper_close(int call_cb) {
83 
84   STLOG_HAL_D("%s", __func__);
85 
86   mHalWrapperState = HAL_WRAPPER_STATE_CLOSED;
87   I2cCloseLayer();
88   if (call_cb)
89   mHalWrapperCallback(HAL_NFC_CLOSE_CPLT_EVT, HAL_NFC_STATUS_OK);
90 
91   return 1;
92 }
93 
halWrapperDataCallback(uint16_t data_len,uint8_t * p_data)94 void halWrapperDataCallback(uint16_t data_len, uint8_t* p_data) {
95   uint8_t propNfcModeSetCmdOn[] = {0x2f, 0x02, 0x02, 0x02, 0x01};
96   uint8_t coreInitCmd[] = {0x20, 0x01, 0x02, 0x00, 0x00};
97 
98   STLOG_HAL_D("%s - mHalWrapperState = %d", __func__, mHalWrapperState);
99 
100   switch (mHalWrapperState) {
101     case HAL_WRAPPER_STATE_CLOSED:  // 0
102       break;
103     case HAL_WRAPPER_STATE_OPEN:  // 1
104       // CORE_RESET_NTF
105       if ((p_data[0] == 0x60) && (p_data[1] == 0x00)) {
106         if (p_data[3] == 0x01) {
107           mHalWrapperCallback(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_OK);
108           mHalWrapperState = HAL_WRAPPER_STATE_OPEN_CPLT;
109         } else if (p_data[3] == 0xa1)  // Loader mode
110         {
111           mHalWrapperCallback(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_FAILED);
112         }
113       } else {
114         mHalWrapperDataCallback(data_len, p_data);
115       }
116       break;
117     case HAL_WRAPPER_STATE_OPEN_CPLT:  // 2
118       // CORE_INIT_RSP
119       if ((p_data[0] == 0x40) && (p_data[1] == 0x01)) {
120       } else if ((p_data[0] == 0x60) && (p_data[1] == 0x06)) {
121         STLOG_HAL_D("%s - Sending PROP_NFC_MODE_SET_CMD", __func__);
122         // Send PROP_NFC_MODE_SET_CMD(ON)
123         if (!HalSendDownstreamTimer(mHalHandle, propNfcModeSetCmdOn,
124                                     sizeof(propNfcModeSetCmdOn), 100)) {
125           STLOG_HAL_E("NFC-NCI HAL: %s  HalSendDownstreamTimer failed", __func__);
126         }
127         mHalWrapperState = HAL_WRAPPER_STATE_NFC_ENABLE_ON;
128       } else {
129         mHalWrapperDataCallback(data_len, p_data);
130       }
131       break;
132     case HAL_WRAPPER_STATE_NFC_ENABLE_ON:  // 3
133       // PROP_NFC_MODE_SET_RSP
134       if ((p_data[0] == 0x4f) && (p_data[1] == 0x02)) {
135         // DO nothing: wait for core_reset_ntf or timer timeout
136       }
137       // CORE_RESET_NTF
138       else if ((p_data[0] == 0x60) && (p_data[1] == 0x00)) {
139         // Stop timer
140         HalSendDownstreamStopTimer(mHalHandle);
141 
142         // Send CORE_INIT_CMD
143         STLOG_HAL_D("%s - Sending CORE_INIT_CMD", __func__);
144         if (!HalSendDownstream(mHalHandle, coreInitCmd, sizeof(coreInitCmd))) {
145            STLOG_HAL_E("NFC-NCI HAL: %s  SendDownstream failed", __func__);
146         }
147       }
148       // CORE_INIT_RSP
149       else if ((p_data[0] == 0x40) && (p_data[1] == 0x01)) {
150         STLOG_HAL_D("%s - NFC mode enabled", __func__);
151         mHalWrapperState = HAL_WRAPPER_STATE_READY;
152         mHalWrapperDataCallback(data_len, p_data);
153       }
154       break;
155     case HAL_WRAPPER_STATE_READY:
156       mHalWrapperDataCallback(data_len, p_data);
157       break;
158   }
159 }
160 
halWrapperCallback(uint8_t event,uint8_t event_status)161 static void halWrapperCallback(uint8_t event, uint8_t event_status) {
162   uint8_t coreInitCmd[] = {0x20, 0x01, 0x02, 0x00, 0x00};
163 
164   switch (mHalWrapperState) {
165     case HAL_WRAPPER_STATE_CLOSED:
166       break;
167 
168     case HAL_WRAPPER_STATE_OPEN:
169       break;
170 
171     case HAL_WRAPPER_STATE_OPEN_CPLT:
172       break;
173 
174     case HAL_WRAPPER_STATE_NFC_ENABLE_ON:
175       if (event == HAL_WRAPPER_TIMEOUT_EVT) {
176         // timeout
177         // Send CORE_INIT_CMD
178           STLOG_HAL_D("%s - Sending CORE_INIT_CMD", __func__);
179         if (!HalSendDownstream(mHalHandle, coreInitCmd, sizeof(coreInitCmd))) {
180             STLOG_HAL_E("NFC-NCI HAL: %s  SendDownstream failed", __func__);
181         }
182         return;
183       }
184       break;
185 
186     case HAL_WRAPPER_STATE_READY:
187       break;
188 
189     default:
190       break;
191   }
192 
193   mHalWrapperCallback(event, event_status);
194 }
195