source: uKadecot/trunk/ecnl_ssp/echonet_dbg.c@ 108

Last change on this file since 108 was 108, checked in by coas-nagasima, 9 years ago

MIMEプロパティの変更

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-chdr; charset=SHIFT_JIS
File size: 14.5 KB
RevLine 
[101]1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2014 Cores Co., Ltd. Japan
5 *
6 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
7 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
8 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
9 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
10 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
11 * スコード中に含まれていること.
12 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
13 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
14 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
15 * の無保証規定を掲載すること.
16 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
17 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
18 * と.
19 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
20 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
21 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
22 * 報告すること.
23 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
24 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
25 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
26 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
27 * 免責すること.
28 *
29 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
30 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
31 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
32 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
33 * の責任を負わない.
34 *
35 * @(#) $Id: echonet_dbg.c 108 2015-06-11 09:15:46Z coas-nagasima $
36 */
37
38/*
39 * ECHONET Lite タスク デバッグ出力
40 */
41
42#include <kernel.h>
43#include <stdio.h>
44#include <stdlib.h>
45#include <stdarg.h>
46#include <string.h>
47#include <t_syslog.h>
48#include <sil.h>
49#include <ctype.h>
50
51#include "syssvc/serial.h"
52#include "syssvc/syslog.h"
53
54#include "echonet.h"
55#include "echonet_dbg.h"
56#include "echonet_fbs.h"
57#include "echonet_task.h"
58
59#ifdef ECN_DBG_WAI_ENA
60#define _ECN_DBG_WAI_SYSLOG _ecn_dbg_wai_syslog()
61#else
62#define _ECN_DBG_WAI_SYSLOG
63#endif
64
65#if defined(ECN_DBG_PUT_ENA) || defined(ECN_CAP_PUT_ENA)
66#if defined(ECN_DBG_WAI_ENA)
67static ER _ecn_dbg_wai_syslog(void);
68/*
69 * syslog()バッファに余裕ができるまで待つ
70 */
71static ER _ecn_dbg_wai_syslog(void)
72{
73 T_SYSLOG_RLOG a_rlog;
74 ER a_ret;
75 int a_ct = 0;
76#ifndef ECN_DBG_WAI_SYSLOG_RETRY
77 #ifdef LOGTASK
78 #define ECN_DBG_WAI_SYSLOG_RETRY 10
79 #else
80 #define ECN_DBG_WAI_SYSLOG_RETRY 0
81 #endif
82#endif
83
84 for (;;) {
85 a_ret = syslog_ref_log(&a_rlog);
86 if (a_ret < 0)
87 return a_ret;
88 if (1 <= a_rlog.count) {
89 a_ct = 0;
90 } else
91#if (defined ECN_DBG_WAI_SYSLOG_RETRY) && (0 < ECN_DBG_WAI_SYSLOG_RETRY)
92 if (ECN_DBG_WAI_SYSLOG_RETRY <= ++a_ct)
93#endif
94 {
95/* a_ret = dly_tsk(100);
96 if (a_ret < 0 && a_ret != E_RLWAI)
97 return a_ret; // */
98 break;
99 }
100
101 a_ret = dly_tsk(1);
102 if (a_ret < 0 && a_ret != E_RLWAI)
103 return a_ret;
104 }
105 return 0;
106}
107#endif /* #if defined(ECN_DBG_WAI_ENA) */
108
109/*
110 * デバッグ出力
111 * 例: ECN_DBG_PUT "task start" ECN_DBG_END;
112 */
113int _ecn_dbg_dbgput(const char *fp_srcloc, const char *fp_form, ...)
114{
115 va_list v;
116 char *p_buf = 0;
117 ID tskid;
118#ifdef ECN_DBG_PUT_USE_STATIC
119 #ifndef SEM_ECN_DBG_PUT
120 /* 256byteバッファ8本ローテーション */
121 static char a_buf[8][256];
122 static volatile uint_t a_buf_idx = 0;
123 uint_t a_buf_idx_a;
124 #else
125 /* セマフォを用いて、1本のバッファ上に文字列を並べて使う */
126 static char a_buf[1024];
127 static volatile uint_t a_buf_pos = 0;
128 size_t a_buf_len;
129 #define ECN_DBG_PUT_BUF_MAX a_buf_len
130 #endif /* #ifdef SEM_ECN_DBG_PUT */
131#endif /* #ifdef ECN_DBG_PUT_USE_STATIC */
132#ifndef ECN_DBG_PUT_BUF_MAX
133 #define ECN_DBG_PUT_BUF_MAX 255
134#endif
135
136 get_tid(&tskid);
137
138 if (!fp_srcloc)
139 fp_srcloc = "(null)";
140
141#ifdef SEM_ECN_DBG_PUT
142 syscall(wai_sem(SEM_ECN_DBG_PUT));
143#endif
144
145#ifdef ECN_DBG_PUT_USE_STATIC
146 #ifndef SEM_ECN_DBG_PUT
147 a_buf_idx_a = ++a_buf_idx;
148 p_buf = a_buf[a_buf_idx_a & 0x07];
149 #else
150 if (sizeof(a_buf) - a_buf_pos < 80) /* 残りが80byte未満になったら、先頭に戻る */
151 a_buf_pos = 0;
152 p_buf = a_buf + a_buf_pos;
153 a_buf_len = sizeof(a_buf) - a_buf_pos - 1;
154 if (80 * 2 <= a_buf_len) /* 80byte*2以上の余白があるうちは、末尾80byteを残す */
155 a_buf_len -= 80;
156 #endif /* #ifdef SEM_ECN_DBG_PUT */
157#else
158 p_buf = (char *)_ecn_fbs_mbx_get(255);
159 if (!p_buf) {
160 syslog(LOG_NOTICE, "%s[%d]: (+mbx fault) %s", fp_srcloc, (int)tskid, fp_form);
161 #ifdef SEM_ECN_DBG_PUT
162 syscall(sig_sem(SEM_ECN_DBG_PUT));
163 #endif /* #ifdef SEM_ECN_DBG_PUT */
164 return 1;
165 }
166#endif /* #ifdef ECN_DBG_PUT_USE_STATIC */
167
168 va_start(v, fp_form);
169
170#ifdef _MSC_VER
171 vsnprintf_s(p_buf, ECN_DBG_PUT_BUF_MAX, ECN_DBG_PUT_BUF_MAX, fp_form, v);
172#else
173 vsprintf(p_buf, fp_form, v);
174#endif
175#ifdef ECN_DBG_PUT_USE_STATIC
176 #ifdef SEM_ECN_DBG_PUT
177 a_buf_len = strlen(p_buf) + 1;
178 /* 残りが80byte未満になったら */
179 if (sizeof(a_buf) - a_buf_pos - a_buf_len < 80) {
180 /* 先頭に戻る */
181 a_buf_pos = 0;
182 } else {
183 a_buf_pos += a_buf_len;
184 }
185 #endif /* #ifdef SEM_ECN_DBG_PUT */
186#endif
187
188 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
189
190#ifdef SEM_ECN_DBG_PUT
191 syscall(sig_sem(SEM_ECN_DBG_PUT));
192#endif
193
194 syslog(LOG_NOTICE, "%s[%d]: %s", fp_srcloc, (int)tskid, p_buf);
195
196 va_end(v);
197
198#ifndef ECN_DBG_PUT_USE_STATIC
199 _ecn_fbs_mbx_rel(p_buf);
200#endif
201 return 0;
202}
203
204/* ECN_ENOD_IDの文字列変換 */
205const char *_ecn_dbg_enod2str(ECN_ENOD_ID fa_enod_id)
206{
207/* #define _ECN_FBS_DBG_ENOD2STR_BUF_MAX_BIT (4)
208/* */
209#ifdef _ECN_FBS_DBG_ENOD2STR_BUF_MAX_BIT
210 static volatile uint8_t a_idx_vol = 0;
211 static char a_buf[1 << _ECN_FBS_DBG_ENOD2STR_BUF_MAX_BIT][sizeof("ENOD_REMOTE_ID()")+5];
212 uint8_t a_idx;
213#endif
214
215 if (fa_enod_id == ENOD_NOT_MATCH_ID)
216 return "ENOD_NOT_MATCH_ID";
217 if (fa_enod_id == ENOD_MULTICAST_ID)
218 return "ENOD_MULTICAST_ID";
219 if (fa_enod_id == ENOD_LOCAL_ID)
220 return "ENOD_LOCAL_ID";
221 if (fa_enod_id == ENOD_API_ID)
222 return "ENOD_API_ID";
223 if (fa_enod_id == ENOD_REMOTE_ID)
224 return "ENOD_REMOTE_ID(0)";
225 if (fa_enod_id == ((ENOD_REMOTE_ID) + 1))
226 return "ENOD_REMOTE_ID(1)";
227 if (fa_enod_id == ((ENOD_REMOTE_ID) + 2))
228 return "ENOD_REMOTE_ID(2)";
229 if (fa_enod_id == ((ENOD_REMOTE_ID) + 3))
230 return "ENOD_REMOTE_ID(3)";
231 if (fa_enod_id == ((ENOD_REMOTE_ID) + 4))
232 return "ENOD_REMOTE_ID(4)";
233 if (fa_enod_id == ((ENOD_REMOTE_ID) + 5))
234 return "ENOD_REMOTE_ID(5)";
235#ifdef _ECN_FBS_DBG_ENOD2STR_BUF_MAX_BIT
236 if (ENOD_REMOTE_ID <= fa_enod_id) {
237 /* return "ENOD_REMOTE_ID"; */
238 a_idx = (++a_idx_vol) & ((1 << _ECN_FBS_DBG_ENOD2STR_BUF_MAX_BIT) - 1);
239#ifdef _MSC_VER
240 sprintf_s(a_buf[a_idx], sizeof(*a_buf), "ENOD_REMOTE_ID(%d)", fa_enod_id - ENOD_REMOTE_ID);
241#else
242 sprintf(a_buf[a_idx], "ENOD_REMOTE_ID(%d)", fa_enod_id - ENOD_REMOTE_ID);
243#endif
244 return a_buf[a_idx];
245 }
246#endif
247
248 return "?";
249}
250
251/*
252 * バイナリダンプ出力
253 */
254void _ecn_dbg_bindmp(const uint8_t *buffer, size_t len)
255{
256 /* static領域のバッファを切り替える個数(2^n) */
257 #define _ECN_FBS_DBG_BINDMP_BUF_MAX_BIT (4)
258/* */
259#ifdef SEM_ECN_DBG_BINDMP
260 #ifdef _ECN_FBS_DBG_BINDMP_BUF_MAX_BIT
261 #undef _ECN_FBS_DBG_BINDMP_BUF_MAX_BIT
262 /* セマフォ(SEM_ECN_DBG_BINDMP)が定義されている場合、バッファ切り替えは不要なのでundef */
263 #endif
264#endif
265#ifndef _ECN_FBS_DBG_BINDMP_BUFLEN
266 /* バッファサイズ(bindmp中の1行が収まるサイズ) */
267 #define _ECN_FBS_DBG_BINDMP_BUFLEN (80)
268#endif
269#ifdef _ECN_FBS_DBG_BINDMP_BUF_MAX_BIT
270 /* static領域のバッファを切り替えるための管理用変数 */
271 static volatile uint8_t a_idx_vol = 0;
272 /* static領域のバッファ切り替え領域 */
273 static char a_buf_area[1 << _ECN_FBS_DBG_BINDMP_BUF_MAX_BIT][_ECN_FBS_DBG_BINDMP_BUFLEN];
274 uint8_t a_idx;
275 char *a_buf;
276#else
277 /* static領域のバッファ領域 */
278 static char a_buf[_ECN_FBS_DBG_BINDMP_BUFLEN];
279#endif
280 const uint8_t *p = buffer; /* 読み取りポインタ */
281 int i, a_blk, a_blk_max, a_pos = 0;
282 const T_ECN_EDT_HDR *p_req_esv;
283 const T_ECN_INTERNAL_MSG *p_im;
284
285#ifdef SEM_ECN_DBG_BINDMP
286 syscall(wai_sem(SEM_ECN_DBG_BINDMP));
287#endif
288
289 if (len != 256) {
290 a_blk_max = 1;
291 } else {
292 a_blk_max = ((T_ECN_FST_BLK *)buffer)->hdr.wr.blk
293 + (((T_ECN_FST_BLK *)buffer)->hdr.wr.pos ? 1 : 0);
294 if (!a_blk_max)
295 a_blk_max = 1;
296 }
297 #ifndef ECN_DBG_BINDMP_MAXLEN
298 /* bindmp出力の最大サイズ */
299 #define ECN_DBG_BINDMP_MAXLEN 1600
300 #endif
301 if (ECN_DBG_BINDMP_MAXLEN < len) {
302 len = ECN_DBG_BINDMP_MAXLEN;
303 }
304
305#ifdef _ECN_FBS_DBG_BINDMP_BUF_MAX_BIT
306 a_idx = (++a_idx_vol) & ((1 << _ECN_FBS_DBG_BINDMP_BUF_MAX_BIT) - 1);
307 a_buf = a_buf_area[a_idx];
308 /* #define a_buf (a_buf_area[a_idx]) */
309#endif
310
311 for (a_blk = 0; p && a_blk < a_blk_max; p = ((T_ECN_FST_BLK *)buffer)->lnk.p_sub[a_blk++]->dat) {
312 if (0 < a_blk) {
313 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
314 syslog(LOG_NOTICE, "p_sub[%d] (0x%08X)", a_blk - 1, p);
315 }
316 memset(a_buf, 0, _ECN_FBS_DBG_BINDMP_BUFLEN);
317 for (i = 0; i < (int)len; i++) {
318 if (i % 16 == 0) {
319 if (a_buf[0]) {
320 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
321 syslog(LOG_NOTICE, "%s", a_buf);
322 }
323#ifdef _MSC_VER
324 sprintf_s(a_buf, _ECN_FBS_DBG_BINDMP_BUFLEN, "[%08X]:", i);
325#else
326 sprintf(a_buf, "[%08X]:", i);
327#endif
328 a_pos = strlen(a_buf);
329 } else {
330 a_buf[a_pos++] = (i % 16 == 8 ? '-':' ');
331 }
332#ifdef _MSC_VER
333 sprintf_s(a_buf + a_pos, _ECN_FBS_DBG_BINDMP_BUFLEN - a_pos, "%02X", p[i]);
334#else
335 sprintf(a_buf + a_pos, "%02X", p[i]);
336#endif
337 a_pos += 2;
338 }
339 if (a_buf[0]) {
340 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
341 syslog(LOG_NOTICE, "%s", a_buf);
342 }
343 if (a_blk_max == 1)
344 break;
345 }
346
347 if (len == 256) {
348 switch (((const T_ECN_FST_BLK *)buffer)->hdr.type) {
349 case ECN_MSG_ECHONET:
350 p_req_esv = &((const T_ECN_FST_BLK *)buffer)->d.t_esv;
351 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
352 syslog(LOG_NOTICE, " sender: %d %s, target: %d %s",
353 ((T_ECN_FST_BLK *)buffer)->hdr.sender, _ecn_dbg_enod2str(((T_ECN_FST_BLK *)buffer)->hdr.sender),
354 ((T_ECN_FST_BLK *)buffer)->hdr.target, _ecn_dbg_enod2str(((T_ECN_FST_BLK *)buffer)->hdr.target));
355 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
356 syslog(LOG_NOTICE, " ecn_hdr: 0x%02X 0x%02X 0x%04X", p_req_esv->ecn_hdr.ehd1, p_req_esv->ecn_hdr.ehd2, p_req_esv->ecn_hdr.tid);
357 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
358 syslog(LOG_NOTICE, " edata: 0x%06X 0x%06X 0x%02X 0x%02X (%s)",
359 p_req_esv->edata.seoj.eojx1 << 16 | p_req_esv->edata.seoj.eojx2 << 8 | p_req_esv->edata.seoj.eojx3,
360 p_req_esv->edata.deoj.eojx1 << 16 | p_req_esv->edata.deoj.eojx2 << 8 | p_req_esv->edata.deoj.eojx3,
361 p_req_esv->edata.esv, p_req_esv->edata.opc, _ecn_dbg_esv2str(p_req_esv->edata.esv));
362 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
363 syslog(LOG_NOTICE, " ecn_prp: 0x%02X 0x%02X", p_req_esv->ecn_prp.epc, p_req_esv->ecn_prp.pdc);
364 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
365 syslog(LOG_NOTICE, " cur(blk/pos): wr %d/%d, rd %d/%d",
366 (int)((T_ECN_FST_BLK *)buffer)->hdr.wr.blk,
367 (int)((T_ECN_FST_BLK *)buffer)->hdr.wr.pos,
368 (int)((T_ECN_FST_BLK *)buffer)->hdr.rd.blk,
369 (int)((T_ECN_FST_BLK *)buffer)->hdr.rd.pos);
370 break;
371 case ECN_MSG_INTERNAL:
372 p_im = (const T_ECN_INTERNAL_MSG *)&((const T_ECN_FST_BLK *)buffer)->payload[0];
373 syslog(LOG_NOTICE, " a_im.command: %d:%s", p_im->command,
374 (p_im->command == ECN_INM_NOTIFY_INSTANCELIST ? "ECN_INM_NOTIFY_INSTANCELIST":
375 (p_im->command == ECN_INM_RELEASE_WAIT ? "ECN_INM_RELEASE_WAIT" : "?")));
376 memset(a_buf, 0, _ECN_FBS_DBG_BINDMP_BUFLEN);
377 a_blk_max = ((const T_ECN_FST_BLK *)buffer)->hdr.wr.blk * 64
378 + ((const T_ECN_FST_BLK *)buffer)->hdr.wr.pos;
379 if (0 < a_blk_max) {
380 if (64 < a_blk_max)
381 a_blk_max = 64;
382 if (_ECN_FBS_DBG_BINDMP_BUFLEN < a_blk_max)
383 a_blk_max = _ECN_FBS_DBG_BINDMP_BUFLEN;
384 for (i = offsetof(T_ECN_INTERNAL_MSG, data); i < a_blk_max; i++) {
385 a_blk = ((const T_ECN_FST_BLK *)buffer)->payload[i];
386 if (!isprint(a_blk) || !isascii(a_blk))
387 a_blk = '.';
388 a_buf[i - 1] = a_blk;
389 }
390 syslog(LOG_NOTICE, " a_im.data: [%s]", &a_buf[offsetof(T_ECN_INTERNAL_MSG, data) - 1]);
391 }
392 break;
393 default:
394 syslog(LOG_NOTICE, " invalid type: %d", ((const T_ECN_FST_BLK *)buffer)->hdr.type);
395 }
396 }
397 else if (8 <= len
398 && ((const T_ECN_FST_BLK *)buffer)->bin[0] == 0x10
399 && ((const T_ECN_FST_BLK *)buffer)->bin[1] == 0x81) {
400 p_req_esv = (const T_ECN_EDT_HDR *)&((const T_ECN_FST_BLK *)buffer)->bin[0];
401 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
402 syslog(LOG_NOTICE, " ecn_hdr: 0x%02X 0x%02X 0x%04X", p_req_esv->ecn_hdr.ehd1, p_req_esv->ecn_hdr.ehd2, p_req_esv->ecn_hdr.tid);
403 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
404 syslog(LOG_NOTICE, " edata: 0x%06X 0x%06X 0x%02X 0x%02X (%s)",
405 p_req_esv->edata.seoj.eojx1 << 16 | p_req_esv->edata.seoj.eojx2 << 8 | p_req_esv->edata.seoj.eojx3,
406 p_req_esv->edata.deoj.eojx1 << 16 | p_req_esv->edata.deoj.eojx2 << 8 | p_req_esv->edata.deoj.eojx3,
407 p_req_esv->edata.esv, p_req_esv->edata.opc, _ecn_dbg_esv2str(p_req_esv->edata.esv));
408 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
409 syslog(LOG_NOTICE, " ecn_prp: 0x%02X 0x%02X", p_req_esv->ecn_prp.epc, p_req_esv->ecn_prp.pdc);
410 }
411#ifdef SEM_ECN_DBG_BINDMP
412 syscall(sig_sem(SEM_ECN_DBG_BINDMP));
413#endif
414}
415
416/*
417 * ECHONET Liteサービスコード文字列変換
418 */
419const char *_ecn_dbg_esv2str(uint8_t fa_esv)
420{
421 switch (fa_esv) {
422 case ESV_SET_I_SNA: return "プロパティ値書き込み要求不可応答"; /* 0x50 */
423 case ESV_SET_C_SNA: return "プロパティ値書き込み要求不可応答"; /* 0x51 */
424 case ESV_GET_SNA: return "プロパティ値読み出し不可応答"; /* 0x52 */
425 case ESV_INF_SNA: return "プロパティ値通知不可応答"; /* 0x53 */
426 case ESV_SET_GET_SNA: return "プロパティ値書き込み・読み出し不可応答"; /* 0x5E */
427 case ESV_SET_I: return "プロパティ値書き込み要求(応答不要)"; /* 0x60 */
428 case ESV_SET_C: return "プロパティ値書き込み要求(応答要)"; /* 0x61 */
429 case ESV_GET: return "プロパティ値読み出し要求"; /* 0x62 */
430 case ESV_INF_REQ: return "プロパティ値通知要求"; /* 0x63 */
431 case ESV_SET_GET: return "プロパティ値書き込み・読み出し要求"; /* 0x6E */
432 case ESV_SET_RES: return "プロパティ値書き込み応答"; /* 0x71 */
433 case ESV_GET_RES: return "プロパティ値読み出し応答"; /* 0x72 */
434 case ESV_INF: return "プロパティ値通知"; /* 0x73 */
435 case ESV_INFC: return "プロパティ値通知(応答要)"; /* 0x74 */
436 case ESV_SET_GET_RES: return "プロパティ値書き込み・読み出し応答"; /* 0x7E */
437 case ESV_INFC_RES: return "プロパティ値通知応答"; /* 0x7A */
438 default:
439 return "(unknown)";
440 }
441}
442#endif /* #if defined(ECN_DBG_PUT_ENA) || defined(ECN_CAP_PUT_ENA) */
Note: See TracBrowser for help on using the repository browser.