1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "debug/lwip_debug.h"
16 #include "lwip/api.h"
17 #include "lwip/netbuf.h"
18 #include "lwip/tcp.h"
19 #include "lwip/udp.h"
20 #include "lwip/priv/tcp_priv.h"
21 #include "lwip/stats.h"
22 #include "lwip/priv/memp_priv.h"
23 #include "lwip/memp.h"
24 #include "esp_log.h"
25 
26 #if CONFIG_LWIP_IPV6
27 #define DBG_LWIP_IP_SHOW(info, ip)  ESP_LWIP_LOGI("%s type=%d ip=%x", (info), (ip).type, (ip).u_addr.ip4.addr)
28 #else
29 #define DBG_LWIP_IP_SHOW(info, ip)  ESP_LWIP_LOGI("%s type=%d ip=%x", (info), IPADDR_TYPE_V4, (ip).addr)
30 #endif
31 #define DBG_LWIP_IP_PCB_SHOW(pcb) \
32         DBG_LWIP_IP_SHOW("local ip", (pcb)->local_ip);\
33         DBG_LWIP_IP_SHOW("remote ip", (pcb)->remote_ip);\
34         ESP_LWIP_LOGI("so_options=%x, tos=%d ttl=%d", (pcb)->so_options, (pcb)->tos, (pcb)->ttl)
35 
36 #define DBG_LWIP_SEG_SHOW(seg) while(seg) { ESP_LWIP_LOGI("\tseg=%p next=%p pbuf=%p flags=%x", (seg), (seg)->next, (seg)->p, (seg)->flags); (seg)=(seg)->next;}
37 #define DBG_LWIP_ITEM_NUMBER_PER_LINE 9
38 
39 #if ESP_STATS_TCP
dbg_lwip_tcp_pcb_cnt_show(struct tcp_pcb * pcb)40 static void dbg_lwip_tcp_pcb_cnt_show(struct tcp_pcb *pcb)
41 {
42     int len = 0;
43     char *buf;
44     char *p;
45     int i;
46 
47     buf = mem_malloc(512);
48     if (!buf) {
49         return;
50     }
51 
52     p = buf;
53     len += sprintf(p + len, "%11s", "tcp_retry: ");
54     for (i=0; i<TCP_MAXRTX; i++) {
55         len += sprintf(p + len, "%-2d=%-5d ", i+1, pcb->retry_cnt[i]);
56     }
57     ESP_LWIP_LOGI("%s", buf);
58     p = buf;
59     len = 0;
60     len += sprintf(p + len, "%11s", "tcp_rto#0:");
61     for (i=0; i<ESP_STATS_TCP_ARRAY_SIZE; i++) {
62         if ((i!=0) && (i%DBG_LWIP_ITEM_NUMBER_PER_LINE==0)) {
63             ESP_LWIP_LOGI("%s", buf);
64             len = 0;
65             p = buf;
66             len += sprintf(p + len, "%11s", "tcp_rto#1:");
67         }
68         len += sprintf(p + len, "%-2d=%-5d ", i+1, pcb->rto_cnt[i]);
69     }
70     ESP_LWIP_LOGI("%s", buf);
71 
72     free(buf);
73 }
74 #endif
75 
dbg_lwip_tcp_pcb_one_show(struct tcp_pcb * pcb)76 static void dbg_lwip_tcp_pcb_one_show(struct tcp_pcb* pcb)
77 {
78     struct tcp_seg *seg = NULL;
79 
80     if (!pcb) {
81         return;
82     }
83 
84     ESP_LWIP_LOGI("pcb=%p next=%p cb_arg=%p", pcb, pcb->next, pcb->callback_arg);
85     DBG_LWIP_IP_PCB_SHOW(pcb);
86     ESP_LWIP_LOGI("state=%x", pcb->state);
87     ESP_LWIP_LOGI("prio=%d", pcb->prio);
88     ESP_LWIP_LOGI("local_port=%d, remote_port=%d", pcb->local_port, pcb->remote_port);
89     ESP_LWIP_LOGI("flags=%x", pcb->flags);
90     ESP_LWIP_LOGI("pooltmr=%d pollinterval=%d, last_tmr=%d tmr=%d rtmer=%d", pcb->polltmr, pcb->pollinterval, pcb->last_timer, pcb->tmr, pcb->rtime);
91     ESP_LWIP_LOGI("recv_nxt=%d recv_wnd=%d recv_ann_wnd=%d recv_ann_right_edge=%d", pcb->rcv_nxt, pcb->rcv_wnd, pcb->rcv_ann_wnd, pcb->rcv_ann_right_edge);
92     ESP_LWIP_LOGI("mss=%d", pcb->mss);
93     ESP_LWIP_LOGI("rttest=%d rtseq=%d sa=%d sv=%d", pcb->rttest, pcb->rtseq, pcb->sa, pcb->sv);
94     ESP_LWIP_LOGI("rto=%d nrtx=%d", pcb->rto, pcb->nrtx);
95     ESP_LWIP_LOGI("dupacks=%d lastack=%d", pcb->dupacks, pcb->lastack);
96 #if ESP_PER_SOC_TCP_WND
97     ESP_LWIP_LOGI("per_soc_window=%d per_soc_snd_buf=%d", pcb->per_soc_tcp_wnd, pcb->per_soc_tcp_snd_buf);
98 #endif
99     ESP_LWIP_LOGI("cwnd=%d ssthreash=%d", pcb->cwnd, pcb->ssthresh);
100     ESP_LWIP_LOGI("snd_next=%d snd_wl1=%d snd_wl2=%d", pcb->snd_nxt, pcb->snd_wl1, pcb->snd_wl2);
101     ESP_LWIP_LOGI("snd_lbb=%d snd_wnd=%d snd_wnd_max=%d", pcb->snd_lbb, pcb->snd_wnd, pcb->snd_wnd_max);
102     //ESP_LWIP_LOGI("acked=%d", pcb->acked);
103     ESP_LWIP_LOGI("snd_buf=%d snd_queuelen=%d", pcb->snd_buf, pcb->snd_queuelen);
104     ESP_LWIP_LOGI("unsent_oversize=%d", pcb->unsent_oversize);
105     ESP_LWIP_LOGI("keep_idle=%d keep_intvl=%d keep_cnt=%d", pcb->keep_idle, pcb->keep_intvl, pcb->keep_cnt);
106     ESP_LWIP_LOGI("persist_cnt=%d persist_backoff=%d", pcb->persist_cnt, pcb->persist_backoff);
107     ESP_LWIP_LOGI("keep_cnt_sent=%d", pcb->keep_cnt_sent);
108 
109     ESP_LWIP_LOGI("unsent segments:");
110     seg = pcb->unsent;
111     DBG_LWIP_SEG_SHOW(seg)
112 
113     ESP_LWIP_LOGI("unacked segments:");
114     seg = pcb->unacked;
115     DBG_LWIP_SEG_SHOW(seg);
116 
117 #if TCP_QUEUE_OOSEQ
118     ESP_LWIP_LOGI("ooseq segments:");
119     seg = pcb->ooseq;
120     DBG_LWIP_SEG_SHOW(seg);
121 #endif
122 
123     ESP_LWIP_LOGI("refused data=%p", pcb->refused_data);
124 
125 #if ESP_STATS_TCP
126     dbg_lwip_tcp_pcb_cnt_show(pcb);
127 #endif
128 }
129 
dbg_lwip_tcp_pcb_list_show(struct tcp_pcb * pcb)130 static void dbg_lwip_tcp_pcb_list_show(struct tcp_pcb* pcb)
131 {
132     while(pcb){
133         dbg_lwip_tcp_pcb_one_show(pcb);
134         pcb = pcb->next;
135     }
136 }
137 
138 extern struct tcp_pcb *tcp_bound_pcbs;
139 extern struct tcp_pcb *tcp_active_pcbs;
140 extern struct tcp_pcb *tcp_tw_pcbs;
dbg_lwip_tcp_pcb_show(void)141 void dbg_lwip_tcp_pcb_show(void)
142 {
143     ESP_LWIP_LOGI("-------------active pcbs------------");
144     dbg_lwip_tcp_pcb_list_show(tcp_active_pcbs);
145     ESP_LWIP_LOGI("-------------bound pcbs-------------");
146     dbg_lwip_tcp_pcb_list_show(tcp_bound_pcbs);
147     ESP_LWIP_LOGI("-------------tw     pcbs------------");
148     dbg_lwip_tcp_pcb_list_show(tcp_tw_pcbs);
149 }
150 
dbg_lwip_udp_pcb_one_show(struct udp_pcb * pcb)151 void dbg_lwip_udp_pcb_one_show(struct udp_pcb *pcb)
152 {
153     ESP_LWIP_LOGI("pcb=%p next=%p", pcb, (void*)pcb->next);
154     DBG_LWIP_IP_PCB_SHOW(pcb);
155     ESP_LWIP_LOGI("flags=%x", pcb->flags);
156     ESP_LWIP_LOGI("local_port=%d remote_port=%d", pcb->local_port, pcb->remote_port);
157     ESP_LWIP_LOGI("recv cb=%p recv_arg=%p", pcb->recv, pcb->recv_arg);
158 }
159 
160 extern struct udp_pcb *udp_pcbs;
dbg_lwip_udp_pcb_show(void)161 void dbg_lwip_udp_pcb_show(void)
162 {
163     struct udp_pcb *pcb = udp_pcbs;
164 
165     while (pcb){
166         dbg_lwip_udp_pcb_one_show(pcb);
167         pcb = pcb->next;
168     }
169 }
170 
dbg_lwip_tcp_rxtx_show(void)171 void dbg_lwip_tcp_rxtx_show(void)
172 {
173     ESP_LWIP_LOGI("TBC");
174 }
175 
dbg_lwip_udp_rxtx_show(void)176 void dbg_lwip_udp_rxtx_show(void)
177 {
178     ESP_LWIP_LOGI("TBC");
179 }
180 
dbg_lwip_stats_show(void)181 void dbg_lwip_stats_show(void)
182 {
183     TCP_STATS_DISPLAY();
184     UDP_STATS_DISPLAY();
185     ICMP_STATS_DISPLAY();
186     IGMP_STATS_DISPLAY();
187     IP_STATS_DISPLAY();
188     IPFRAG_STATS_DISPLAY();
189     ETHARP_STATS_DISPLAY();
190     LINK_STATS_DISPLAY();
191     MEM_STATS_DISPLAY();
192     SYS_STATS_DISPLAY();
193     IP6_STATS_DISPLAY();
194     ICMP6_STATS_DISPLAY();
195     IP6_FRAG_STATS_DISPLAY();
196     MLD6_STATS_DISPLAY();
197     ND6_STATS_DISPLAY();
198 }
199 
200 #if (ESP_STATS_MEM == 1)
201 
202 uint32_t g_lwip_mem_cnt[MEMP_MAX][2];
203 extern const struct memp_desc * const memp_pools[MEMP_MAX];
204 
dbg_lwip_cnt_show(void)205 void dbg_lwip_cnt_show(void)
206 {
207     int i=0;
208 
209     ESP_LWIP_LOGI("-----lwip memory counter-----");
210     ESP_LWIP_LOGI("%6s %8s %8s", "index", "alloc", "free");
211     for (i=0; i<MEMP_MAX; i++){
212         ESP_LWIP_LOGI("%6u %8u %8u", i, g_lwip_mem_cnt[i][0], g_lwip_mem_cnt[i][1]);
213     }
214 }
215 
216 
217 #endif
218