source: UsbWattMeter/trunk/ecnl_lwip/echonet_fbs.c@ 164

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

TOPPERS/ECNLサンプルアプリ「USB充電器電力計」を追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 8.5 KB
Line 
1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2014-2016 Cores Co., Ltd. Japan
5 *
6 * ã‹L’˜ìŒ ŽÒ‚́CˆÈ‰º‚Ì(1)`(4)‚ÌðŒ‚ð–ž‚½‚·ê‡‚ÉŒÀ‚èC–{ƒ\ƒtƒgƒEƒF
7 * ƒAi–{ƒ\ƒtƒgƒEƒFƒA‚ð‰ü•Ï‚µ‚½‚à‚Ì‚ðŠÜ‚ށDˆÈ‰º“¯‚¶j‚ðŽg—pE•¡»E‰ü
8 * •ÏEÄ”z•ziˆÈ‰ºC—˜—p‚ƌĂԁj‚·‚邱‚Ƃ𖳏ž‚Å‹–‘ø‚·‚éD
9 * (1) –{ƒ\ƒtƒgƒEƒFƒA‚ðƒ\[ƒXƒR[ƒh‚ÌŒ`‚Å—˜—p‚·‚éê‡‚ɂ́Cã‹L‚Ì’˜ì
10 * Œ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’肪C‚»‚Ì‚Ü‚Ü‚ÌŒ`‚Ń\[
11 * ƒXƒR[ƒh’†‚ÉŠÜ‚Ü‚ê‚Ä‚¢‚邱‚ƁD
12 * (2) –{ƒ\ƒtƒgƒEƒFƒA‚ðCƒ‰ƒCƒuƒ‰ƒŠŒ`Ž®‚ȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
13 * —p‚Å‚«‚éŒ`‚ōĔz•z‚·‚éê‡‚ɂ́CÄ”z•z‚É”º‚¤ƒhƒLƒ…
14ƒƒ“ƒgi—˜—p
15 * ŽÒƒ}ƒjƒ…
16ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L
17 * ‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
18 * (3) –{ƒ\ƒtƒgƒEƒFƒA‚ðC‹@Ší‚É‘g‚ݍž‚ނȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
19 * —p‚Å‚«‚È‚¢Œ`‚ōĔz•z‚·‚éê‡‚ɂ́CŽŸ‚Ì‚¢‚¸‚ê‚©‚ÌðŒ‚ð–ž‚½‚·‚±
20 * ‚ƁD
21 * (a) Ä”z•z‚É”º‚¤ƒhƒLƒ…
22ƒƒ“ƒgi—˜—pŽÒƒ}ƒjƒ…
23ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜
24 * ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
25 * (b) Ä”z•z‚ÌŒ`‘Ô‚ðC•Ê‚É’è‚ß‚é•û–@‚É‚æ‚Á‚āCTOPPERSƒvƒƒWƒFƒNƒg‚É
26 * •ñ‚·‚邱‚ƁD
27 * (4) –{ƒ\ƒtƒgƒEƒFƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚é‚¢‚©‚Ȃ鑹
28 * ŠQ‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð–Ɛӂ·‚邱‚ƁD
29 * ‚Ü‚½C–{ƒ\ƒtƒgƒEƒFƒA‚̃†[ƒU‚Ü‚½‚̓Gƒ“ƒhƒ†[ƒU‚©‚ç‚Ì‚¢‚©‚Ȃ闝
30 * —R‚ÉŠî‚­¿‹‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð
31 * –Ɛӂ·‚邱‚ƁD
32 *
33 * –{ƒ\ƒtƒgƒEƒFƒA‚́C–³•ÛØ‚Å’ñ‹Ÿ‚³‚ê‚Ä‚¢‚é‚à‚Ì‚Å‚ ‚éDã‹L’˜ìŒ ŽÒ‚¨
34 * ‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚́C–{ƒ\ƒtƒgƒEƒFƒA‚ÉŠÖ‚µ‚āC“Á’è‚ÌŽg—p–Ú“I
35 * ‚ɑ΂·‚é“K‡«‚àŠÜ‚߂āC‚¢‚©‚È‚é•ÛØ‚às‚í‚È‚¢D‚Ü‚½C–{ƒ\ƒtƒgƒEƒF
36 * ƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚½‚¢‚©‚Ȃ鑹ŠQ‚ÉŠÖ‚µ‚Ä‚àC‚»
37 * ‚̐ӔC‚𕉂í‚È‚¢D
38 *
39 * @(#) $Id: echonet_fbs.c 164 2016-03-07 11:33:50Z coas-nagasima $
40 */
41
42/*
43 * ŒÅ’è’·ƒoƒbƒtƒ@‰Â•Ï’·ƒXƒgƒŠ[ƒ€
44 */
45
46#include <kernel.h>
47#include <string.h>
48#include <t_syslog.h>
49#include <t_stdlib.h>
50#include "echonet_fbs.h"
51#include "arch/sys_arch.h"
52
53uint8_t lwip_heap_buf[NUM_ECHONET_MEMPOOL_BLOCK * ECHONET_MEMPOOL_BLOCK_SIZE];
54void *lwip_heap = lwip_heap_buf;
55size_t lwip_heapsz = sizeof(lwip_heap_buf);
56
57static ER get_message(T_ECN_FST_BLK **ppk_msg, int size)
58{
59 void *blk;
60
61 *ppk_msg = NULL;
62
63 if ((size <= 0) || (size > DEF_ECN_FBS_BUF_MAXLEN))
64 return E_PAR;
65
66 blk = sys_malloc(ECHONET_MEMPOOL_BLOCK_SIZE);
67 if (blk == NULL)
68 return E_NOMEM;
69
70 memset(blk, 0, ECHONET_MEMPOOL_BLOCK_SIZE);
71 *ppk_msg = (T_ECN_FST_BLK *)(blk);
72 (*ppk_msg)->hdr.length = (uint16_t)size;
73
74 return E_OK;
75}
76
77static void * get_block(T_ECN_FST_BLK *pk_msg, int pos, bool_t exp, int *size)
78{
79 void *buf;
80 void *blk;
81 int no;
82 T_ECN_SUB_BLK *mblk;
83 int temp;
84
85 if ((pos < 0) || (!exp && (pos >= pk_msg->hdr.length))) {
86 return NULL;
87 }
88
89 if (pos < DEF_ECN_FBS_FST_DAT_LEN) {
90 buf = (void *)&pk_msg->payload[pos];
91 temp = DEF_ECN_FBS_FST_DAT_LEN - pos;
92 if (temp < *size) {
93 *size = temp;
94 }
95 }
96 else {
97 pos -= DEF_ECN_FBS_FST_DAT_LEN;
98 no = pos / DEF_ECN_FBS_SUB_BUF_LEN;
99
100 mblk = pk_msg->lnk.p_sub[no];
101
102 pos -= no * DEF_ECN_FBS_SUB_BUF_LEN;
103 temp = DEF_ECN_FBS_SUB_BUF_LEN - pos;
104 if (temp < *size) {
105 *size = temp;
106 }
107 if (exp) {
108 if (mblk == NULL) {
109 blk = sys_malloc(ECHONET_MEMPOOL_BLOCK_SIZE);
110 if (blk == NULL)
111 return NULL;
112
113 mblk = (T_ECN_SUB_BLK *)(blk);
114
115 pk_msg->lnk.p_sub[no] = mblk;
116 }
117
118 temp = pos + *size + no * DEF_ECN_FBS_SUB_BUF_LEN + DEF_ECN_FBS_FST_DAT_LEN;
119 if (pk_msg->hdr.length < temp) {
120 pk_msg->hdr.length = (uint16_t)temp;
121 }
122 }
123
124 buf = &mblk->payload[pos];
125 }
126
127 return buf;
128}
129
130static ER release_message(T_ECN_FST_BLK *pk_msg)
131{
132 int i;
133
134 for (i = 0; i < 32; i++) {
135 void *blk = pk_msg->lnk.p_sub[i];
136 if (blk == NULL)
137 continue;
138
139 sys_free(blk);
140 }
141
142 sys_free(pk_msg);
143
144 return E_OK;
145}
146
147static int read_message(T_ECN_FST_BLK *pk_msg, int pos, void * dst, int size)
148{
149 int len, rest = size;
150 void * buf;
151
152 if (size <= 0)
153 return 0;
154
155 len = rest;
156 buf = get_block(pk_msg, pos, false, &len);
157 if ((buf == NULL) || (len <= 0))
158 return 0;
159
160 if((pos + len) > pk_msg->hdr.length)
161 len = pk_msg->hdr.length - pos;
162
163 for (; ; ) {
164 memcpy(dst, buf, len);
165 dst = (void *)((intptr_t)dst + len);
166 rest -= len;
167 pos += len;
168
169 if (rest <= 0)
170 break;
171
172 len = rest;
173 buf = get_block(pk_msg, pos, false, &len);
174 if ((buf == NULL) || (len <= 0))
175 return size - rest;
176 }
177
178 return size;
179}
180
181static int write_message(const void * src, T_ECN_FST_BLK *pk_msg, int pos, int size)
182{
183 int len, rest = size;
184 void * buf;
185
186 if (size <= 0)
187 return 0;
188
189 len = rest;
190 buf = get_block(pk_msg, pos, true, &len);
191 if ((buf == NULL) || (len <= 0))
192 return 0;
193
194 for (; ; ) {
195 memcpy(buf, src, len);
196 src = (void *)((intptr_t)src +len);
197 rest -= len;
198 pos += len;
199
200 if (rest <= 0)
201 break;
202
203 len = rest;
204 buf = get_block(pk_msg, pos, true, &len);
205 if ((buf == NULL) || (len <= 0))
206 return size - rest;
207 }
208
209 if (pk_msg->hdr.length < pos)
210 pk_msg->hdr.length = (uint16_t)pos;
211
212 return size;
213}
214
215static int copy_message(T_ECN_FST_BLK *pk_src, int spos, T_ECN_FST_BLK *pk_dst, int dpos, int size)
216{
217 int dlen, slen, len, rest = size;
218 void * dbuf, *sbuf;
219
220 if (size <= 0)
221 return 0;
222
223 dlen = rest;
224 dbuf = get_block(pk_dst, dpos, true, &dlen);
225 if (dbuf == NULL)
226 return 0;
227
228 slen = rest;
229 sbuf = get_block(pk_src, spos, false, &slen);
230 if (sbuf == NULL)
231 return 0;
232
233 for (; ; ) {
234 len = (dlen < slen) ? dlen : slen;
235
236 if (len == 0)
237 return size - rest;
238
239 memcpy(dbuf, sbuf, len);
240
241 dpos += len;
242 spos += len;
243 rest -= len;
244
245 if (rest <= 0)
246 break;
247
248 dlen = rest;
249 dbuf = get_block(pk_dst, dpos, true, &dlen);
250 if (dbuf == NULL)
251 return size - rest;
252
253 slen = rest;
254 sbuf = get_block(pk_src, spos, false, &slen);
255 if (sbuf == NULL)
256 return size - rest;
257 }
258
259 return size;
260}
261
262/* —̈æŠm•Û */
263ER _ecn_fbs_cre(ECN_FBS_SIZE_T fa_req_size, ECN_FBS_ID *fp_id)
264{
265 return get_message(&fp_id->ptr, fa_req_size);
266}
267
268/* —̈æ‰ð•ú */
269ER _ecn_fbs_del(ECN_FBS_ID fa_id)
270{
271 return release_message(fa_id.ptr);
272}
273
274/* •ÛŽƒf[ƒ^‚Ì—L–³ */
275bool_t _ecn_fbs_exist_data(ECN_FBS_ID fa_id)
276{
277 return fa_id.ptr->hdr.length > fa_id.ptr->hdr.wr;
278}
279
280/* •ÛŽƒf[ƒ^’·‚̎擾 */
281ECN_FBS_SSIZE_T _ecn_fbs_get_datalen(ECN_FBS_ID fa_id)
282{
283 return fa_id.ptr->hdr.length;
284}
285
286/* “Ç‚ÝŽæ‚èƒJ[ƒ\ƒ‹‚̈ʒuŽæ“¾ */
287ECN_FBS_SSIZE_T _ecn_fbs_get_rpos(ECN_FBS_ID fa_id)
288{
289 return fa_id.ptr->hdr.rd;
290}
291
292/* “Ç‚ÝŽæ‚èƒJ[ƒ\ƒ‹‚̈ʒuÝ’è */
293ER _ecn_fbs_set_rpos(ECN_FBS_ID fa_id, ECN_FBS_SSIZE_T fa_pos)
294{
295 if (fa_id.ptr->hdr.length <= (unsigned int)fa_pos) /* ˆÊ’uŽw’肪‘å‚«‚·‚¬‚é */
296 return E_PAR;
297
298 fa_id.ptr->hdr.rd = fa_pos;
299
300 return E_OK;
301}
302
303/* “Ç‚ÝŽæ‚èƒJ[ƒ\ƒ‹‚̈ʒuˆÚ“® */
304ER _ecn_fbs_seek_rpos(ECN_FBS_ID fa_id, ECN_FBS_SSIZE_T fa_seek)
305{
306 fa_id.ptr->hdr.rd += fa_seek;
307 if (fa_id.ptr->hdr.rd > fa_id.ptr->hdr.length)
308 fa_id.ptr->hdr.rd = fa_id.ptr->hdr.length;
309
310 return E_OK;
311}
312
313/* ”CˆÓŽw’èˆÊ’u‚Ì1byte“Ç‚ÝŽæ‚è */
314int _ecn_fbs_peek(ECN_FBS_ID fa_id, ECN_FBS_SSIZE_T fa_seek)
315{
316 uint8_t result = 0;
317 int ret;
318
319 ret = read_message(fa_id.ptr, fa_seek, &result, 1);
320
321 return (ret == 1) ? result : -1;
322}
323
324/* ”CˆÓŽw’èˆÊ’u‚Ì1byte‘‚«ž‚Ý */
325ER _ecn_fbs_poke(ECN_FBS_ID fa_id, ECN_FBS_SSIZE_T fa_seek, int fa_val)
326{
327 uint8_t result = fa_val;
328 int ret;
329
330 ret = write_message(&result, fa_id.ptr, fa_seek, 1);
331
332 return (ret == 1) ? E_OK : E_PAR;
333}
334
335/* ƒf[ƒ^’ljÁ */
336ER _ecn_fbs_add_data(ECN_FBS_ID fa_id, const void *fa_dat, ECN_FBS_SSIZE_T fa_len)
337{
338 if((fa_id.ptr->hdr.wr + fa_len) > fa_id.ptr->hdr.length)
339 return E_PAR;
340
341 fa_id.ptr->hdr.wr += write_message(fa_dat, fa_id.ptr, fa_id.ptr->hdr.wr, fa_len);
342 return E_OK;
343}
344
345/* ƒf[ƒ^’ljÁ(—̈æ‚ðŽ©“®“I‚ÉŠg’£‚·‚é) */
346ER _ecn_fbs_add_data_ex(ECN_FBS_ID fa_id, const void *fa_dat, ECN_FBS_SSIZE_T fa_len)
347{
348 fa_id.ptr->hdr.wr += write_message(fa_dat, fa_id.ptr, fa_id.ptr->hdr.wr, fa_len);
349 return E_OK;
350}
351
352/* ƒf[ƒ^Žæ“¾ */
353ER _ecn_fbs_get_data(ECN_FBS_ID fa_id, void *fa_buf, ECN_FBS_SSIZE_T fa_maxlen, ECN_FBS_SSIZE_T *p_len)
354{
355 int ret;
356
357 ret = read_message(fa_id.ptr, fa_id.ptr->hdr.rd, fa_buf, fa_maxlen);
358 fa_id.ptr->hdr.rd += ret;
359 *p_len = ret;
360
361 return E_OK;
362}
363
364ER ecn_fbs_enqueue(T_ECN_FBS_QUEUE *pk_queue, T_ECN_FST_BLK *pk_buf)
365{
366 loc_cpu();
367
368 *((T_ECN_FST_BLK **)pk_buf->_msg) = NULL;
369 if (pk_queue->pk_head != NULL) {
370 *((T_ECN_FST_BLK **)pk_queue->pk_last->_msg) = pk_buf;
371 }
372 else {
373 pk_queue->pk_head = pk_buf;
374 }
375 pk_queue->pk_last = pk_buf;
376
377 unl_cpu();
378
379 return E_OK;
380}
381
382ER ecn_fbs_dequeue(T_ECN_FBS_QUEUE *pk_queue, T_ECN_FST_BLK **ppk_buf)
383{
384 ER ercd;
385
386 loc_cpu();
387
388 if (pk_queue->pk_head != NULL) {
389 *ppk_buf = pk_queue->pk_head;
390 pk_queue->pk_head = *((T_ECN_FST_BLK **)(*ppk_buf)->_msg);
391 ercd = E_OK;
392 }
393 else {
394 ercd = E_TMOUT;
395 }
396
397 unl_cpu();
398
399 return ercd;
400}
Note: See TracBrowser for help on using the repository browser.