source: UsbWattMeter/trunk/ecnl_lwip/echonet_dbg.c

Last change on this file was 167, checked in by coas-nagasima, 8 years ago

MIMEにSJISを設定

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc; charset=SHIFT_JIS
File size: 13.0 KB
Line 
1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2014-2016 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 167 2016-03-08 11:37:45Z 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 <t_stdlib.h>
49#include <sil.h>
50#include <ctype.h>
51
52#include "syssvc/serial.h"
53#include "syssvc/syslog.h"
54
55#include "echonet.h"
56#include "echonet_dbg.h"
57#include "echonet_fbs.h"
58#include "echonet_task.h"
59
60#ifdef ECN_DBG_WAI_ENA
61#define _ECN_DBG_WAI_SYSLOG _ecn_dbg_wai_syslog()
62#else
63#define _ECN_DBG_WAI_SYSLOG
64#endif
65
66#if defined(ECN_DBG_PUT_ENA) || defined(ECN_CAP_PUT_ENA)
67#if defined(ECN_DBG_WAI_ENA)
68static ER _ecn_dbg_wai_syslog(void);
69/*
70 * syslog()バッファに余裕ができるまで待つ
71 */
72static ER _ecn_dbg_wai_syslog(void)
73{
74 T_SYSLOG_RLOG a_rlog;
75 ER a_ret;
76 int a_ct = 0;
77#ifndef ECN_DBG_WAI_SYSLOG_RETRY
78 #ifdef LOGTASK
79 #define ECN_DBG_WAI_SYSLOG_RETRY 10
80 #else
81 #define ECN_DBG_WAI_SYSLOG_RETRY 0
82 #endif
83#endif
84
85 for (;;) {
86 a_ret = syslog_ref_log(&a_rlog);
87 if (a_ret < 0)
88 return a_ret;
89 if (1 <= a_rlog.count) {
90 a_ct = 0;
91 } else
92#if (defined ECN_DBG_WAI_SYSLOG_RETRY) && (0 < ECN_DBG_WAI_SYSLOG_RETRY)
93 if (ECN_DBG_WAI_SYSLOG_RETRY <= ++a_ct)
94#endif
95 {
96/* a_ret = dly_tsk(100);
97 if (a_ret < 0 && a_ret != E_RLWAI)
98 return a_ret; // */
99 break;
100 }
101
102 a_ret = dly_tsk(1);
103 if (a_ret < 0 && a_ret != E_RLWAI)
104 return a_ret;
105 }
106 return 0;
107}
108#endif /* #if defined(ECN_DBG_WAI_ENA) */
109
110/*
111 * デバッグ出力
112 * 例: ECN_DBG_PUT( "task start" );
113 */
114int _ecn_dbg_dbgput(const char *fp_srcloc, const char *fp_form, ...)
115{
116 va_list v;
117 unsigned char p_buf[256];
118 ID tskid;
119#ifndef ECN_DBG_PUT_BUF_MAX
120 #define ECN_DBG_PUT_BUF_MAX 255
121#endif
122
123 get_tid(&tskid);
124
125 if (!fp_srcloc)
126 fp_srcloc = "(null)";
127
128#ifdef SEM_ECN_DBG_PUT
129 syscall(wai_sem(SEM_ECN_DBG_PUT));
130#endif
131
132 va_start(v, fp_form);
133
134#ifdef _MSC_VER
135 vsnprintf_s(p_buf, ECN_DBG_PUT_BUF_MAX, ECN_DBG_PUT_BUF_MAX, fp_form, v);
136#else
137 vsprintf(p_buf, fp_form, v);
138#endif
139
140 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
141
142#ifdef SEM_ECN_DBG_PUT
143 syscall(sig_sem(SEM_ECN_DBG_PUT));
144#endif
145
146 syslog(LOG_NOTICE, "%s[%d]: %s", fp_srcloc, (int)tskid, p_buf);
147
148 va_end(v);
149
150 return 0;
151}
152
153/* ECN_ENOD_IDの文字列変換 */
154const char *_ecn_dbg_enod2str(ECN_ENOD_ID fa_enod_id)
155{
156/* #define _ECN_FBS_DBG_ENOD2STR_BUF_MAX_BIT (4)
157/* */
158#ifdef _ECN_FBS_DBG_ENOD2STR_BUF_MAX_BIT
159 static volatile uint8_t a_idx_vol = 0;
160 static char a_buf[1 << _ECN_FBS_DBG_ENOD2STR_BUF_MAX_BIT][sizeof("ENOD_REMOTE_ID()")+5];
161 uint8_t a_idx;
162#endif
163
164 if (fa_enod_id == ENOD_NOT_MATCH_ID)
165 return "ENOD_NOT_MATCH_ID";
166 if (fa_enod_id == ENOD_MULTICAST_ID)
167 return "ENOD_MULTICAST_ID";
168 if (fa_enod_id == ENOD_LOCAL_ID)
169 return "ENOD_LOCAL_ID";
170 if (fa_enod_id == ENOD_API_ID)
171 return "ENOD_API_ID";
172 if (fa_enod_id == ENOD_REMOTE_ID)
173 return "ENOD_REMOTE_ID(0)";
174 if (fa_enod_id == ((ENOD_REMOTE_ID) + 1))
175 return "ENOD_REMOTE_ID(1)";
176 if (fa_enod_id == ((ENOD_REMOTE_ID) + 2))
177 return "ENOD_REMOTE_ID(2)";
178 if (fa_enod_id == ((ENOD_REMOTE_ID) + 3))
179 return "ENOD_REMOTE_ID(3)";
180 if (fa_enod_id == ((ENOD_REMOTE_ID) + 4))
181 return "ENOD_REMOTE_ID(4)";
182 if (fa_enod_id == ((ENOD_REMOTE_ID) + 5))
183 return "ENOD_REMOTE_ID(5)";
184#ifdef _ECN_FBS_DBG_ENOD2STR_BUF_MAX_BIT
185 if (ENOD_REMOTE_ID <= fa_enod_id) {
186 /* return "ENOD_REMOTE_ID"; */
187 a_idx = (++a_idx_vol) & ((1 << _ECN_FBS_DBG_ENOD2STR_BUF_MAX_BIT) - 1);
188#ifdef _MSC_VER
189 sprintf_s(a_buf[a_idx], sizeof(*a_buf), "ENOD_REMOTE_ID(%d)", fa_enod_id - ENOD_REMOTE_ID);
190#else
191 sprintf(a_buf[a_idx], "ENOD_REMOTE_ID(%d)", fa_enod_id - ENOD_REMOTE_ID);
192#endif
193 return a_buf[a_idx];
194 }
195#endif
196
197 return "?";
198}
199
200/*
201 * バイナリダンプ出力
202 */
203void _ecn_dbg_bindmp(const T_ECN_FST_BLK *buffer, size_t len)
204{
205 /* static領域のバッファを切り替える個数(2^n) */
206 #define _ECN_FBS_DBG_BINDMP_BUF_MAX_BIT (4)
207/* */
208#ifdef SEM_ECN_DBG_BINDMP
209 #ifdef _ECN_FBS_DBG_BINDMP_BUF_MAX_BIT
210 #undef _ECN_FBS_DBG_BINDMP_BUF_MAX_BIT
211 /* セマフォ(SEM_ECN_DBG_BINDMP)が定義されている場合、バッファ切り替えは不要なのでundef */
212 #endif
213#endif
214#ifndef _ECN_FBS_DBG_BINDMP_BUFLEN
215 /* バッファサイズ(bindmp中の1行が収まるサイズ) */
216 #define _ECN_FBS_DBG_BINDMP_BUFLEN (80)
217#endif
218#ifdef _ECN_FBS_DBG_BINDMP_BUF_MAX_BIT
219 /* static領域のバッファを切り替えるための管理用変数 */
220 static volatile uint8_t a_idx_vol = 0;
221 /* static領域のバッファ切り替え領域 */
222 static char a_buf_area[1 << _ECN_FBS_DBG_BINDMP_BUF_MAX_BIT][_ECN_FBS_DBG_BINDMP_BUFLEN];
223 uint8_t a_idx;
224 char *a_buf;
225#else
226 /* static領域のバッファ領域 */
227 static char a_buf[_ECN_FBS_DBG_BINDMP_BUFLEN];
228#endif
229 const uint8_t *p = buffer; /* 読み取りポインタ */
230 int i, a_blk, a_blk_max, a_pos = 0;
231 const T_ECN_EDT_HDR *p_req_esv;
232 const T_ECN_INTERNAL_MSG *p_im;
233
234#ifdef SEM_ECN_DBG_BINDMP
235 syscall(wai_sem(SEM_ECN_DBG_BINDMP));
236#endif
237
238 if (len != 256) {
239 a_blk_max = 1;
240 } else {
241 a_blk_max = buffer->hdr.wr ? 1 : 0;
242 if (!a_blk_max)
243 a_blk_max = 1;
244 }
245 #ifndef ECN_DBG_BINDMP_MAXLEN
246 /* bindmp出力の最大サイズ */
247 #define ECN_DBG_BINDMP_MAXLEN 1600
248 #endif
249 if (ECN_DBG_BINDMP_MAXLEN < len) {
250 len = ECN_DBG_BINDMP_MAXLEN;
251 }
252
253#ifdef _ECN_FBS_DBG_BINDMP_BUF_MAX_BIT
254 a_idx = (++a_idx_vol) & ((1 << _ECN_FBS_DBG_BINDMP_BUF_MAX_BIT) - 1);
255 a_buf = a_buf_area[a_idx];
256 /* #define a_buf (a_buf_area[a_idx]) */
257#endif
258
259 for (a_blk = 0; p && a_blk < a_blk_max; p = buffer->lnk.p_sub[a_blk++]->payload) {
260 if (0 < a_blk) {
261 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
262 syslog(LOG_NOTICE, "p_sub[%d] (0x%08X)", a_blk - 1, p);
263 }
264 memset(a_buf, 0, _ECN_FBS_DBG_BINDMP_BUFLEN);
265 for (i = 0; i < (int)len; i++) {
266 if (i % 16 == 0) {
267 if (a_buf[0]) {
268 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
269 syslog(LOG_NOTICE, "%s", a_buf);
270 }
271#ifdef _MSC_VER
272 sprintf_s(a_buf, _ECN_FBS_DBG_BINDMP_BUFLEN, "[%08X]:", i);
273#else
274 sprintf(a_buf, "[%08X]:", i);
275#endif
276 a_pos = strlen(a_buf);
277 } else {
278 a_buf[a_pos++] = (i % 16 == 8 ? '-':' ');
279 }
280#ifdef _MSC_VER
281 sprintf_s(a_buf + a_pos, _ECN_FBS_DBG_BINDMP_BUFLEN - a_pos, "%02X", p[i]);
282#else
283 sprintf(a_buf + a_pos, "%02X", p[i]);
284#endif
285 a_pos += 2;
286 }
287 if (a_buf[0]) {
288 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
289 syslog(LOG_NOTICE, "%s", a_buf);
290 }
291 if (a_blk_max == 1)
292 break;
293 }
294
295 if (len == 256) {
296 switch (buffer->hdr.type) {
297 case ECN_MSG_ECHONET:
298 p_req_esv = &((T_EDATA *)buffer)->hdr;
299 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
300 syslog(LOG_NOTICE, " sender: %d %s, target: %d %s",
301 buffer->hdr.sender.id, _ecn_dbg_enod2str(buffer->hdr.sender.id),
302 buffer->hdr.target.id, _ecn_dbg_enod2str(buffer->hdr.target.id));
303 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
304 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);
305 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
306 syslog(LOG_NOTICE, " edata: 0x%06X 0x%06X 0x%02X 0x%02X (%s)",
307 p_req_esv->edata.seoj.eojx1 << 16 | p_req_esv->edata.seoj.eojx2 << 8 | p_req_esv->edata.seoj.eojx3,
308 p_req_esv->edata.deoj.eojx1 << 16 | p_req_esv->edata.deoj.eojx2 << 8 | p_req_esv->edata.deoj.eojx3,
309 p_req_esv->edata.esv, p_req_esv->edata.opc, _ecn_dbg_esv2str(p_req_esv->edata.esv));
310 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
311 syslog(LOG_NOTICE, " ecn_prp: 0x%02X 0x%02X", p_req_esv->ecn_prp.epc, p_req_esv->ecn_prp.pdc);
312 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
313 syslog(LOG_NOTICE, " cur(blk/pos): wr %d, rd %d",
314 (int)buffer->hdr.wr,
315 (int)buffer->hdr.rd);
316 break;
317 case ECN_MSG_INTERNAL:
318 p_im = (const T_ECN_INTERNAL_MSG *)&buffer->payload[0];
319 syslog(LOG_NOTICE, " a_im.command: %d:%s", p_im->command,
320 (p_im->command == ECN_INM_NOTIFY_INSTANCELIST ? "ECN_INM_NOTIFY_INSTANCELIST" :
321 (p_im->command == ECN_INM_GET_DEVICE_LIST_REQ ? "ECN_INM_GET_DEVICE_LIST_REQ" :
322 (p_im->command == ECN_INM_GET_DEVICE_LIST_RES ? "ECN_INM_GET_DEVICE_LIST_RES" :
323 (p_im->command == ECN_INM_GET_DEVICE_INFO_REQ ? "ECN_INM_GET_DEVICE_INFO_REQ" :
324 (p_im->command == ECN_INM_GET_DEVICE_INFO_RES ? "ECN_INM_GET_DEVICE_INFO_RES" :
325 (p_im->command == ECN_UDP_MSG_GET_IPADDR_REQ ? "ECN_UDP_MSG_GET_IPADDR_REQ" :
326 (p_im->command == ECN_UDP_MSG_GET_IPADDR_RES ? "ECN_UDP_MSG_GET_IPADDR_RES" :
327 (p_im->command == ECN_UDP_MSG_GET_IPADDR_ERROR ? "ECN_UDP_MSG_GET_IPADDR_ERROR" : "?")))))))));
328 memset(a_buf, 0, _ECN_FBS_DBG_BINDMP_BUFLEN);
329 a_blk_max = buffer->hdr.wr;
330 if (0 < a_blk_max) {
331 if (64 < a_blk_max)
332 a_blk_max = 64;
333 if (_ECN_FBS_DBG_BINDMP_BUFLEN < a_blk_max)
334 a_blk_max = _ECN_FBS_DBG_BINDMP_BUFLEN;
335 for (i = offsetof(T_ECN_INTERNAL_MSG, data); i < a_blk_max; i++) {
336 a_blk = buffer->payload[i];
337 if (!isprint(a_blk) || !isascii(a_blk))
338 a_blk = '.';
339 a_buf[i - 1] = a_blk;
340 }
341 syslog(LOG_NOTICE, " a_im.data: [%s]", &a_buf[offsetof(T_ECN_INTERNAL_MSG, data) - 1]);
342 }
343 break;
344 default:
345 syslog(LOG_NOTICE, " invalid type: %d", buffer->hdr.type);
346 }
347 }
348 else if (8 <= len
349 && buffer->payload[0] == 0x10
350 && buffer->payload[1] == 0x81) {
351 p_req_esv = (const T_ECN_EDT_HDR *)&buffer->payload[0];
352 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
353 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);
354 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
355 syslog(LOG_NOTICE, " edata: 0x%06X 0x%06X 0x%02X 0x%02X (%s)",
356 p_req_esv->edata.seoj.eojx1 << 16 | p_req_esv->edata.seoj.eojx2 << 8 | p_req_esv->edata.seoj.eojx3,
357 p_req_esv->edata.deoj.eojx1 << 16 | p_req_esv->edata.deoj.eojx2 << 8 | p_req_esv->edata.deoj.eojx3,
358 p_req_esv->edata.esv, p_req_esv->edata.opc, _ecn_dbg_esv2str(p_req_esv->edata.esv));
359 _ECN_DBG_WAI_SYSLOG; /* syslog()バッファに余裕ができるまで待つ */
360 syslog(LOG_NOTICE, " ecn_prp: 0x%02X 0x%02X", p_req_esv->ecn_prp.epc, p_req_esv->ecn_prp.pdc);
361 }
362#ifdef SEM_ECN_DBG_BINDMP
363 syscall(sig_sem(SEM_ECN_DBG_BINDMP));
364#endif
365}
366
367/*
368 * ECHONET Liteサービスコード文字列変換
369 */
370const char *_ecn_dbg_esv2str(uint8_t fa_esv)
371{
372 switch (fa_esv) {
373 case ESV_SET_I_SNA: return "プロパティ値書き込み要求不可応答"; /* 0x50 */
374 case ESV_SET_C_SNA: return "プロパティ値書き込み要求不可応答"; /* 0x51 */
375 case ESV_GET_SNA: return "プロパティ値読み出し不可応答"; /* 0x52 */
376 case ESV_INF_SNA: return "プロパティ値通知不可応答"; /* 0x53 */
377 case ESV_SET_GET_SNA: return "プロパティ値書き込み・読み出し不可応答"; /* 0x5E */
378 case ESV_SET_I: return "プロパティ値書き込み要求(応答不要)"; /* 0x60 */
379 case ESV_SET_C: return "プロパティ値書き込み要求(応答要)"; /* 0x61 */
380 case ESV_GET: return "プロパティ値読み出し要求"; /* 0x62 */
381 case ESV_INF_REQ: return "プロパティ値通知要求"; /* 0x63 */
382 case ESV_SET_GET: return "プロパティ値書き込み・読み出し要求"; /* 0x6E */
383 case ESV_SET_RES: return "プロパティ値書き込み応答"; /* 0x71 */
384 case ESV_GET_RES: return "プロパティ値読み出し応答"; /* 0x72 */
385 case ESV_INF: return "プロパティ値通知"; /* 0x73 */
386 case ESV_INFC: return "プロパティ値通知(応答要)"; /* 0x74 */
387 case ESV_SET_GET_RES: return "プロパティ値書き込み・読み出し応答"; /* 0x7E */
388 case ESV_INFC_RES: return "プロパティ値通知応答"; /* 0x7A */
389 default:
390 return "(unknown)";
391 }
392}
393#endif /* #if defined(ECN_DBG_PUT_ENA) || defined(ECN_CAP_PUT_ENA) */
Note: See TracBrowser for help on using the repository browser.