1 /*
2  ** Licensed under the Apache License, Version 2.0 (the "License");
3  ** you may not use this file except in compliance with the License.
4  ** You may obtain a copy of the License at
5  **
6  ** http://www.apache.org/licenses/LICENSE-2.0
7  **
8  ** Unless required by applicable law or agreed to in writing, software
9  ** distributed under the License is distributed on an "AS IS" BASIS,
10  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  ** See the License for the specific language governing permissions and
12  ** limitations under the License.
13  **
14  ** Copyright 2023 NXP
15  **
16  */
17 #include "phNxpTempMgr.h"
18 
19 #include <phNxpConfig.h>
20 #include <phNxpLog.h>
21 #include <phOsalNfc_Timer.h>
22 #include <unistd.h>
23 
24 #include <mutex>
25 
26 #define PH_NFC_TIMER_ID_INVALID (0xFFFF)
27 #define PH_NXP_TEMPMGR_TOTAL_DELAY (11)
28 
tempNTf_timeout_cb(uint32_t TimerId,void * pContext)29 static void tempNTf_timeout_cb(uint32_t TimerId, void* pContext) {
30   (void)TimerId;
31   NXPLOG_NCIHAL_D("phNxpTempMgr::tempNTf_timeout_cb timedout");
32   phNxpTempMgr* tMgr = (phNxpTempMgr*)pContext;
33   tMgr->Reset(false /*reset timer*/);
34 }
35 
phNxpTempMgr()36 phNxpTempMgr::phNxpTempMgr() {
37   timeout_timer_id_ = PH_NFC_TIMER_ID_INVALID;
38   is_ic_temp_ok_ = true;
39   total_delay_ms_ = PH_NXP_TEMPMGR_TOTAL_DELAY * 1000;  // 11 sec
40 }
41 
GetInstance()42 phNxpTempMgr& phNxpTempMgr::GetInstance() {
43   static phNxpTempMgr nxpTempmgr;
44   return nxpTempmgr;
45 }
46 
UpdateTempStatusLocked(bool temp_status)47 void phNxpTempMgr::UpdateTempStatusLocked(bool temp_status) {
48   std::lock_guard<std::mutex> lock(ic_temp_mutex_);
49   is_ic_temp_ok_ = temp_status;
50 }
UpdateICTempStatus(uint8_t * p_ntf,uint16_t p_len)51 void phNxpTempMgr::UpdateICTempStatus(uint8_t* p_ntf, uint16_t p_len) {
52   (void)p_len;
53   NFCSTATUS status = NFCSTATUS_FAILED;
54   bool temp_status = p_ntf[03] == 0x00 ? true : false;
55   UpdateTempStatusLocked(temp_status);
56   NXPLOG_NCIHAL_D("phNxpTempMgr: IC temp state is %d", IsICTempOk());
57   // Temperature status will be notified for only one module at a time.
58   // If temp NOK status was notified for eSE first, next temp status
59   // NTF (OK/NOK) will also be notified for the same module i.e. eSE in this
60   // case
61   if (!IsICTempOk()) {
62     if (timeout_timer_id_ == PH_NFC_TIMER_ID_INVALID)
63       timeout_timer_id_ = phOsalNfc_Timer_Create();
64     if (timeout_timer_id_ != PH_NFC_TIMER_ID_INVALID) {
65       /* Start timer */
66       status = phOsalNfc_Timer_Start(timeout_timer_id_, total_delay_ms_,
67                                      &tempNTf_timeout_cb, this);
68       if (NFCSTATUS_SUCCESS != status) {
69         NXPLOG_NCIHAL_D("tempNtf timer not started!!!");
70       }
71     } else {
72       NXPLOG_NCIHAL_E("tempNtf timer creation failed");
73     }
74   } else {
75     if (timeout_timer_id_ != PH_NFC_TIMER_ID_INVALID) {
76       /* Stop Timer */
77       status = phOsalNfc_Timer_Stop(timeout_timer_id_);
78       if (NFCSTATUS_SUCCESS != status) {
79         NXPLOG_NCIHAL_D("tempNtf timer stop ERROR!!!");
80       }
81     }
82   }
83 }
84 
Wait()85 void phNxpTempMgr::Wait() {
86   if (!IsICTempOk()) {
87     NXPLOG_NCIHAL_D("Wait for %d seconds", total_delay_ms_ / 1000);
88     uint16_t delay_per_try = 500;  // millisec
89     while (!IsICTempOk()) {
90       usleep(delay_per_try * 1000);  // 500 millisec
91     }
92   }
93 }
Reset(bool reset_timer)94 void phNxpTempMgr::Reset(bool reset_timer) {
95   NXPLOG_NCIHAL_D("phNxpTempMgr::Reset ");
96   UpdateTempStatusLocked(true /*Temp OK*/);
97   if (reset_timer) {
98     timeout_timer_id_ = PH_NFC_TIMER_ID_INVALID;
99   }
100 }
101