1 /*
2  *    Copyright (C) 2013 SAMSUNG S.LSI
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 
19 #include <hardware/nfc.h>
20 #include <malloc.h>
21 #include <string.h>
22 
23 #include "device.h"
24 #include "hal.h"
25 #include "hal_msg.h"
26 #include "osi.h"
27 #include "util.h"
28 
29 #include <cutils/properties.h>
30 
31 uint32_t fw_update_state = 0;
32 /* START [181106] Patch for supporting NCI v2.0 */
33 // [1. NCI Version Management]
34 int gNciVersion = NCI_VER_1_0;  // 0x10 : NCI 1.0, 0x20 : NCI2.0
35 /* END [181106] Patch for supporting NCI v2.0 */
36 
nfc_hal_state_switch(tNFC_HAL_MSG * msg,eHAL_STATE state)37 static void nfc_hal_state_switch(tNFC_HAL_MSG* msg, eHAL_STATE state) {
38   tNFC_HAL_MSG* new_msg;
39 
40   new_msg = (tNFC_HAL_MSG*)OSI_mem_get(HAL_EVT_SIZE);
41   if (!new_msg) {
42     OSI_loge("Failed to memory allocate!");
43     nfc_stack_cback(HAL_NFC_ERROR_EVT, HAL_NFC_STATUS_OK);
44     return;
45   }
46 
47   nfc_hal_info.state = state;
48   memcpy(new_msg, msg, sizeof(HAL_EVT_SIZE));
49   OSI_queue_put(nfc_hal_info.msg_q, (void*)new_msg);
50 }
51 
hal_sleep(void * param)52 void hal_sleep(__attribute__((unused)) void* param) {
53   nfc_hal_info.flag &= ~HAL_FLAG_PROP_ONE_TIMER;
54   nfc_hal_info.cfg.override_timeout = 0;
55   device_sleep();
56 }
57 
hal_update_sleep_timer(void)58 void hal_update_sleep_timer(void) {
59   device_wakeup();
60 
61   /* workaround for double timer */
62   if (nfc_hal_info.flag & HAL_FLAG_MASK_USING_TIMER) return;
63 
64   if (nfc_hal_info.flag & HAL_FLAG_PROP_ONE_TIMER)
65     OSI_timer_start(nfc_hal_info.sleep_timer, nfc_hal_info.cfg.override_timeout,
66                     (tOSI_TIMER_CALLBACK)hal_sleep, NULL);
67   else
68     OSI_timer_start(nfc_hal_info.sleep_timer, nfc_hal_info.cfg.sleep_timeout,
69                     (tOSI_TIMER_CALLBACK)hal_sleep, NULL);
70 }
71 
__send_to_device(uint8_t * data,size_t len)72 int __send_to_device(uint8_t* data, size_t len) {
73   hal_update_sleep_timer();
74   if (nfc_hal_info.nci_last_pkt)
75     memcpy((void*)nfc_hal_info.nci_last_pkt, (void*)data, len);
76 
77   return device_write(data, len);
78 }
79 
nfc_hal_open_sm(tNFC_HAL_MSG * msg)80 void nfc_hal_open_sm(tNFC_HAL_MSG* msg) {
81   tNFC_NCI_PKT* pkt = &msg->nci_packet;
82 
83   switch (msg->event) {
84     case HAL_EVT_OPEN:
85       device_set_mode(NFC_DEV_MODE_ON);
86       hal_nci_send_prop_fw_cfg();
87       break;
88     case HAL_EVT_READ:
89       nci_read_payload(msg);
90       util_nci_analyzer(pkt);
91       if (NCI_MT(pkt) != NCI_MT_RSP || NCI_GID(pkt) != NCI_GID_PROP ||
92           NCI_OID(pkt) != NCI_PROP_FW_CFG) {
93         OSI_logd("Not matched rsponse!! we expect NCI_PROP_FW_CFG_RSP");
94       } else {
95         if (NCI_STATUS(pkt) != NCI_STATUS_OK &&
96             NCI_STATUS(pkt) != NCI_STATUS_E_SYNTAX &&
97             NCI_STATUS(pkt) != NCI_CLOCK_STATUS_SYNTAX_ERROR &&
98             NCI_STATUS(pkt) != NCI_CLOCK_STATUS_MISMATCHED &&
99             NCI_STATUS(pkt) != NCI_CLOCK_STATUS_FULL) {
100           OSI_loge("Failed to config FW, status: %d", NCI_STATUS(pkt));
101           break;
102         } else {
103           if (NCI_STATUS(pkt) == NCI_STATUS_OK) {
104             nfc_hal_info.state = HAL_STATE_POSTINIT;
105             nfc_stack_cback(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_OK);
106             break;
107           }
108           OSI_loge("Failed to config FW, status: %d", NCI_STATUS(pkt));
109         }
110       }
111       break;
112     case HAL_EVT_COMPLETE_FAILED:
113       device_set_mode(NFC_DEV_MODE_OFF);
114       nfc_stack_cback(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_FAILED);
115       break;
116 
117     case HAL_EVT_TERMINATE:
118       // TODO: terminate
119       break;
120     default:
121       break;
122   }
123 }
124 
nfc_hal_postinit_sm(tNFC_HAL_MSG * msg)125 void nfc_hal_postinit_sm(tNFC_HAL_MSG* msg) {
126   tNFC_NCI_PKT* pkt = &msg->nci_packet;
127 
128   switch (msg->event) {
129     case HAL_EVT_CORE_INIT:
130       nfc_hal_info.vs_info.state = VS_INIT;
131       nfc_hal_state_switch(msg, HAL_STATE_VS);
132       break;
133 
134     case HAL_EVT_WRITE:
135       if (NCI_GID(pkt) == NCI_GID_CORE) {
136         if (NCI_OID(pkt) == NCI_CORE_RESET && NCI_LEN(pkt) == 1) {
137           if (nfc_hal_info.flag & HAL_FLAG_ALREADY_RESET) goto complete;
138 
139           nfc_hal_info.flag |= HAL_FLAG_W4_CORE_RESET_RSP;
140           OSI_timer_start(nfc_hal_info.nci_timer, 1000,
141                           (tOSI_TIMER_CALLBACK)fw_force_update, NULL);
142           OSI_logd("set flag to 0x%06X", nfc_hal_info.flag);
143         } else if (NCI_OID(pkt) == NCI_CORE_INIT &&
144                    (NCI_LEN(pkt) == 0 || NCI_LEN(pkt) == 2)) {
145           if (nfc_hal_info.flag & HAL_FLAG_ALREADY_INIT) goto complete;
146 
147           nfc_hal_info.flag |= HAL_FLAG_W4_CORE_INIT_RSP;
148           OSI_timer_start(nfc_hal_info.nci_timer, 1000,
149                           (tOSI_TIMER_CALLBACK)nci_init_timeout, NULL);
150           OSI_logd("set flag to 0x%06X", nfc_hal_info.flag);
151         }
152       }
153       hal_nci_send(&msg->nci_packet);
154       break;
155 
156     case HAL_EVT_READ:
157       nci_read_payload(msg);
158       if (NCI_GID(pkt) == NCI_GID_CORE) {
159         if (NCI_OID(pkt) == NCI_CORE_RESET) {
160           OSI_logd("Respond CORE_RESET_RSP");
161           nfc_hal_info.flag &= ~HAL_FLAG_W4_CORE_RESET_RSP;
162           nfc_hal_info.flag |= HAL_FLAG_ALREADY_RESET;
163           /* START [19082300] Patch for supporting NCI v2.0 */
164           // [1. NCI Version Management]
165           // gNciVersion : 0x10 : NCI1.0, 0x20 : NCI2.0
166           if ((NCI_LEN(pkt) == 0x03) && NCI_MT(pkt) == NCI_MT_RSP)
167             gNciVersion = NCI_VER_1_0;
168           else {
169             gNciVersion = NCI_VER_2_0;
170           }
171           /* END [19082300] Patch for supporting NCI v2.0 */
172         } else if (NCI_OID(pkt) == NCI_CORE_INIT) {
173           OSI_logd("Respond CORE_INIT_RSP");
174           nfc_hal_info.flag &= ~HAL_FLAG_W4_CORE_INIT_RSP;
175           nfc_hal_info.flag |= HAL_FLAG_ALREADY_INIT;
176         }
177         OSI_timer_stop(nfc_hal_info.nci_timer);
178       }
179       util_nci_analyzer(pkt);
180       nfc_data_callback(&msg->nci_packet);
181       break;
182 
183     case HAL_EVT_COMPLETE:
184     complete:
185       nfc_hal_info.flag |= HAL_FLAG_NTF_TRNS_ERROR | HAL_FLAG_RETRY_TRNS;
186       nfc_hal_info.state = HAL_STATE_SERVICE;
187 
188       OSI_logd("Complete postinit sm");
189 
190       nfc_stack_cback(HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_OK);
191       break;
192     case HAL_EVT_COMPLETE_FAILED:
193       nfc_stack_cback(HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED);
194       break;
195 
196     /* START - VTS */
197     case HAL_EVT_POWER_CYCLE:
198       OSI_logt("HAL_EVT_POWER_CYCLE");
199       device_sleep();
200       device_close();
201       OSI_logt("HAL state change to POWERCYCLE");
202       nfc_hal_state_switch(msg, HAL_STATE_POWERCYCLE);
203       break;
204       /* END - VTS */
205 
206     case HAL_EVT_TERMINATE:
207       // TODO: terminate
208       break;
209     default:
210       break;
211   }
212 }
213 
nfc_hal_vs_sm(tNFC_HAL_MSG * msg)214 void nfc_hal_vs_sm(tNFC_HAL_MSG* msg) {
215   tNFC_HAL_VS_INFO* vs = &nfc_hal_info.vs_info;
216 
217   if (msg->event != HAL_EVT_READ && msg->event != HAL_EVT_CORE_INIT) {
218     OSI_loge("Unexpected event [%d]", msg->event);
219     return;
220   }
221 
222   if (vs->state != VS_INIT) {
223     nci_read_payload(msg);
224     util_nci_analyzer(pkt);
225   }
226 
227   switch (vs->state) {
228     case VS_INIT:
229       hal_nci_send_clearLmrt();
230       vs->state = VS_W4_COMPLETE;
231       break;
232     case VS_W4_COMPLETE:
233       OSI_logd("Vendor Specific is complete.");
234       msg->event = HAL_EVT_COMPLETE;
235       nfc_hal_state_switch(msg, HAL_STATE_POSTINIT);
236       break;
237     default:
238       OSI_loge("Unexpected event [%d]", msg->event);
239       break;
240   }
241 }
242 
nfc_hal_service_sm(tNFC_HAL_MSG * msg)243 void nfc_hal_service_sm(tNFC_HAL_MSG* msg) {
244   tNFC_NCI_PKT* pkt = &msg->nci_packet;
245   /* START [H16031401] */
246   nfc_hal_info.msg_event = msg->event;
247   /* END [H16031401] */
248 
249   switch (msg->event) {
250     /* START - VTS */
251     case HAL_EVT_CORE_INIT:
252       nfc_hal_info.vs_info.state = VS_INIT;
253       nfc_hal_state_switch(msg, HAL_STATE_VS);
254       break;
255     /* END - VTS */
256     case HAL_EVT_WRITE:
257       if (nfc_hal_prehandler(pkt)) hal_nci_send(pkt);
258       break;
259     case HAL_EVT_READ:
260       nci_read_payload(msg);
261       util_nci_analyzer(pkt);
262       hal_update_sleep_timer();
263       if (nfc_hal_prehandler(pkt)) nfc_data_callback(pkt);
264       break;
265     case HAL_EVT_CONTROL_GRANTED:
266       nfc_hal_state_switch(msg, HAL_STATE_GRANTED);
267       break;
268     case HAL_EVT_TERMINATE:
269       // TODO: terminate
270       break;
271     default:
272       break;
273   }
274 }
275 
nfc_hal_grant_finish(void)276 static void nfc_hal_grant_finish(void) {
277   nfc_stack_cback(HAL_NFC_RELEASE_CONTROL_EVT, HAL_NFC_STATUS_OK);
278   nfc_hal_info.state = HAL_STATE_SERVICE;
279   nfc_hal_info.grant_cback = NULL;
280 }
281 
nfc_hal_grant_sm(tNFC_HAL_MSG * msg)282 void nfc_hal_grant_sm(tNFC_HAL_MSG* msg) {
283   tNFC_NCI_PKT* pkt = &msg->nci_packet;
284   uint8_t cback_ret = HAL_GRANT_FINISH;
285 
286   /* Granted mode is not need to SLEEP.
287    * hal should pend granted mode just few time */
288   switch (msg->event) {
289     case HAL_EVT_READ:
290       nci_read_payload(msg);
291       util_nci_analyzer(pkt);
292       cback_ret = nfc_hal_info.grant_cback(pkt);
293       if (cback_ret == HAL_GRANT_FINISH) nfc_hal_grant_finish();
294 
295       if (cback_ret != HAL_GRANT_SEND_NEXT) break;
296       [[fallthrough]];
297     case HAL_EVT_CONTROL_GRANTED:
298       pkt = (tNFC_NCI_PKT*)OSI_queue_get(nfc_hal_info.nci_q);
299       if (pkt) {
300         // TODO: Should CLF respond?
301         hal_nci_send(pkt);
302         OSI_mem_free((tOSI_MEM_HANDLER)pkt);
303       } else
304         nfc_hal_grant_finish();
305 
306       break;
307 
308     case HAL_EVT_WRITE:
309       OSI_loge("HAL is in granted mode!");
310       break;
311   }
312 }
313 /* START - VTS */
nfc_hal_power_sm(tNFC_HAL_MSG * msg)314 void nfc_hal_power_sm(tNFC_HAL_MSG* msg) {
315   switch (msg->event) {
316     case HAL_EVT_POWER_CYCLE:
317       // have to do is hal open
318       OSI_logt("HAL_EVT_POWER_CYCLE");
319       // nfc_hal_init();
320 
321       if (device_open()) return;
322 
323       msg->event = HAL_EVT_OPEN;
324       nfc_hal_state_switch(msg, HAL_STATE_OPEN);
325       break;
326     default:
327       break;
328   }
329 }
330 /* END - VTS */
331 
332 /* TASK */
nfc_hal_task(void)333 void nfc_hal_task(void) {
334   tNFC_HAL_MSG* msg;
335   eHAL_STATE old_st;
336 
337   OSI_logt("enter!");
338 
339   if (!nfc_hal_info.msg_task || !nfc_hal_info.nci_timer ||
340       !nfc_hal_info.msg_q || !nfc_hal_info.nci_q) {
341     OSI_loge("msg_task = %p, nci_timer = %p, msg_q = %p, nci_q = %p",
342              nfc_hal_info.msg_task, nfc_hal_info.nci_timer, nfc_hal_info.msg_q,
343              nfc_hal_info.nci_q);
344 
345     nfc_hal_deinit();
346     OSI_loge("nfc_hal initialization is not succeeded.");
347     nfc_stack_cback(HAL_NFC_ERROR_EVT, HAL_NFC_STATUS_FAILED);
348     return;
349   }
350 
351   while (OSI_task_isRun(nfc_hal_info.msg_task) == OSI_RUN) {
352     msg = (tNFC_HAL_MSG*)OSI_queue_get_wait(nfc_hal_info.msg_q);
353     if (!msg) continue;
354 
355     OSI_logd("Got a event: %s(%d)", event_to_string(msg->event), msg->event);
356     if (msg->event == HAL_EVT_TERMINATE) break;
357 
358     OSI_logd("current state: %s", state_to_string(nfc_hal_info.state));
359     old_st = nfc_hal_info.state;
360     switch (nfc_hal_info.state) {
361       case HAL_STATE_INIT:
362       case HAL_STATE_DEINIT:
363       case HAL_STATE_OPEN:
364         nfc_hal_open_sm(msg);
365         break;
366       case HAL_STATE_VS:
367         nfc_hal_vs_sm(msg);
368         break;
369       case HAL_STATE_POSTINIT:
370         nfc_hal_postinit_sm(msg);
371         break;
372       case HAL_STATE_SERVICE:
373         nfc_hal_service_sm(msg);
374         break;
375       case HAL_STATE_GRANTED:
376         nfc_hal_grant_sm(msg);
377         break;
378       /* START - VTS */
379       case HAL_STATE_POWERCYCLE:
380         nfc_hal_power_sm(msg);
381         break;
382       /* END - VTS */
383       default:
384         break;
385     }
386     OSI_mem_free((tOSI_MEM_HANDLER)msg);
387 
388     if (old_st != nfc_hal_info.state) {
389       OSI_logd("hal state is changed: %s -> %s", state_to_string(old_st),
390                state_to_string(nfc_hal_info.state));
391     }
392   }
393   OSI_logt("exit!");
394 }
395 
396 /* Print */
event_to_string(uint8_t event)397 const char* event_to_string(uint8_t event) {
398   switch (event) {
399     case HAL_EVT_OPEN:
400       return "HAL_EVT_OPEN";
401     case HAL_EVT_CORE_INIT:
402       return "HAL_EVT_CORE_INIT";
403     case HAL_EVT_WRITE:
404       return "HAL_EVT_WRITE";
405     case HAL_EVT_READ:
406       return "HAL_EVT_READ";
407     case HAL_EVT_CONTROL_GRANTED:
408       return "HAL_EVT_CONTROL_GRANTED";
409     /* START - VTS */
410     case HAL_EVT_POWER_CYCLE:
411       return "HAL_EVT_POWER_CYCLE";
412     /* END - VTS */
413     case HAL_EVT_TERMINATE:
414       return "NFC_HAL_TERMINATE";
415     case HAL_EVT_COMPLETE:
416       return "NFC_HAL_COMPLETE";
417     case HAL_EVT_COMPLETE_FAILED:
418       return "NFC_HAL_COMPLETE_FAILED";
419   }
420   return "Unknown event.";
421 }
422 
state_to_string(eHAL_STATE state)423 const char* state_to_string(eHAL_STATE state) {
424   switch (state) {
425     case HAL_STATE_INIT:
426       return "INIT";
427     case HAL_STATE_DEINIT:
428       return "DEINIT";
429     case HAL_STATE_OPEN:
430       return "OPEN";
431     case HAL_STATE_VS:
432       return "VENDOR_SPECIFIC";
433     case HAL_STATE_POSTINIT:
434       return "POST_INIT";
435     case HAL_STATE_SERVICE:
436       return "SERVICE";
437     case HAL_STATE_GRANTED:
438       return "GRANT";
439     /* START - VTS */
440     case HAL_STATE_POWERCYCLE:
441       return "POWER_CYCLE";
442       /* END - VTS */
443     case HAL_STATE_CLOSE:
444       return "CLOSE";
445   }
446   return "Unknown state.";
447 }
448