source: EcnlProtoTool/trunk/mrbgems/mruby-ecnl/src/echonet_fbs.c@ 270

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

mruby版ECNLプロトタイピング・ツールを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 9.9 KB
Line 
1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2014-2016 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 */
51
52/*
53 * 固定長バッファ可変長ストリーム
54 */
55
56#include <mruby.h>
57#include <string.h>
58#include "echonet_fbs.h"
59#include "echonet_task.h"
60
61ER get_message(mrb_state *mrb, T_ECN_FST_BLK **ppk_msg, int size)
62{
63 void * blk;
64
65 *ppk_msg = NULL;
66
67 if ((size <= 0) || (size > DEF_ECN_FBS_BUF_MAXLEN))
68 return E_PAR;
69
70 blk = mrb_malloc_simple(mrb, ECHONET_MEMPOOL_BLOCK_SIZE);
71 if (blk == NULL)
72 return E_NOMEM;
73
74 memset(blk, 0, ECHONET_MEMPOOL_BLOCK_SIZE);
75 *ppk_msg = (T_ECN_FST_BLK *)(blk);
76 (*ppk_msg)->hdr.length = (uint16_t)size;
77
78 return E_OK;
79}
80
81void *get_block(mrb_state *mrb, T_ECN_FST_BLK *pk_msg, int pos, bool_t exp, int *size)
82{
83 void * buf;
84 void * blk;
85 int no;
86 T_ECN_SUB_BLK *mblk;
87 int temp;
88
89 if ((pos < 0) || (!exp && (pos >= pk_msg->hdr.length))) {
90 return NULL;
91 }
92
93 if (pos < DEF_ECN_FBS_FST_DAT_LEN) {
94 buf = (void *)&pk_msg->payload[pos];
95 temp = DEF_ECN_FBS_FST_DAT_LEN - pos;
96 if (temp < *size) {
97 *size = temp;
98 }
99 }
100 else {
101 pos -= DEF_ECN_FBS_FST_DAT_LEN;
102 no = pos / DEF_ECN_FBS_SUB_BUF_LEN;
103
104 mblk = pk_msg->lnk.p_sub[no];
105
106 pos -= no * DEF_ECN_FBS_SUB_BUF_LEN;
107 temp = DEF_ECN_FBS_SUB_BUF_LEN - pos;
108 if (temp < *size) {
109 *size = temp;
110 }
111 if (exp) {
112 if (mblk == NULL) {
113 blk = mrb_malloc_simple(mrb, ECHONET_MEMPOOL_BLOCK_SIZE);
114 if (blk == NULL)
115 return NULL;
116
117 mblk = (T_ECN_SUB_BLK *)(blk);
118
119 pk_msg->lnk.p_sub[no] = mblk;
120 }
121
122 temp = pos + *size + no * DEF_ECN_FBS_SUB_BUF_LEN + DEF_ECN_FBS_FST_DAT_LEN;
123 if (pk_msg->hdr.length < temp) {
124 pk_msg->hdr.length = (uint16_t)temp;
125 }
126 }
127
128 buf = &mblk->payload[pos];
129 }
130
131 return buf;
132}
133
134ER release_message(mrb_state *mrb, T_ECN_FST_BLK *pk_msg)
135{
136 int i;
137
138 for (i = 0; i < 32; i++) {
139 void * blk = pk_msg->lnk.p_sub[i];
140 if (blk == NULL)
141 continue;
142
143 mrb_free(mrb, blk);
144 }
145
146 mrb_free(mrb, pk_msg);
147
148 return E_OK;
149}
150
151int read_message(mrb_state *mrb, T_ECN_FST_BLK *pk_msg, int pos, void * dst, int size)
152{
153 int len, rest = size;
154 void * buf;
155
156 if (size <= 0)
157 return 0;
158
159 len = rest;
160 buf = get_block(mrb, pk_msg, pos, false, &len);
161 if ((buf == NULL) || (len <= 0))
162 return 0;
163
164 if ((pos + len) > pk_msg->hdr.length)
165 len = pk_msg->hdr.length - pos;
166
167 for (; ; ) {
168 memcpy(dst, buf, len);
169 dst = (void *)((intptr_t)dst + len);
170 rest -= len;
171 pos += len;
172
173 if (rest <= 0)
174 break;
175
176 len = rest;
177 buf = get_block(mrb, pk_msg, pos, false, &len);
178 if ((buf == NULL) || (len <= 0))
179 return size - rest;
180 }
181
182 return size;
183}
184
185int write_message(mrb_state *mrb, const void * src, T_ECN_FST_BLK *pk_msg, int pos, int size)
186{
187 int len, rest = size;
188 void * buf;
189
190 if (size <= 0)
191 return 0;
192
193 len = rest;
194 buf = get_block(mrb, pk_msg, pos, true, &len);
195 if ((buf == NULL) || (len <= 0))
196 return 0;
197
198 for (; ; ) {
199 memcpy(buf, src, len);
200 src = (void *)((intptr_t)src + len);
201 rest -= len;
202 pos += len;
203
204 if (rest <= 0)
205 break;
206
207 len = rest;
208 buf = get_block(mrb, pk_msg, pos, true, &len);
209 if ((buf == NULL) || (len <= 0))
210 return size - rest;
211 }
212
213 if (pk_msg->hdr.length < pos)
214 pk_msg->hdr.length = (uint16_t)pos;
215
216 return size;
217}
218
219int copy_message(mrb_state *mrb, T_ECN_FST_BLK *pk_src, int spos, T_ECN_FST_BLK *pk_dst, int dpos, int size)
220{
221 int dlen, slen, len, rest = size;
222 void * dbuf, *sbuf;
223
224 if (size <= 0)
225 return 0;
226
227 dlen = rest;
228 dbuf = get_block(mrb, pk_dst, dpos, true, &dlen);
229 if (dbuf == NULL)
230 return 0;
231
232 slen = rest;
233 sbuf = get_block(mrb, pk_src, spos, false, &slen);
234 if (sbuf == NULL)
235 return 0;
236
237 for (; ; ) {
238 len = (dlen < slen) ? dlen : slen;
239
240 if (len == 0)
241 return size - rest;
242
243 memcpy(dbuf, sbuf, len);
244
245 dpos += len;
246 spos += len;
247 rest -= len;
248
249 if (rest <= 0)
250 break;
251
252 dlen = rest;
253 dbuf = get_block(mrb, pk_dst, dpos, true, &dlen);
254 if (dbuf == NULL)
255 return size - rest;
256
257 slen = rest;
258 sbuf = get_block(mrb, pk_src, spos, false, &slen);
259 if (sbuf == NULL)
260 return size - rest;
261 }
262
263 return size;
264}
265
266/* メモリブロック取得 ok:ポインタ NG:NULL */
267void *_ecn_fbs_mbx_get(mrb_state *mrb, ECN_FBS_SIZE_T fa_req_size)
268{
269 void *result;
270
271 if ((fa_req_size <= 0) || (fa_req_size > ECHONET_MEMPOOL_BLOCK_SIZE))
272 return NULL;
273
274 result = mrb_malloc_simple(mrb, ECHONET_MEMPOOL_BLOCK_SIZE);
275 if (result == NULL)
276 return NULL;
277
278 memset(result, 0, ECHONET_MEMPOOL_BLOCK_SIZE);
279
280 return result;
281}
282
283/* メモリブロック解放 */
284ER _ecn_fbs_mbx_rel(mrb_state *mrb, void *p)
285{
286 mrb_free(mrb, p);
287
288 return E_OK;
289}
290
291/* 領域確保 */
292ER _ecn_fbs_cre(mrb_state *mrb, ECN_FBS_SIZE_T fa_req_size, ECN_FBS_ID *fp_id)
293{
294 return get_message(mrb, &fp_id->ptr, fa_req_size);
295}
296
297/* 領域解放 */
298ER _ecn_fbs_del(mrb_state *mrb, ECN_FBS_ID fa_id)
299{
300 return release_message(mrb, fa_id.ptr);
301}
302
303/* 保持データの有無 */
304bool_t _ecn_fbs_exist_data(ECN_FBS_ID fa_id)
305{
306 return fa_id.ptr->hdr.length > fa_id.ptr->hdr.wr;
307}
308
309/* 保持データ長の取得 */
310ECN_FBS_SSIZE_T _ecn_fbs_get_datalen(ECN_FBS_ID fa_id)
311{
312 return fa_id.ptr->hdr.length;
313}
314
315/* 読み取りカーソルの位置取得 */
316ECN_FBS_SSIZE_T _ecn_fbs_get_rpos(ECN_FBS_ID fa_id)
317{
318 return fa_id.ptr->hdr.rd;
319}
320
321/* 読み取りカーソルの位置設定 */
322ER _ecn_fbs_set_rpos(ECN_FBS_ID fa_id, ECN_FBS_SSIZE_T fa_pos)
323{
324 if (fa_id.ptr->hdr.length <= (unsigned int)fa_pos) /* 位置指定が大きすぎる */
325 return E_PAR;
326
327 fa_id.ptr->hdr.rd = fa_pos;
328
329 return E_OK;
330}
331
332/* 読み取りカーソルの位置移動 */
333ER _ecn_fbs_seek_rpos(ECN_FBS_ID fa_id, ECN_FBS_SSIZE_T fa_seek)
334{
335 fa_id.ptr->hdr.rd += fa_seek;
336 if (fa_id.ptr->hdr.rd > fa_id.ptr->hdr.length)
337 fa_id.ptr->hdr.rd = fa_id.ptr->hdr.length;
338
339 return E_OK;
340}
341
342/* 任意指定位置の1byte読み取り */
343int _ecn_fbs_peek(mrb_state *mrb, ECN_FBS_ID fa_id, ECN_FBS_SSIZE_T fa_seek)
344{
345 uint8_t result = 0;
346 int ret;
347
348 ret = read_message(mrb, fa_id.ptr, fa_seek, &result, 1);
349
350 return (ret == 1) ? result : -1;
351}
352
353/* 任意指定位置の1byte書き込み */
354ER _ecn_fbs_poke(mrb_state *mrb, ECN_FBS_ID fa_id, ECN_FBS_SSIZE_T fa_seek, int fa_val)
355{
356 uint8_t result = fa_val;
357 int ret;
358
359 ret = write_message(mrb, &result, fa_id.ptr, fa_seek, 1);
360
361 return (ret == 1) ? E_OK : E_PAR;
362}
363
364/* データ追加 */
365ER _ecn_fbs_add_data(mrb_state *mrb, ECN_FBS_ID fa_id, const void *fa_dat, ECN_FBS_SSIZE_T fa_len)
366{
367 if ((fa_id.ptr->hdr.wr + fa_len) > fa_id.ptr->hdr.length)
368 return E_PAR;
369
370 fa_id.ptr->hdr.wr += write_message(mrb, fa_dat, fa_id.ptr, fa_id.ptr->hdr.wr, fa_len);
371 return E_OK;
372}
373
374/* データ追加(領域を自動的に拡張する) */
375ER _ecn_fbs_add_data_ex(mrb_state *mrb, ECN_FBS_ID fa_id, const void *fa_dat, ECN_FBS_SSIZE_T fa_len)
376{
377 fa_id.ptr->hdr.wr += write_message(mrb, fa_dat, fa_id.ptr, fa_id.ptr->hdr.wr, fa_len);
378 return E_OK;
379}
380
381/* データ取得 */
382ER _ecn_fbs_get_data(mrb_state *mrb, ECN_FBS_ID fa_id, void *fa_buf, ECN_FBS_SSIZE_T fa_maxlen, ECN_FBS_SSIZE_T *p_len)
383{
384 int ret;
385
386 ret = read_message(mrb, fa_id.ptr, fa_id.ptr->hdr.rd, fa_buf, fa_maxlen);
387 fa_id.ptr->hdr.rd += ret;
388 *p_len = ret;
389
390 return E_OK;
391}
392
393#define loc_cpu()
394#define unl_cpu()
395
396ER ecn_fbs_enqueue(T_ECN_FBS_QUEUE *pk_queue, T_ECN_FST_BLK *pk_buf)
397{
398 loc_cpu();
399
400 *((T_ECN_FST_BLK **)pk_buf->_msg) = NULL;
401 if (pk_queue->pk_head != NULL) {
402 *((T_ECN_FST_BLK **)pk_queue->pk_last->_msg) = pk_buf;
403 }
404 else {
405 pk_queue->pk_head = pk_buf;
406 }
407 pk_queue->pk_last = pk_buf;
408
409 unl_cpu();
410
411 return E_OK;
412}
413
414ER ecn_fbs_dequeue(T_ECN_FBS_QUEUE *pk_queue, T_ECN_FST_BLK **ppk_buf)
415{
416 ER ercd;
417
418 loc_cpu();
419
420 if (pk_queue->pk_head != NULL) {
421 *ppk_buf = pk_queue->pk_head;
422 pk_queue->pk_head = *((T_ECN_FST_BLK **)(*ppk_buf)->_msg);
423 ercd = E_OK;
424 }
425 else {
426 ercd = E_TMOUT;
427 }
428
429 unl_cpu();
430
431 return ercd;
432}
Note: See TracBrowser for help on using the repository browser.