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

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

文字コードを設定

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