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

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

ファイルヘッダーの更新

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