1 /*
2  * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdio.h>
8 #include <ctype.h>
9 #include <string.h>
10 #include <stdbool.h>
11 #include "esp_log.h"
12 
13 #ifndef CONFIG_IDF_TARGET_LINUX
14 #include "esp_memory_utils.h"  // for esp_ptr_byte_accessible
15 #else
esp_ptr_byte_accessible(const void * ptr)16 static inline bool esp_ptr_byte_accessible(const void* ptr) {
17     (void) ptr;
18     return true;
19 }
20 #endif // CONFIG_IDF_TARGET_LINUX
21 
22 //print number of bytes per line for esp_log_buffer_char and esp_log_buffer_hex
23 #define BYTES_PER_LINE 16
24 
esp_log_buffer_hex_internal(const char * tag,const void * buffer,uint16_t buff_len,esp_log_level_t log_level)25 void esp_log_buffer_hex_internal(const char *tag, const void *buffer, uint16_t buff_len,
26                                  esp_log_level_t log_level)
27 {
28     if (buff_len == 0) {
29         return;
30     }
31     char temp_buffer[BYTES_PER_LINE + 3]; //for not-byte-accessible memory
32     char hex_buffer[3 * BYTES_PER_LINE + 1];
33     const char *ptr_line;
34     int bytes_cur_line;
35 
36     do {
37         if (buff_len > BYTES_PER_LINE) {
38             bytes_cur_line = BYTES_PER_LINE;
39         } else {
40             bytes_cur_line = buff_len;
41         }
42         if (!esp_ptr_byte_accessible(buffer)) {
43             //use memcpy to get around alignment issue
44             memcpy(temp_buffer, buffer, (bytes_cur_line + 3) / 4 * 4);
45             ptr_line = temp_buffer;
46         } else {
47             ptr_line = buffer;
48         }
49 
50         for (int i = 0; i < bytes_cur_line; i ++) {
51             sprintf(hex_buffer + 3 * i, "%02x ", ptr_line[i]);
52         }
53         ESP_LOG_LEVEL(log_level, tag, "%s", hex_buffer);
54         buffer += bytes_cur_line;
55         buff_len -= bytes_cur_line;
56     } while (buff_len);
57 }
58 
esp_log_buffer_char_internal(const char * tag,const void * buffer,uint16_t buff_len,esp_log_level_t log_level)59 void esp_log_buffer_char_internal(const char *tag, const void *buffer, uint16_t buff_len,
60                                   esp_log_level_t log_level)
61 {
62     if (buff_len == 0) {
63         return;
64     }
65     char temp_buffer[BYTES_PER_LINE + 3]; //for not-byte-accessible memory
66     char char_buffer[BYTES_PER_LINE + 1];
67     const char *ptr_line;
68     int bytes_cur_line;
69 
70     do {
71         if (buff_len > BYTES_PER_LINE) {
72             bytes_cur_line = BYTES_PER_LINE;
73         } else {
74             bytes_cur_line = buff_len;
75         }
76         if (!esp_ptr_byte_accessible(buffer)) {
77             //use memcpy to get around alignment issue
78             memcpy(temp_buffer, buffer, (bytes_cur_line + 3) / 4 * 4);
79             ptr_line = temp_buffer;
80         } else {
81             ptr_line = buffer;
82         }
83 
84         for (int i = 0; i < bytes_cur_line; i ++) {
85             sprintf(char_buffer + i, "%c", ptr_line[i]);
86         }
87         ESP_LOG_LEVEL(log_level, tag, "%s", char_buffer);
88         buffer += bytes_cur_line;
89         buff_len -= bytes_cur_line;
90     } while (buff_len);
91 }
92 
esp_log_buffer_hexdump_internal(const char * tag,const void * buffer,uint16_t buff_len,esp_log_level_t log_level)93 void esp_log_buffer_hexdump_internal(const char *tag, const void *buffer, uint16_t buff_len, esp_log_level_t log_level)
94 {
95 
96     if (buff_len == 0) {
97         return;
98     }
99     char temp_buffer[BYTES_PER_LINE + 3]; //for not-byte-accessible memory
100     const char *ptr_line;
101     //format: field[length]
102     // ADDR[10]+"   "+DATA_HEX[8*3]+" "+DATA_HEX[8*3]+"  |"+DATA_CHAR[8]+"|"
103     char hd_buffer[10 + 3 + BYTES_PER_LINE * 3 + 3 + BYTES_PER_LINE + 1 + 1];
104     char *ptr_hd;
105     int bytes_cur_line;
106 
107     do {
108         if (buff_len > BYTES_PER_LINE) {
109             bytes_cur_line = BYTES_PER_LINE;
110         } else {
111             bytes_cur_line = buff_len;
112         }
113         if (!esp_ptr_byte_accessible(buffer)) {
114             //use memcpy to get around alignment issue
115             memcpy(temp_buffer, buffer, (bytes_cur_line + 3) / 4 * 4);
116             ptr_line = temp_buffer;
117         } else {
118             ptr_line = buffer;
119         }
120         ptr_hd = hd_buffer;
121 
122         ptr_hd += sprintf(ptr_hd, "%p ", buffer);
123         for (int i = 0; i < BYTES_PER_LINE; i ++) {
124             if ((i & 7) == 0) {
125                 ptr_hd += sprintf(ptr_hd, " ");
126             }
127             if (i < bytes_cur_line) {
128                 ptr_hd += sprintf(ptr_hd, " %02x", ptr_line[i]);
129             } else {
130                 ptr_hd += sprintf(ptr_hd, "   ");
131             }
132         }
133         ptr_hd += sprintf(ptr_hd, "  |");
134         for (int i = 0; i < bytes_cur_line; i ++) {
135             if (isprint((int)ptr_line[i])) {
136                 ptr_hd += sprintf(ptr_hd, "%c", ptr_line[i]);
137             } else {
138                 ptr_hd += sprintf(ptr_hd, ".");
139             }
140         }
141         ptr_hd += sprintf(ptr_hd, "|");
142 
143         ESP_LOG_LEVEL(log_level, tag, "%s", hd_buffer);
144         buffer += bytes_cur_line;
145         buff_len -= bytes_cur_line;
146     } while (buff_len);
147 }
148