source: EcnlProtoTool/trunk/ntshell/webserver/websocket_fbs.c

Last change on this file was 436, checked in by coas-nagasima, 4 years ago

ntstdio_snprintfの動作が間違っていたのを修正。
Webサーバーを更新

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