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

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

ファイルを追加、更新。

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