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