source: azure_iot_hub/trunk/ntshell/echonet/echonet_fbs.c@ 388

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

Azure IoT Hub Device C SDK を使ったサンプルの追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 10.4 KB
Line 
1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2014 Cores Co., Ltd. Japan
5 *
6 * 上記著作権者
7は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
8 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
9 * 変・再é…
10å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
11 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
12 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
13 * スコード中に含まれていること.
14 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
15 * 用できる形で再é…
16å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
17å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
18 * 者
19マニュアルなど)に,上記の著作権表示,この利用条件および下記
20 * の無保証規定を掲載すること.
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再é…
23å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
24 * と.
25 * (a) 再é…
26å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
27マニュアルなど)に,上記の著
28 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
29 * (b) 再é…
30å¸ƒã®å½¢æ…
31‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
32 * 報告すること.
33 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
34 * 害からも,上記著作権者
35およびTOPPERSプロジェクトをå…
36è²¬ã™ã‚‹ã“と.
37 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
38 * 由に基づく請求からも,上記著作権者
39およびTOPPERSプロジェクトを
40 * å…
41è²¬ã™ã‚‹ã“と.
42 *
43 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
44お
45 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
46 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
47 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
48 * の責任を負わない.
49 *
50 * @(#) $Id: echonet_fbs.c 388 2019-05-22 11:25:18Z coas-nagasima $
51 */
52
53/*
54 * 固定長バッファ可変長ストリーム
55 */
56
57#include <kernel.h>
58#include <string.h>
59#include <t_syslog.h>
60#include <t_stdlib.h>
61#include "echonet_fbs.h"
62#ifdef ECHONET_USE_MALLOC
63#include <stdlib.h>
64#endif
65
66static ER get_message(T_ECN_FST_BLK **ppk_msg, int size)
67{
68 void * blk;
69#ifndef ECHONET_USE_MALLOC
70 ER ret;
71#endif
72
73 *ppk_msg = NULL;
74
75 if ((size <= 0) || (size > DEF_ECN_FBS_BUF_MAXLEN))
76 return E_PAR;
77
78#ifndef ECHONET_USE_MALLOC
79 ret = tget_mpf(ecn_mempoolid, &blk, ECHONET_MEMPOOL_GET_TMO);
80 if (ret != E_OK)
81 return ret;
82#else
83 blk = malloc(ECHONET_MEMPOOL_BLOCK_SIZE);
84 if (blk == NULL)
85 return E_NOMEM;
86#endif
87
88 memset(blk, 0, ECHONET_MEMPOOL_BLOCK_SIZE);
89 *ppk_msg = (T_ECN_FST_BLK *)(blk);
90 (*ppk_msg)->hdr.length = (uint16_t)size;
91
92 return E_OK;
93}
94
95static void * get_block(T_ECN_FST_BLK *pk_msg, int pos, bool_t exp, int *size)
96{
97#ifndef ECHONET_USE_MALLOC
98 ER ret;
99#endif
100 void * buf;
101 void * blk;
102 int no;
103 T_ECN_SUB_BLK *mblk;
104 int temp;
105
106 if ((pos < 0) || (!exp && (pos >= pk_msg->hdr.length))) {
107 return NULL;
108 }
109
110 if (pos < DEF_ECN_FBS_FST_DAT_LEN) {
111 buf = (void *)&pk_msg->payload[pos];
112 temp = DEF_ECN_FBS_FST_DAT_LEN - pos;
113 if (temp < *size) {
114 *size = temp;
115 }
116 }
117 else {
118 pos -= DEF_ECN_FBS_FST_DAT_LEN;
119 no = pos / DEF_ECN_FBS_SUB_BUF_LEN;
120
121 mblk = pk_msg->lnk.p_sub[no];
122
123 pos -= no * DEF_ECN_FBS_SUB_BUF_LEN;
124 temp = DEF_ECN_FBS_SUB_BUF_LEN - pos;
125 if (temp < *size) {
126 *size = temp;
127 }
128 if (exp) {
129 if (mblk == NULL) {
130#ifndef ECHONET_USE_MALLOC
131 ret = get_mpf(ecn_mempoolid, &blk);
132 if (ret != E_OK)
133 return NULL;
134#else
135 blk = malloc(ECHONET_MEMPOOL_BLOCK_SIZE);
136 if (blk == NULL)
137 return NULL;
138#endif
139 mblk = (T_ECN_SUB_BLK *)(blk);
140
141 pk_msg->lnk.p_sub[no] = mblk;
142 }
143
144 temp = pos + *size + no * DEF_ECN_FBS_SUB_BUF_LEN + DEF_ECN_FBS_FST_DAT_LEN;
145 if (pk_msg->hdr.length < temp) {
146 pk_msg->hdr.length = (uint16_t)temp;
147 }
148 }
149
150 buf = &mblk->payload[pos];
151 }
152
153 return buf;
154}
155
156static ER release_message(T_ECN_FST_BLK *pk_msg)
157{
158#ifndef ECHONET_USE_MALLOC
159 ER ret;
160#endif
161 int i;
162
163 for (i = 0; i < 32; i++) {
164 void * blk = pk_msg->lnk.p_sub[i];
165 if (blk == NULL)
166 continue;
167
168#ifndef ECHONET_USE_MALLOC
169 ret = rel_mpf(ecn_mempoolid, blk);
170 if (ret != E_OK)
171 return ret;
172#else
173 free(blk);
174#endif
175 }
176
177#ifndef ECHONET_USE_MALLOC
178 return rel_mpf(ecn_mempoolid, pk_msg);
179#else
180 free(pk_msg);
181
182 return E_OK;
183#endif
184}
185
186static int read_message(T_ECN_FST_BLK *pk_msg, int pos, void * dst, int size)
187{
188 int len, rest = size;
189 void * buf;
190
191 if (size <= 0)
192 return 0;
193
194 len = rest;
195 buf = get_block(pk_msg, pos, false, &len);
196 if ((buf == NULL) || (len <= 0))
197 return 0;
198
199 if((pos + len) > pk_msg->hdr.length)
200 len = pk_msg->hdr.length - pos;
201
202 for (; ; ) {
203 memcpy(dst, buf, len);
204 dst = (void *)((intptr_t)dst + len);
205 rest -= len;
206 pos += len;
207
208 if (rest <= 0)
209 break;
210
211 len = rest;
212 buf = get_block(pk_msg, pos, false, &len);
213 if ((buf == NULL) || (len <= 0))
214 return size - rest;
215 }
216
217 return size;
218}
219
220static int write_message(const void * src, T_ECN_FST_BLK *pk_msg, int pos, int size)
221{
222 int len, rest = size;
223 void * buf;
224
225 if (size <= 0)
226 return 0;
227
228 len = rest;
229 buf = get_block(pk_msg, pos, true, &len);
230 if ((buf == NULL) || (len <= 0))
231 return 0;
232
233 for (; ; ) {
234 memcpy(buf, src, len);
235 src = (void *)((intptr_t)src +len);
236 rest -= len;
237 pos += len;
238
239 if (rest <= 0)
240 break;
241
242 len = rest;
243 buf = get_block(pk_msg, pos, true, &len);
244 if ((buf == NULL) || (len <= 0))
245 return size - rest;
246 }
247
248 if (pk_msg->hdr.length < pos)
249 pk_msg->hdr.length = (uint16_t)pos;
250
251 return size;
252}
253
254static int copy_message(T_ECN_FST_BLK *pk_src, int spos, T_ECN_FST_BLK *pk_dst, int dpos, int size)
255{
256 int dlen, slen, len, rest = size;
257 void * dbuf, *sbuf;
258
259 if (size <= 0)
260 return 0;
261
262 dlen = rest;
263 dbuf = get_block(pk_dst, dpos, true, &dlen);
264 if (dbuf == NULL)
265 return 0;
266
267 slen = rest;
268 sbuf = get_block(pk_src, spos, false, &slen);
269 if (sbuf == NULL)
270 return 0;
271
272 for (; ; ) {
273 len = (dlen < slen) ? dlen : slen;
274
275 if (len == 0)
276 return size - rest;
277
278 memcpy(dbuf, sbuf, len);
279
280 dpos += len;
281 spos += len;
282 rest -= len;
283
284 if (rest <= 0)
285 break;
286
287 dlen = rest;
288 dbuf = get_block(pk_dst, dpos, true, &dlen);
289 if (dbuf == NULL)
290 return size - rest;
291
292 slen = rest;
293 sbuf = get_block(pk_src, spos, false, &slen);
294 if (sbuf == NULL)
295 return size - rest;
296 }
297
298 return size;
299}
300
301/* メモリブロック取得 ok:ポインタ NG:NULL */
302void *_ecn_fbs_dtq_get(ECN_FBS_SIZE_T fa_req_size)
303{
304 void *result;
305#ifndef ECHONET_USE_MALLOC
306 ER ret;
307#endif
308
309 if ((fa_req_size <= 0) || (fa_req_size > ECHONET_MEMPOOL_BLOCK_SIZE))
310 return NULL;
311
312#ifndef ECHONET_USE_MALLOC
313 ret = get_mpf(ecn_mempoolid, &result);
314 if (ret != E_OK)
315 return NULL;
316#else
317 result = malloc(ECHONET_MEMPOOL_BLOCK_SIZE);
318 if (result == NULL)
319 return NULL;
320#endif
321
322 memset(result, 0, ECHONET_MEMPOOL_BLOCK_SIZE);
323
324 return result;
325}
326
327/* メモリブロック解放 */
328ER _ecn_fbs_dtq_rel(void *p)
329{
330#ifndef ECHONET_USE_MALLOC
331 return rel_mpf(ecn_mempoolid, p);
332#else
333 free(p);
334
335 return E_OK;
336#endif
337}
338
339/* 領域確保 */
340ER _ecn_fbs_cre(ECN_FBS_SIZE_T fa_req_size, ECN_FBS_ID *fp_id)
341{
342 return get_message(&fp_id->ptr, fa_req_size);
343}
344
345/* 領域解放 */
346ER _ecn_fbs_del(ECN_FBS_ID fa_id)
347{
348 return release_message(fa_id.ptr);
349}
350
351/* 保持データの有無 */
352bool_t _ecn_fbs_exist_data(ECN_FBS_ID fa_id)
353{
354 return fa_id.ptr->hdr.length > fa_id.ptr->hdr.wr;
355}
356
357/* 保持データ長の取得 */
358ECN_FBS_SSIZE_T _ecn_fbs_get_datalen(ECN_FBS_ID fa_id)
359{
360 return fa_id.ptr->hdr.length;
361}
362
363/* 読み取りカーソルの位置取得 */
364ECN_FBS_SSIZE_T _ecn_fbs_get_rpos(ECN_FBS_ID fa_id)
365{
366 return fa_id.ptr->hdr.rd;
367}
368
369/* 読み取りカーソルの位置設定 */
370ER _ecn_fbs_set_rpos(ECN_FBS_ID fa_id, ECN_FBS_SSIZE_T fa_pos)
371{
372 if (fa_id.ptr->hdr.length <= (unsigned int)fa_pos) /* 位置指定が大きすぎる */
373 return E_PAR;
374
375 fa_id.ptr->hdr.rd = fa_pos;
376
377 return E_OK;
378}
379
380/* 読み取りカーソルの位置移動 */
381ER _ecn_fbs_seek_rpos(ECN_FBS_ID fa_id, ECN_FBS_SSIZE_T fa_seek)
382{
383 fa_id.ptr->hdr.rd += fa_seek;
384 if (fa_id.ptr->hdr.rd > fa_id.ptr->hdr.length)
385 fa_id.ptr->hdr.rd = fa_id.ptr->hdr.length;
386
387 return E_OK;
388}
389
390/* 任意指定位置の1byte読み取り */
391int _ecn_fbs_peek(ECN_FBS_ID fa_id, ECN_FBS_SSIZE_T fa_seek)
392{
393 uint8_t result = 0;
394 int ret;
395
396 ret = read_message(fa_id.ptr, fa_seek, &result, 1);
397
398 return (ret == 1) ? result : -1;
399}
400
401/* 任意指定位置の1byte書き込み */
402ER _ecn_fbs_poke(ECN_FBS_ID fa_id, ECN_FBS_SSIZE_T fa_seek, int fa_val)
403{
404 uint8_t result = fa_val;
405 int ret;
406
407 ret = write_message(&result, fa_id.ptr, fa_seek, 1);
408
409 return (ret == 1) ? E_OK : E_PAR;
410}
411
412/* データ追加 */
413ER _ecn_fbs_add_data(ECN_FBS_ID fa_id, const void *fa_dat, ECN_FBS_SSIZE_T fa_len)
414{
415 if((fa_id.ptr->hdr.wr + fa_len) > fa_id.ptr->hdr.length)
416 return E_PAR;
417
418 fa_id.ptr->hdr.wr += write_message(fa_dat, fa_id.ptr, fa_id.ptr->hdr.wr, fa_len);
419 return E_OK;
420}
421
422/* データ追加(領域を自動的に拡張する) */
423ER _ecn_fbs_add_data_ex(ECN_FBS_ID fa_id, const void *fa_dat, ECN_FBS_SSIZE_T fa_len)
424{
425 fa_id.ptr->hdr.wr += write_message(fa_dat, fa_id.ptr, fa_id.ptr->hdr.wr, fa_len);
426 return E_OK;
427}
428
429/* データ取得 */
430ER _ecn_fbs_get_data(ECN_FBS_ID fa_id, void *fa_buf, ECN_FBS_SSIZE_T fa_maxlen, ECN_FBS_SSIZE_T *p_len)
431{
432 int ret;
433
434 ret = read_message(fa_id.ptr, fa_id.ptr->hdr.rd, fa_buf, fa_maxlen);
435 fa_id.ptr->hdr.rd += ret;
436 *p_len = ret;
437
438 return E_OK;
439}
440
441ER ecn_fbs_enqueue(T_ECN_FBS_QUEUE *pk_queue, T_ECN_FST_BLK *pk_buf)
442{
443 loc_cpu();
444
445 *((T_ECN_FST_BLK **)pk_buf->_msg) = NULL;
446 if (pk_queue->pk_head != NULL) {
447 *((T_ECN_FST_BLK **)pk_queue->pk_last->_msg) = pk_buf;
448 }
449 else {
450 pk_queue->pk_head = pk_buf;
451 }
452 pk_queue->pk_last = pk_buf;
453
454 unl_cpu();
455
456 return E_OK;
457}
458
459ER ecn_fbs_dequeue(T_ECN_FBS_QUEUE *pk_queue, T_ECN_FST_BLK **ppk_buf)
460{
461 ER ercd;
462
463 loc_cpu();
464
465 if (pk_queue->pk_head != NULL) {
466 *ppk_buf = pk_queue->pk_head;
467 pk_queue->pk_head = *((T_ECN_FST_BLK **)(*ppk_buf)->_msg);
468 ercd = E_OK;
469 }
470 else {
471 ercd = E_TMOUT;
472 }
473
474 unl_cpu();
475
476 return ercd;
477}
Note: See TracBrowser for help on using the repository browser.