• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2023 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 "NfcHalFwLog"
20 
21 #include "hal_fwlog.h"
22 
23 #include <cutils/properties.h>
24 #include <dlfcn.h>
25 #include <errno.h>
26 #include <hardware/nfc.h>
27 #include <string.h>
28 
29 #include "android_logmsg.h"
30 #include "hal_fd.h"
31 #include "halcore.h"
32 
33 extern void DispHal(const char* title, const void* data, size_t length);
34 
handlePollingLoopData(uint8_t format,uint8_t * tlvBuffer,uint16_t data_len,uint8_t ** NewTlv)35 uint8_t handlePollingLoopData(uint8_t format, uint8_t* tlvBuffer,
36                               uint16_t data_len, uint8_t** NewTlv) {
37   uint8_t value_len = 0;
38   uint8_t flag = 0;
39 
40   uint32_t timestamp = (tlvBuffer[data_len - 4] << 24) |
41                        (tlvBuffer[data_len - 3] << 16) |
42                        (tlvBuffer[data_len - 2] << 8) | tlvBuffer[data_len - 1];
43 
44   uint32_t ts = 0;
45 
46   if ((format & 0x30) == 0x30) {
47     // ST54L: 3.95us unit
48     ts = (uint32_t)(((timestamp * 1024) / 259) + 0.5);
49   } else {
50     // ST54J/K: 4.57us unit
51     ts = (uint32_t)(((timestamp * 128) / 28) + 0.5);
52   }
53 
54   int t = tlvBuffer[0];
55 
56   switch (t) {
57     case T_fieldOn:
58     case T_fieldOff:
59       STLOG_HAL_D("%s - FieldOn/Off", __func__);
60       *NewTlv = (uint8_t*)malloc(9 * sizeof(uint8_t));
61       value_len = 0x06;
62       (*NewTlv)[0] = TYPE_REMOTE_FIELD;
63       (*NewTlv)[1] = flag;
64       (*NewTlv)[2] = value_len;
65       (*NewTlv)[3] = (ts >> 24) & 0xFF;
66       (*NewTlv)[4] = (ts >> 16) & 0xFF;
67       (*NewTlv)[5] = (ts >> 8) & 0xFF;
68       (*NewTlv)[6] = ts & 0xFF;
69       (*NewTlv)[7] = 0xFF;
70       (*NewTlv)[8] = (t == T_fieldOn) ? 0x1 : 0x0;
71       break;
72     case T_CERxError:
73     case T_CERx: {
74       STLOG_HAL_D("%s - T_CERx", __func__);
75       int tlv_size = tlvBuffer[1] - 2;
76       if (tlv_size < 9) {
77         tlv_size = 8;
78       }
79 
80       // work-around type-A short frame notification bug
81       if (hal_fd_getFwInfo()->chipHwVersion == HW_ST54J &&
82           (tlvBuffer[2] & 0xF) == 0x01 &&  // short frame
83           tlvBuffer[5] == 0x00 &&          // no error
84           tlvBuffer[6] == 0x0F             // incorrect real size
85       ) {
86         tlv_size = 9;
87       }
88 
89       value_len = tlv_size - 3;
90       *NewTlv = (uint8_t*)malloc(tlv_size * sizeof(uint8_t));
91       uint8_t gain;
92       uint8_t type;
93       int length_value = tlv_size - 8;
94       gain = (tlvBuffer[3] & 0xF0) >> 4;
95 
96       switch (tlvBuffer[2] & 0xF) {
97         case 0x1:
98           flag |= 0x01;
99           type = TYPE_A;
100           break;
101         case 0x2:
102         case 0x3:
103         case 0x4:
104         case 0x5:
105         case 0x6:
106         case 0xB:
107         case 0xD:
108           type = TYPE_A;
109           break;
110         case 0x7:
111         case 0xC:
112           type = TYPE_B;
113           break;
114         case 0x8:
115         case 0x9:
116           type = TYPE_F;
117           break;
118         case 0xA:
119           type = TYPE_V;
120           break;
121         default:
122           type = TYPE_UNKNOWN;
123           break;
124       }
125       if ((tlvBuffer[5] != 0) ||
126           ((type == TYPE_A) &&
127            (tlvBuffer[8] != 0x26 && tlvBuffer[8] != 0x52)) ||
128           ((type == TYPE_B) && (tlvBuffer[8] != 0x05) &&
129            (length_value == 0x3))) {
130         // if error flag is set, consider the frame as unknown.
131         type = TYPE_UNKNOWN;
132       }
133       (*NewTlv)[0] = type;
134       (*NewTlv)[1] = flag;
135       (*NewTlv)[2] = value_len;
136       (*NewTlv)[3] = (ts >> 24) & 0xFF;
137       (*NewTlv)[4] = (ts >> 16) & 0xFF;
138       (*NewTlv)[5] = (ts >> 8) & 0xFF;
139       (*NewTlv)[6] = ts & 0xFF;
140       (*NewTlv)[7] = gain;
141       if (tlv_size > 8) {
142         memcpy(*NewTlv + 8, tlvBuffer + 8, length_value);
143       }
144     } break;
145     default:
146       break;
147   }
148   if (value_len)
149     return value_len + 3;
150   else
151     return 0;
152 }
153 
notifyPollingLoopFrames(uint8_t * p_data,uint16_t data_len,uint8_t * bufferToSend)154 int notifyPollingLoopFrames(uint8_t* p_data, uint16_t data_len,
155                             uint8_t* bufferToSend) {
156   int current_tlv_length = 0;
157   int tlv_len = 0;
158   int ntf_len = 4;
159   uint8_t* tlvFormatted = NULL;
160   uint8_t* ObserverNtf = NULL;
161   uint8_t* PreviousObserverNtf;
162   uint8_t NCI_ANDROID_PASSIVE_OBSERVER_HEADER[4] = {0x6f, 0xc, 0x01, 0x3};
163 
164   for (int current_tlv_pos = 6;
165        current_tlv_pos + p_data[current_tlv_pos + 1] + 2 <= data_len;
166        current_tlv_pos += current_tlv_length) {
167     current_tlv_length = p_data[current_tlv_pos + 1] + 2;
168     uint8_t* tlvBuffer = p_data + current_tlv_pos;
169 
170     tlv_len = handlePollingLoopData(p_data[3], tlvBuffer, current_tlv_length,
171                                     &tlvFormatted);
172 
173     if (tlvFormatted != NULL) {
174       if (ObserverNtf == NULL) {
175         ObserverNtf = (uint8_t*)malloc(4 * sizeof(uint8_t));
176         memcpy(ObserverNtf, NCI_ANDROID_PASSIVE_OBSERVER_HEADER, 4);
177       }
178 
179       PreviousObserverNtf = ObserverNtf;
180 
181       ObserverNtf = (uint8_t*)malloc((ntf_len + tlv_len) * sizeof(uint8_t));
182       memcpy(ObserverNtf, PreviousObserverNtf, ntf_len);
183       memcpy(ObserverNtf + ntf_len, tlvFormatted, tlv_len);
184       ObserverNtf[2] = ntf_len + tlv_len - 3;
185       ntf_len += tlv_len;
186       free(tlvFormatted);
187       tlvFormatted = NULL;
188       free(PreviousObserverNtf);
189     }
190   }
191   if (ObserverNtf != nullptr) {
192     if (ntf_len <= 258) {
193       memcpy(bufferToSend, ObserverNtf, ntf_len);
194     }
195     free(ObserverNtf);
196     return ntf_len;
197   } else {
198     return 0;
199   }
200 }
201