• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2025 NXP.
4  *
5  * NXP Confidential. This software is owned or controlled by NXP and may only be
6  * used strictly in accordance with the applicable license terms. By expressly
7  * accepting such terms or by downloading,installing, activating and/or
8  * otherwise using the software, you are agreeing that you have read,and that
9  * you agree to comply with and are bound by, such license terms. If you do not
10  * agree to be bound by the applicable license terms, then you may not retain,
11  * install, activate or otherwise use the software.
12  *
13  */
14 
15 #include "phNxpUciHal_ext.h"
16 #include "phUwbTypes.h"
17 #include <stdio.h>
18 #include <sys/stat.h>
19 #include <time.h>
20 
21 /******************* Global variables *****************************************/
22 phNxpUciHalLog_Control_t nxpucihallog_ctrl;
23 extern phNxpUciHal_Control_t nxpucihal_ctrl;
24 extern uci_debug_log_file_t gLogFile;
25 
26 /******************************************************************************
27  * Function         phNxpUciLog_initialize
28  *
29  * Description      This function is called during the initialization of the UWB
30  *
31  * Returns          void
32  *
33  ******************************************************************************/
phNxpUciLog_initialize()34 void phNxpUciLog_initialize() {
35 
36   char UCI_Logger_log_path[100] = {0};
37 
38   if (!gLogFile.is_log_file_required) {
39     return;
40   }
41 
42   gLogFile.debuglogFile = NULL;
43   sprintf(UCI_Logger_log_path, "%suci_debug_log.txt", debug_log_path);
44   if (NULL == (gLogFile.debuglogFile = fopen(UCI_Logger_log_path, "rb+"))) {
45     NXPLOG_UCIHAL_D("unable to open log file");
46     if (NULL == (gLogFile.debuglogFile = fopen(UCI_Logger_log_path, "wb"))) {
47       NXPLOG_UCIHAL_D("unable to create log file");
48     } else {
49       long offset = 0;
50       NXPLOG_UCIHAL_D("Created debug log file set 0 as offset");
51       fwrite(&offset, sizeof(offset), 1, gLogFile.debuglogFile);
52       fwrite("\n", sizeof(char), 1, gLogFile.debuglogFile);
53     }
54   } else {
55     long offset = 0;
56     NXPLOG_UCIHAL_D("debug log file exist set offset");
57     if (1 != fread(&offset, sizeof(long), 1, gLogFile.debuglogFile)) {
58       NXPLOG_UCIHAL_D("phNxpUciPropHal_initialize: fread() failed at %d",
59                       __LINE__);
60       return;
61     }
62     if (fseek(gLogFile.debuglogFile, offset, SEEK_SET)) {
63       NXPLOG_UCIHAL_E("phNxpUciHalProp_print_log: fseek() failed at %d",
64                       __LINE__);
65       return;
66     }
67   }
68 
69   if (chmod(UCI_Logger_log_path, 0744) != 0) {
70     NXPLOG_UCIHAL_E("Can't change chmod log");
71   }
72 }
73 
74 /******************************************************************************
75  * Function         phNxpUciHalProp_fw_crash
76  *
77  * Description      FW crash dump log function
78  *
79  * Returns          None
80  *
81  ******************************************************************************/
phNxpUciHalProp_fw_crash()82 static void phNxpUciHalProp_fw_crash() {
83   NXPLOG_UCIHAL_D("[%s]", __func__);
84   tHAL_UWB_STATUS status;
85   // Debug get error log command: GID = UCI_GID_PROPRIETARY
86   // OID = EXT_UCI_MSG_DBG_GET_ERROR_LOG
87   std::vector<uint8_t> payload = {0x2E, 0x02, 0x00, 0x00};
88   phNxpUciHal_rx_handler_add(UCI_MT_RSP, UCI_GID_PROPRIETARY,
89                              EXT_UCI_MSG_DBG_GET_ERROR_LOG, true,
90                              phNxpUciHal_dump_log);
91   status = phNxpUciHal_send_ext_cmd(payload.size(), payload.data());
92 
93   if (status != HAL_UWB_STATUS_OK) {
94     NXPLOG_UCIHAL_E("Failed to send firmware crash command");
95     return;
96   }
97 
98   /* Send FW crash NTF to upper layer for triggering MW recovery */
99   phNxpUciHal_send_dev_error_status_ntf();
100 
101   NXPLOG_UCIHAL_D("[%s] Firmware crash handling completed", __func__);
102 }
103 
104 /******************************************************************************
105  * Function         phNxpUciHalProp_trigger_fw_crash_log_dump
106  *
107  * Description      dump FW crash log when fw is crashed
108  *
109  *
110  ******************************************************************************/
phNxpUciHalProp_trigger_fw_crash_log_dump()111 void phNxpUciHalProp_trigger_fw_crash_log_dump() {
112   nxpucihallog_ctrl.log_thread_handler = std::thread(&phNxpUciHalProp_fw_crash);
113   nxpucihallog_ctrl.log_thread_handler.detach();
114 }
115 
116 /******************************************************************************
117  * Function         phNxpUciHalProp_dump_log
118  *
119  * Description      This function is responsible for collecting and processing
120  *                  debug logs. It is triggered whenever debug log data needs
121  *                  to be retrieved and analyzed.
122  *
123  * Returns          void.
124  *
125  ******************************************************************************/
phNxpUciHal_dump_log(size_t data_len,const uint8_t * p_rx_data)126 bool phNxpUciHal_dump_log(size_t data_len, const uint8_t *p_rx_data) {
127   int cmd_len, len;
128   bool isSkipPacket = false;
129   const uint8_t mt = ((p_rx_data[0]) & UCI_MT_MASK) >> UCI_MT_SHIFT;
130   const uint8_t gid = p_rx_data[0] & UCI_GID_MASK;
131   const uint8_t oid = p_rx_data[1] & UCI_OID_MASK;
132   const uint8_t pbf = (p_rx_data[0] & UCI_PBF_MASK) >> UCI_PBF_SHIFT;
133 
134   uint8_t isExtendedLength =
135       (p_rx_data[EXTND_LEN_INDICATOR_OFFSET] & EXTND_LEN_INDICATOR_OFFSET_MASK);
136   cmd_len = p_rx_data[NORMAL_MODE_LENGTH_OFFSET];
137 
138   if (isExtendedLength) {
139     cmd_len = ((cmd_len << EXTENDED_MODE_LEN_SHIFT) |
140                p_rx_data[EXTENDED_MODE_LEN_OFFSET]);
141   }
142 
143   if ((gid == UCI_GID_PROPRIETARY) && (oid == EXT_UCI_MSG_DBG_GET_ERROR_LOG)) {
144     if (nxpucihal_ctrl.hal_ext_enabled == 1) {
145       char FW_crash_log_path[100] = {0};
146       sprintf(FW_crash_log_path, "%suwb_FW_crash.log", debug_log_path);
147       if (NULL ==
148           (nxpucihallog_ctrl.FwCrashLogFile = fopen(FW_crash_log_path, "wb"))) {
149         NXPLOG_UCIHAL_E("unable to open log file %s", FW_crash_log_path);
150         nxpucihal_ctrl.cmdrsp.WakeupError(UWBSTATUS_FAILED);
151       } else {
152         len = fwrite(&p_rx_data[UCI_NTF_PAYLOAD_OFFSET], 1, cmd_len,
153                      nxpucihallog_ctrl.FwCrashLogFile);
154         fflush(nxpucihallog_ctrl.FwCrashLogFile);
155         NXPLOG_UCIHAL_D("FW crash dump: %d bytes written", len);
156         fclose(nxpucihallog_ctrl.FwCrashLogFile);
157       }
158       if (!pbf) {
159         nxpucihal_ctrl.cmdrsp.Wakeup(gid, oid);
160       }
161     }
162     isSkipPacket = true;
163   }
164   return isSkipPacket;
165 }
166 
phNxpUciHalProp_print_log(uint8_t what,const uint8_t * p_data,uint16_t len)167 void phNxpUciHalProp_print_log(uint8_t what, const uint8_t *p_data,
168                                uint16_t len) {
169   char print_buffer[len * 3 + 1];
170   char dd_mm_buffer[8];
171   char UCI_Logger_log_path[100] = {0};
172   const uint8_t mt = ((p_data[0]) & UCI_MT_MASK) >> UCI_MT_SHIFT;
173   const uint8_t gid = p_data[0] & UCI_GID_MASK;
174   const uint8_t oid = p_data[1] & UCI_OID_MASK;
175   bool is_range_ntf = false;
176   uint8_t status_index = 29;
177 
178   if (!gLogFile.is_log_file_required) {
179     return;
180   }
181 
182   if (gLogFile.debuglogFile == NULL) {
183     NXPLOG_UCIHAL_E("debuglogFile file pointer is null...");
184     return;
185   }
186 
187   char yy_time[20];
188   time_t current_time = time(0);
189   tm *dd_mm_tm = localtime(&current_time);
190   strftime(yy_time, sizeof(yy_time), "%x %T", dd_mm_tm);
191   if (gLogFile.fileSize < 100000) {
192     if (!nxpucihal_ctrl.uwb_device_initialized) {
193       // Check file size
194       if (ftell(gLogFile.debuglogFile) + 5 + strlen(yy_time) +
195               strlen(NXPLOG_ITEM_UCIR) + 4 >
196           gLogFile.fileSize) {
197         if (fseek(gLogFile.debuglogFile, 9L, SEEK_SET)) {
198           NXPLOG_UCIHAL_E("phNxpUciHalProp_print_log: fseek() failed at %d",
199                           __LINE__);
200           return;
201         }
202         if (ftell(gLogFile.debuglogFile) > gLogFile.fileSize) {
203           return;
204         }
205       }
206       if (mt == UCI_MT_RSP && p_data[4] != UCI_STATUS_OK) {
207         fprintf(gLogFile.debuglogFile, "\n%s %s:", yy_time, NXPLOG_ITEM_UCIR);
208         len = fwrite(p_data, 1, len, gLogFile.debuglogFile);
209         fwrite("\n", 1, 1, gLogFile.debuglogFile);
210         gLogFile.init_sequence_started = false;
211       }
212       if (!gLogFile.init_sequence_started) {
213         fprintf(gLogFile.debuglogFile, "\n%s INIT", yy_time);
214       }
215       gLogFile.init_sequence_started = true;
216       return;
217     }
218     gLogFile.init_sequence_started = false;
219     if (((gid != UCI_GID_SESSION_MANAGE) ||
220          (oid != UCI_MSG_SESSION_SET_APP_CONFIG)) &&
221         ((gid != UCI_GID_PROPRIETARY_0X0F) ||
222          (oid != SET_VENDOR_SET_CALIBRATION))) {
223       switch (mt) {
224       case UCI_MT_CMD:
225         len = UCI_MSG_HDR_SIZE;
226         break;
227       case UCI_MT_RSP:
228         len = UCI_RESPONSE_PAYLOAD_OFFSET;
229         break;
230       case UCI_MT_NTF:
231         // Handle range data ntf
232         if ((gid == UCI_GID_SESSION_CONTROL) &&
233             (oid == UCI_OID_RANGE_DATA_NTF)) {
234           // Sequence number - 4
235           // first 4 bytes
236           // session handle - 4
237           // status
238           if (p_data[4 + 15] == 0x00) {
239             status_index += 2;
240           } else {
241             status_index += 8;
242           }
243           is_range_ntf = true;
244         }
245         break;
246       default:
247         break;
248       }
249     }
250   }
251 
252   if ((gid == UCI_GID_PROPRIETARY && oid == EXT_UCI_MSG_DBG_DATA_LOGGER_NTF) ||
253       ((gid == UCI_GID_PROPRIETARY_0X0F) &&
254        (oid == EXT_UCI_MSG_DBG_PSDU_LOG_NTF)) ||
255       ((gid == UCI_GID_PROPRIETARY_0X0F) &&
256        (oid == EXT_UCI_MSG_DBG_CIR_LOG_NTF))) {
257     return;
258   }
259 
260   uint32_t file_size = ftell(gLogFile.debuglogFile);
261 
262   if ((file_size + (strlen(yy_time) + 1 + strlen(NXPLOG_ITEM_UCIX) + 1 + len) >=
263        gLogFile.fileSize)) {
264     int val = fseek(gLogFile.debuglogFile, 9L, SEEK_SET);
265     if (ftell(gLogFile.debuglogFile) > gLogFile.fileSize) {
266       return;
267     }
268   }
269 
270   switch (what) {
271   case 0: {
272     fprintf(gLogFile.debuglogFile, "\n%s %s:", yy_time, NXPLOG_ITEM_UCIX);
273   } break;
274   case 1: {
275     fprintf(gLogFile.debuglogFile, "\n%s %s:", yy_time, NXPLOG_ITEM_UCIR);
276   } break;
277   default:
278     return;
279     break;
280   }
281   memset(print_buffer, 0, sizeof(print_buffer));
282   int i = 0, j = 0;
283   if (is_range_ntf) {
284     fwrite(&p_data[j], 1, 9, gLogFile.debuglogFile);
285     fwrite(&p_data[status_index], 1, 1, gLogFile.debuglogFile);
286   } else {
287 
288     len = fwrite(&p_data[j], 1, len, gLogFile.debuglogFile);
289     fflush(gLogFile.debuglogFile);
290   }
291 }
292 
293 /******************************************************************************
294  * Function         phNxpUciLog_deinitialize
295  *
296  * Description      This function close files and frees up memory used by
297  *                  proprietary hal.
298  *
299  * Returns          void
300  *
301  ******************************************************************************/
phNxpUciLog_deinitialize()302 void phNxpUciLog_deinitialize() {
303   /* FW debug log dump file closed */
304   if (nxpucihallog_ctrl.FwCrashLogFile != NULL) {
305     fclose(nxpucihallog_ctrl.FwCrashLogFile);
306   }
307 
308   if (gLogFile.debuglogFile != NULL) {
309     long offset = ftell(gLogFile.debuglogFile);
310     fseek(gLogFile.debuglogFile, 0L, SEEK_SET);
311     fwrite(&offset, sizeof(long), 1, gLogFile.debuglogFile);
312     fwrite("\n", sizeof(char), 1, gLogFile.debuglogFile);
313     fclose(gLogFile.debuglogFile);
314     gLogFile.debuglogFile = NULL;
315   }
316 }
317