This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088

Dependents:   MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more

libMiMic(MiMic library for mbed)は、WebService機能を提供するSDKです。 mbedでWebAPIに対応したネットワークデバイスを簡単に作ることが出来ます。

libMiMicはMiMic projectで開発しています。MiMic projectについてはこちらをご覧ください。 http://nyatla.jp/mimic/wp/

構成

libMiMicはmbedRTOS上で動作し、ユーザアプリケーションにAPIを提供します。コアAPIはC言語で記述されていますが、使用頻度の高いものについてはmbed向けのC++APIが準備されています。

/media/uploads/nyatla/libmimic-sdk.png

※libMiMicはmbedの標準イーサネットドライバをしようしていません。

標準イーサネットドライバと同時に使用することはできません。

  • MiMicIP - IPv4スタックです。レテンシとメモリ消費量を抑えたuipベースのライブラリです。
  • ARP/ICMP/UDP/TCP - 基礎的なソケットAPIを提供します。APIは独自です。
  • HTTP/1.1 Server - HTTP/1.1に対応したサーバです。マルチセッション・Chunked・持続性接続に対応しています。
  • HTTP Modules - HTTP/1.1の機能モジュールです。以下のモジュールがあります。
    • ROM file provider - ROMに格納したファイルイメージを公開します。
    • File system provider - mbedファイルシステムを公開します。
    • Onchip configuration - プログラムフラッシュを利用して設定を保存します。
    • MiMicVM processor - RPCリクエスト(MiMicVM)を処理します。
    • FileUpload - ファイルアップロードを受け取ります。
    • URL decoder - HTTPリクエストを解析します。
    • UPnP handler -UPnPメッセージを処理します。
    • WebSocket - Websocketサーバです。
  • mDNS - マルチキャストDNSサービスです。
  • UPnP - UPnP/1.0の機能を提供します。UPnP handlerと協調して動作します。(現在はデバイス探索(SSDP)・デスクリプション(Description)のみ実装してあります。)
  • DHCP/APIPA - ゼロコンフィギュレーション用のモジュールです。
  • HTTP/1.1 Client
  • mbed C++ class library - mbed向けのC++CPIです。C言語のものより簡単です。

対応機種

  • mbed(mbed LPC1768)
  • LPCXpresso1769

プログラム

Import programMiMicRemoteMCU-for-Mbed

MiMic RemoteMCU for mbed. This program provides MCU control API over REST API. It can control MCU from Javascript,PHP or any HTTP rest client directly. And, The application has self development environment.

Import programMbedFileServer

The program publishes files at local directory and SD filesystem. It is a full-fledged webServer somewhat.

サンプル

Import programMiMicSimpleHttpd

This is a simplest HTTP server made ​​of libMiMic. It will echo back a request path.

Import programUPnPBasicDevice

Simplest UPnP basic device example. This program to run UPnP basic device on the mbed.

Import programWebSocketSample

MiMicSDK Websocket module sample program.

Import programHttpClientSamlpe

A http client sample program.

Import programTcpSocketClientSamlpe

MiMicSDK Tcp client socket sample program.

Import programUdpSocketSamlpe

Udp socket sample program. This program will send back the received packet.

チュートリアル

English

libMiMic(MiMic library for mbed) is SDK which provides Webservice functions. It can be created networking device easily using mbed.

See more MiMic information, See MiMic project website. http://nyatla.jp/mimic/wp/

Structure

libMiMic run on mbed RTOS and provides networking API to user application. This library has C++ class API for the mbed, and low-level C language API.

/media/uploads/nyatla/libmimic-sdk.png

For WebService general, it can be written in a simple C + + API.

libMiMic does not have the standard Ethernet driver of mbed. It is not possible that will be used with the standard Ethernet driver.

  • MiMicIP - IPv4 protocol stack. This is based uip which is reduced memory and latency.
  • ARP / ICMP / UDP / TCP - Those are provide basic IP protocols.
  • HTTP/1.1 Server - The Http server compatible HTTP/1.1. It supports multi-session, chunked transport, persistent connection.
  • HTTP Modules - There are addon-module for HTTP server. The following modules.
    • ROM file module - Publish the file images in ROM.
    • File system module - Publish thefiles in mbed file system.
    • Onchip configuration module - To save the network settings to the program flash via REST.
    • MiMicVM module - To handle the (MiMicVM) RPC request.
    • FileUpload module - Accept a file via HTTP POST.
    • URL dedoce module - A versatility URL decoder.
    • UPnP handle module - To handle UPnP messages.
    • UPnP - This provides UPnP/1.0 device functions. It works together with UPnP handler.
    • Websocket - websocket (version13) server
  • mDNS Service - DNS-SD protocol server.
  • UPnP - This provides UPnP/1.0 device functions which works with UPnP handler. (You have been implemented (SSDP) ? description only (Description) device search now.) It is a module zero configuration for - DHCP / APIPA. mbed C + + class library - C of mbed for + + is the CPI. It is simple than that of the C language.
  • DHCP/APIPA - It support zero-cpnfigulation.
  • mbed C++ class library. Almost APIs for Web applications are available.
  • HTTP/1.1 Client

Supported target

  • mbed(mbed LPC1768)
  • LPCXpresso1769

Application

Import programMiMicRemoteMCU-for-Mbed

MiMic RemoteMCU for mbed. This program provides MCU control API over REST API. It can control MCU from Javascript,PHP or any HTTP rest client directly. And, The application has self development environment.

Import programMbedFileServer

The program publishes files at local directory and SD filesystem. It is a full-fledged webServer somewhat.

Sample

Import programMiMicSimpleHttpd

This is a simplest HTTP server made ​​of libMiMic. It will echo back a request path.

Import programUPnPBasicDevice

Simplest UPnP basic device example. This program to run UPnP basic device on the mbed.

Import programWebSocketSample

MiMicSDK Websocket module sample program.

Import programHttpClientSamlpe

A http client sample program.

Import programTcpSocketClientSamlpe

MiMicSDK Tcp client socket sample program.

Import programUdpSocketSamlpe

Udp socket sample program. This program will send back the received packet.

Tutorial

Committer:
nyatla
Date:
Fri Sep 13 06:38:16 2013 +0000
Revision:
57:bc4330dfa62f
Child:
58:03b89038b21a
update mimic core r329;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nyatla 57:bc4330dfa62f 1 /*********************************************************************************
nyatla 57:bc4330dfa62f 2 * PROJECT: MiMic
nyatla 57:bc4330dfa62f 3 * --------------------------------------------------------------------------------
nyatla 57:bc4330dfa62f 4 *
nyatla 57:bc4330dfa62f 5 * This file is part of MiMic
nyatla 57:bc4330dfa62f 6 * Copyright (C)2011 Ryo Iizuka
nyatla 57:bc4330dfa62f 7 *
nyatla 57:bc4330dfa62f 8 * MiMic is free software: you can redistribute it and/or modify
nyatla 57:bc4330dfa62f 9 * it under the terms of the GNU Lesser General Public License as published
nyatla 57:bc4330dfa62f 10 * by the Free Software Foundation, either version 3 of the License, or
nyatla 57:bc4330dfa62f 11 * (at your option) any later version.
nyatla 57:bc4330dfa62f 12 *
nyatla 57:bc4330dfa62f 13 * This program is distributed in the hope that it will be useful,
nyatla 57:bc4330dfa62f 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nyatla 57:bc4330dfa62f 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
nyatla 57:bc4330dfa62f 16 * GNU General Public License for more details.
nyatla 57:bc4330dfa62f 17 *
nyatla 57:bc4330dfa62f 18 * You should have received a copy of the GNU Lesser General Public License
nyatla 57:bc4330dfa62f 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
nyatla 57:bc4330dfa62f 20 *
nyatla 57:bc4330dfa62f 21 * For further information please contact.
nyatla 57:bc4330dfa62f 22 * http://nyatla.jp/
nyatla 57:bc4330dfa62f 23 * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
nyatla 57:bc4330dfa62f 24 *
nyatla 57:bc4330dfa62f 25 *********************************************************************************/
nyatla 57:bc4330dfa62f 26 #include "NyLPC_cModWebSocket.h"
nyatla 57:bc4330dfa62f 27 #include "NyLPC_utils.h"
nyatla 57:bc4330dfa62f 28
nyatla 57:bc4330dfa62f 29
nyatla 57:bc4330dfa62f 30
nyatla 57:bc4330dfa62f 31 #define NyLPC_TcModWebSocket_FRAME_TYPE_BIN 0x01
nyatla 57:bc4330dfa62f 32 #define NyLPC_TcModWebSocket_FRAME_TYPE_TXT 0x02
nyatla 57:bc4330dfa62f 33
nyatla 57:bc4330dfa62f 34
nyatla 57:bc4330dfa62f 35
nyatla 57:bc4330dfa62f 36 #define STRBUF_MAX 32
nyatla 57:bc4330dfa62f 37 struct TModWebSocketHeader
nyatla 57:bc4330dfa62f 38 {
nyatla 57:bc4330dfa62f 39 struct NyLPC_THttpBasicHeader super;
nyatla 57:bc4330dfa62f 40 NyLPC_TcStr_t _tstr;
nyatla 57:bc4330dfa62f 41 NyLPC_TChar _tstr_buf[STRBUF_MAX];
nyatla 57:bc4330dfa62f 42 NyLPC_TChar key[24+4];
nyatla 57:bc4330dfa62f 43 NyLPC_TInt16 version;
nyatla 57:bc4330dfa62f 44 NyLPC_TUInt8 sub_protocol_id;
nyatla 57:bc4330dfa62f 45 NyLPC_TUInt8 message_id;
nyatla 57:bc4330dfa62f 46 const NyLPC_TChar* _ref_sub_protocol;
nyatla 57:bc4330dfa62f 47 };
nyatla 57:bc4330dfa62f 48
nyatla 57:bc4330dfa62f 49
nyatla 57:bc4330dfa62f 50
nyatla 57:bc4330dfa62f 51 #define MESSAGE_ID_UNKNOWN 0x00
nyatla 57:bc4330dfa62f 52 #define MESSAGE_ID_UPGRADE 0x01
nyatla 57:bc4330dfa62f 53 #define MESSAGE_ID_SEC_WEBSOCKET_KEY 0x02
nyatla 57:bc4330dfa62f 54 #define MESSAGE_ID_ORIGIN 0x03
nyatla 57:bc4330dfa62f 55 #define MESSAGE_ID_SEC_WEBSOCKET_PROTOCL 0x04
nyatla 57:bc4330dfa62f 56 #define MESSAGE_ID_SEC_WEBSOCKET_VERSION 0x05
nyatla 57:bc4330dfa62f 57
nyatla 57:bc4330dfa62f 58 static const struct NyLPC_TTextIdTbl msg_tbl[]=
nyatla 57:bc4330dfa62f 59 {
nyatla 57:bc4330dfa62f 60 {"Upgrade",MESSAGE_ID_UPGRADE},
nyatla 57:bc4330dfa62f 61 {"Sec-WebSocket-Key",MESSAGE_ID_SEC_WEBSOCKET_KEY},
nyatla 57:bc4330dfa62f 62 {"Origin",MESSAGE_ID_ORIGIN},
nyatla 57:bc4330dfa62f 63 {"Sec-WebSocket-Protocol",MESSAGE_ID_SEC_WEBSOCKET_PROTOCL},
nyatla 57:bc4330dfa62f 64 {"Sec-WebSocket-Version",MESSAGE_ID_SEC_WEBSOCKET_VERSION},
nyatla 57:bc4330dfa62f 65 {NULL,MESSAGE_ID_UNKNOWN}
nyatla 57:bc4330dfa62f 66 };
nyatla 57:bc4330dfa62f 67
nyatla 57:bc4330dfa62f 68 static NyLPC_TBool messageHandler(NyLPC_TcHttpBasicHeaderParser_t* i_inst,const NyLPC_TChar* i_name,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out)
nyatla 57:bc4330dfa62f 69 {
nyatla 57:bc4330dfa62f 70 struct TModWebSocketHeader* out=(struct TModWebSocketHeader*)o_out;
nyatla 57:bc4330dfa62f 71 if(i_name!=NULL){
nyatla 57:bc4330dfa62f 72 out->message_id=NyLPC_TTextIdTbl_getMatchIdIgnoreCase(i_name,msg_tbl);
nyatla 57:bc4330dfa62f 73 NyLPC_cStr_clear(&(out->_tstr));
nyatla 57:bc4330dfa62f 74 }else{
nyatla 57:bc4330dfa62f 75 switch(out->message_id)
nyatla 57:bc4330dfa62f 76 {
nyatla 57:bc4330dfa62f 77 case MESSAGE_ID_UPGRADE:
nyatla 57:bc4330dfa62f 78 if(i_c!='\0'){
nyatla 57:bc4330dfa62f 79 if(!NyLPC_cStr_put(&(out->_tstr),i_c)){
nyatla 57:bc4330dfa62f 80 NyLPC_OnErrorGoto(ERROR);
nyatla 57:bc4330dfa62f 81 }
nyatla 57:bc4330dfa62f 82 }else{
nyatla 57:bc4330dfa62f 83 //websocketかチェック
nyatla 57:bc4330dfa62f 84 if(!NyLPC_cStr_isEqualIgnoreCase(&out->_tstr,"websocket")){
nyatla 57:bc4330dfa62f 85 return NyLPC_TBool_FALSE;//不一致
nyatla 57:bc4330dfa62f 86 }
nyatla 57:bc4330dfa62f 87 }
nyatla 57:bc4330dfa62f 88 break;
nyatla 57:bc4330dfa62f 89 case MESSAGE_ID_SEC_WEBSOCKET_KEY:
nyatla 57:bc4330dfa62f 90 if(i_c!='\0'){
nyatla 57:bc4330dfa62f 91 if(!NyLPC_cStr_put(&(out->_tstr),i_c)){
nyatla 57:bc4330dfa62f 92 NyLPC_OnErrorGoto(ERROR);
nyatla 57:bc4330dfa62f 93 }
nyatla 57:bc4330dfa62f 94 }else{
nyatla 57:bc4330dfa62f 95 //HASH値をコピー
nyatla 57:bc4330dfa62f 96 strcpy(out->key,NyLPC_cStr_str(&out->_tstr));
nyatla 57:bc4330dfa62f 97 }
nyatla 57:bc4330dfa62f 98 break;
nyatla 57:bc4330dfa62f 99 case MESSAGE_ID_SEC_WEBSOCKET_PROTOCL:
nyatla 57:bc4330dfa62f 100 if(i_c!='\0' && i_c!=','){
nyatla 57:bc4330dfa62f 101 if(!NyLPC_cStr_put(&(out->_tstr),i_c)){
nyatla 57:bc4330dfa62f 102 NyLPC_OnErrorGoto(ERROR);
nyatla 57:bc4330dfa62f 103 }
nyatla 57:bc4330dfa62f 104 }else{
nyatla 57:bc4330dfa62f 105 //トークン終端
nyatla 57:bc4330dfa62f 106 if(out->_ref_sub_protocol!=NULL){
nyatla 57:bc4330dfa62f 107 //サブプロトコルが指定されている場合はチェック
nyatla 57:bc4330dfa62f 108 if(NyLPC_stricmp(NyLPC_cStr_str(&out->_tstr),out->_ref_sub_protocol)==0){
nyatla 57:bc4330dfa62f 109 out->sub_protocol_id=1;//SubProtocol一致
nyatla 57:bc4330dfa62f 110 }
nyatla 57:bc4330dfa62f 111 }
nyatla 57:bc4330dfa62f 112 //','の時はリセット
nyatla 57:bc4330dfa62f 113 if(i_c!=','){
nyatla 57:bc4330dfa62f 114 NyLPC_cStr_clear(&(out->_tstr));
nyatla 57:bc4330dfa62f 115 }
nyatla 57:bc4330dfa62f 116 }
nyatla 57:bc4330dfa62f 117 break;
nyatla 57:bc4330dfa62f 118 case MESSAGE_ID_SEC_WEBSOCKET_VERSION:
nyatla 57:bc4330dfa62f 119 if(i_c!='\0'){
nyatla 57:bc4330dfa62f 120 if(!NyLPC_cStr_put(&(out->_tstr),i_c)){
nyatla 57:bc4330dfa62f 121 NyLPC_OnErrorGoto(ERROR);
nyatla 57:bc4330dfa62f 122 }
nyatla 57:bc4330dfa62f 123 }else{
nyatla 57:bc4330dfa62f 124 //VERSION
nyatla 57:bc4330dfa62f 125 out->version=atoi(NyLPC_cStr_str(&out->_tstr));
nyatla 57:bc4330dfa62f 126 if(out->version<0){
nyatla 57:bc4330dfa62f 127 NyLPC_OnErrorGoto(ERROR);
nyatla 57:bc4330dfa62f 128 }
nyatla 57:bc4330dfa62f 129 }
nyatla 57:bc4330dfa62f 130 }
nyatla 57:bc4330dfa62f 131 }
nyatla 57:bc4330dfa62f 132 return NyLPC_TBool_TRUE;
nyatla 57:bc4330dfa62f 133 ERROR:
nyatla 57:bc4330dfa62f 134 return NyLPC_TBool_FALSE;
nyatla 57:bc4330dfa62f 135 }
nyatla 57:bc4330dfa62f 136
nyatla 57:bc4330dfa62f 137
nyatla 57:bc4330dfa62f 138
nyatla 57:bc4330dfa62f 139
nyatla 57:bc4330dfa62f 140 /**
nyatla 57:bc4330dfa62f 141 * デフォルトハンドラ
nyatla 57:bc4330dfa62f 142 */
nyatla 57:bc4330dfa62f 143 static const struct NyLPC_TcHttpBasicHeaderParser_Handler handler=
nyatla 57:bc4330dfa62f 144 {
nyatla 57:bc4330dfa62f 145 messageHandler,
nyatla 57:bc4330dfa62f 146 NULL
nyatla 57:bc4330dfa62f 147 };
nyatla 57:bc4330dfa62f 148 #define NyLPC_TcModWebSocket_ST_START_PAYLOAD 0x01
nyatla 57:bc4330dfa62f 149 #define NyLPC_TcModWebSocket_ST_READ_PAYLOAD 0x02
nyatla 57:bc4330dfa62f 150 #define NyLPC_TcModWebSocket_ST_CLOSED 0x03
nyatla 57:bc4330dfa62f 151
nyatla 57:bc4330dfa62f 152
nyatla 57:bc4330dfa62f 153 /**
nyatla 57:bc4330dfa62f 154 * コンストラクタ。
nyatla 57:bc4330dfa62f 155 */
nyatla 57:bc4330dfa62f 156 void NyLPC_cModWebSocket_initialize(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_ref_root_path)
nyatla 57:bc4330dfa62f 157 {
nyatla 57:bc4330dfa62f 158 NyLPC_cModRomFiles_initialize(&i_inst->super,i_ref_root_path,NULL,0);
nyatla 57:bc4330dfa62f 159 i_inst->_frame_type=NyLPC_TcModWebSocket_FRAME_TYPE_TXT;
nyatla 57:bc4330dfa62f 160 i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED;
nyatla 57:bc4330dfa62f 161 }
nyatla 57:bc4330dfa62f 162 void NyLPC_cModWebSocket_finalize(NyLPC_TcModWebSocket_t* i_inst)
nyatla 57:bc4330dfa62f 163 {
nyatla 57:bc4330dfa62f 164 NyLPC_cModRomFiles_finalize(&i_inst->super);
nyatla 57:bc4330dfa62f 165 }
nyatla 57:bc4330dfa62f 166 /**
nyatla 57:bc4330dfa62f 167 * モジュールがコネクションをハンドリングできるかを返します。
nyatla 57:bc4330dfa62f 168 */
nyatla 57:bc4330dfa62f 169 NyLPC_TBool NyLPC_cModWebSocket_canHandle(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TcHttpdConnection_t* i_connection)
nyatla 57:bc4330dfa62f 170 {
nyatla 57:bc4330dfa62f 171 return NyLPC_cModRomFiles_canHandle(&i_inst->super,i_connection);
nyatla 57:bc4330dfa62f 172 }
nyatla 57:bc4330dfa62f 173
nyatla 57:bc4330dfa62f 174 static union{
nyatla 57:bc4330dfa62f 175 struct TModWebSocketHeader header;
nyatla 57:bc4330dfa62f 176 }work;
nyatla 57:bc4330dfa62f 177
nyatla 57:bc4330dfa62f 178
nyatla 57:bc4330dfa62f 179
nyatla 57:bc4330dfa62f 180 /**
nyatla 57:bc4330dfa62f 181 * モジュールを実行します。
nyatla 57:bc4330dfa62f 182 */
nyatla 57:bc4330dfa62f 183 NyLPC_TBool NyLPC_cModWebSocket_execute(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TcHttpdConnection_t* i_connection)
nyatla 57:bc4330dfa62f 184 {
nyatla 57:bc4330dfa62f 185 union{
nyatla 57:bc4330dfa62f 186 NyLPC_TcHttpBasicHeaderParser_t parser;
nyatla 57:bc4330dfa62f 187 SHA1_CTX sh1;
nyatla 57:bc4330dfa62f 188 }sh;
nyatla 57:bc4330dfa62f 189
nyatla 57:bc4330dfa62f 190 //リクエストParse済へ遷移(この関数の後はModが責任を持ってリクエストを返却)
nyatla 57:bc4330dfa62f 191 NyLPC_cHttpdConnection_setReqStatusParsed(i_connection);
nyatla 57:bc4330dfa62f 192
nyatla 57:bc4330dfa62f 193
nyatla 57:bc4330dfa62f 194
nyatla 57:bc4330dfa62f 195 //排他ロック
nyatla 57:bc4330dfa62f 196 NyLPC_cHttpdConnection_lock(i_connection);
nyatla 57:bc4330dfa62f 197 {//parser
nyatla 57:bc4330dfa62f 198
nyatla 57:bc4330dfa62f 199 //初期化
nyatla 57:bc4330dfa62f 200 work.header.version=0;
nyatla 57:bc4330dfa62f 201 work.header.sub_protocol_id=0;
nyatla 57:bc4330dfa62f 202 NyLPC_cStr_initialize(&work.header._tstr,work.header._tstr_buf,STRBUF_MAX);
nyatla 57:bc4330dfa62f 203
nyatla 57:bc4330dfa62f 204 NyLPC_cHttpBasicHeaderParser_initialize(&sh.parser,&handler);
nyatla 57:bc4330dfa62f 205
nyatla 57:bc4330dfa62f 206 //プリフェッチしたデータを流す
nyatla 57:bc4330dfa62f 207 NyLPC_cHttpBasicHeaderParser_parseInit(&sh.parser,&(work.header.super));
nyatla 57:bc4330dfa62f 208 NyLPC_cHttpdConnection_pushPrefetchInfo(i_connection,&sh.parser,&work.header.super);
nyatla 57:bc4330dfa62f 209 //後続をストリームから取り込む
nyatla 57:bc4330dfa62f 210 if(!NyLPC_cHttpBasicHeaderParser_parseStream(&sh.parser,NyLPC_cHttpdConnection_refStream(i_connection),&(work.header.super))){
nyatla 57:bc4330dfa62f 211 NyLPC_cHttpdUtils_sendErrorResponse(i_connection,500);
nyatla 57:bc4330dfa62f 212 NyLPC_OnErrorGoto(Error1);
nyatla 57:bc4330dfa62f 213 }
nyatla 57:bc4330dfa62f 214 if(!NyLPC_cHttpBasicHeaderParser_parseFinish(&sh.parser,&(work.header.super))){
nyatla 57:bc4330dfa62f 215 NyLPC_cHttpdUtils_sendErrorResponse(i_connection,500);
nyatla 57:bc4330dfa62f 216 NyLPC_OnErrorGoto(Error1);
nyatla 57:bc4330dfa62f 217 }
nyatla 57:bc4330dfa62f 218 //HeaderParserはここで破棄(URLEncode,cSTRも)
nyatla 57:bc4330dfa62f 219 NyLPC_cHttpBasicHeaderParser_finalize(&sh.parser);
nyatla 57:bc4330dfa62f 220
nyatla 57:bc4330dfa62f 221 NyLPC_cStr_finalize(&single_header._tstr);
nyatla 57:bc4330dfa62f 222
nyatla 57:bc4330dfa62f 223
nyatla 57:bc4330dfa62f 224 //HTTP/1.1であること。Connection:Upgradeはチェックしない。
nyatla 57:bc4330dfa62f 225 if(work.header.super.startline.req.version!=NyLPC_THttpVersion_11)
nyatla 57:bc4330dfa62f 226 {
nyatla 57:bc4330dfa62f 227 NyLPC_cHttpdUtils_sendErrorResponse(i_connection,400);
nyatla 57:bc4330dfa62f 228 NyLPC_OnErrorGoto(Error2);
nyatla 57:bc4330dfa62f 229 }
nyatla 57:bc4330dfa62f 230 if(NyLPC_cHttpdConnection_getMethod(i_connection)!=NyLPC_THttpMethodType_GET){
nyatla 57:bc4330dfa62f 231 NyLPC_cHttpdUtils_sendErrorResponse(i_connection,400);
nyatla 57:bc4330dfa62f 232 NyLPC_OnErrorGoto(Error2);
nyatla 57:bc4330dfa62f 233 }
nyatla 57:bc4330dfa62f 234 //WebSocket version 13であること
nyatla 57:bc4330dfa62f 235 if(work.header.version!=13){
nyatla 57:bc4330dfa62f 236 NyLPC_cHttpdUtils_sendErrorResponse(i_connection,400);
nyatla 57:bc4330dfa62f 237 NyLPC_OnErrorGoto(Error2);
nyatla 57:bc4330dfa62f 238 }
nyatla 57:bc4330dfa62f 239
nyatla 57:bc4330dfa62f 240 //レスポンスの生成(生データを直接ストリームへ書きこむ)
nyatla 57:bc4330dfa62f 241 if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_connection),
nyatla 57:bc4330dfa62f 242 "HTTP/1.1 101 Switching Protocols\r\n" //32+2
nyatla 57:bc4330dfa62f 243 "Upgrade: websocket\r\n" //18+2
nyatla 57:bc4330dfa62f 244 "Connection: Upgrade\r\n" //19+2
nyatla 57:bc4330dfa62f 245 "Sec-WebSocket-Accept: " //22
nyatla 57:bc4330dfa62f 246 ,32+2+18+2+19+2+22)){
nyatla 57:bc4330dfa62f 247 NyLPC_OnErrorGoto(Error3);
nyatla 57:bc4330dfa62f 248 }
nyatla 57:bc4330dfa62f 249 //SH1キーの生成
nyatla 57:bc4330dfa62f 250 SHA1Init(&sh.sh1);
nyatla 57:bc4330dfa62f 251 SHA1Update(&sh.sh1,(const unsigned char*)work.header.key,strlen(work.header.key));
nyatla 57:bc4330dfa62f 252 SHA1Update(&sh.sh1,(const unsigned char*)"258EAFA5-E914-47DA-95CA-C5AB0DC85B11",36);
nyatla 57:bc4330dfa62f 253 //ワークメモリ32バイトはstrの使いまわし
nyatla 57:bc4330dfa62f 254 SHA1Final((unsigned char*)(work.header._tstr_buf),&sh.sh1);
nyatla 57:bc4330dfa62f 255 //BASE64化(single_header.keyへ出力)
nyatla 57:bc4330dfa62f 256 NyLPC_cBase64_encode(work.header._tstr_buf,20,work.header.key);
nyatla 57:bc4330dfa62f 257 if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_connection),work.header.key,28)){
nyatla 57:bc4330dfa62f 258 NyLPC_OnErrorGoto(Error3);
nyatla 57:bc4330dfa62f 259 }
nyatla 57:bc4330dfa62f 260 //SubProtocolの認証が有る場合
nyatla 57:bc4330dfa62f 261 if(work.header.sub_protocol_id!=0){
nyatla 57:bc4330dfa62f 262 if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_connection)
nyatla 57:bc4330dfa62f 263 ,"\r\nSec-WebSocket-Protocol: " //24
nyatla 57:bc4330dfa62f 264 ,24)){
nyatla 57:bc4330dfa62f 265 NyLPC_OnErrorGoto(Error3);
nyatla 57:bc4330dfa62f 266 }
nyatla 57:bc4330dfa62f 267 if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_connection)
nyatla 57:bc4330dfa62f 268 ,work.header._ref_sub_protocol
nyatla 57:bc4330dfa62f 269 ,strlen(work.header._ref_sub_protocol)))
nyatla 57:bc4330dfa62f 270 {
nyatla 57:bc4330dfa62f 271 NyLPC_OnErrorGoto(Error3);
nyatla 57:bc4330dfa62f 272 }
nyatla 57:bc4330dfa62f 273 }
nyatla 57:bc4330dfa62f 274 //Sec-WebSocket-Protocol
nyatla 57:bc4330dfa62f 275 if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_connection),"\r\n\r\n",4)){
nyatla 57:bc4330dfa62f 276 NyLPC_OnErrorGoto(Error3);
nyatla 57:bc4330dfa62f 277 }
nyatla 57:bc4330dfa62f 278 i_inst->_payload_st=NyLPC_TcModWebSocket_ST_START_PAYLOAD;
nyatla 57:bc4330dfa62f 279 }
nyatla 57:bc4330dfa62f 280 //占有解除
nyatla 57:bc4330dfa62f 281 NyLPC_cHttpdConnection_unlock(i_connection);
nyatla 57:bc4330dfa62f 282 //参照コネクションの設定
nyatla 57:bc4330dfa62f 283 i_inst->_ref_connection=i_connection;
nyatla 57:bc4330dfa62f 284 NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection));
nyatla 57:bc4330dfa62f 285 return NyLPC_TBool_TRUE;
nyatla 57:bc4330dfa62f 286 Error3:
nyatla 57:bc4330dfa62f 287 Error2:
nyatla 57:bc4330dfa62f 288 //VM排他ロックの解除
nyatla 57:bc4330dfa62f 289 NyLPC_cHttpdConnection_unlock(i_connection);
nyatla 57:bc4330dfa62f 290 return NyLPC_TBool_FALSE;
nyatla 57:bc4330dfa62f 291 Error1:
nyatla 57:bc4330dfa62f 292 NyLPC_cHttpBasicHeaderParser_finalize(&parser);
nyatla 57:bc4330dfa62f 293 NyLPC_cStr_finalize(&single_header._tstr);
nyatla 57:bc4330dfa62f 294 //VM排他ロックの解除
nyatla 57:bc4330dfa62f 295 NyLPC_cHttpdConnection_unlock(i_connection);
nyatla 57:bc4330dfa62f 296 return NyLPC_TBool_FALSE;
nyatla 57:bc4330dfa62f 297 }
nyatla 57:bc4330dfa62f 298
nyatla 57:bc4330dfa62f 299
nyatla 57:bc4330dfa62f 300
nyatla 57:bc4330dfa62f 301 static void writeClosePacket(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TUInt16 i_code)
nyatla 57:bc4330dfa62f 302 {
nyatla 57:bc4330dfa62f 303 char w[4];
nyatla 57:bc4330dfa62f 304 w[0]=0x88;
nyatla 57:bc4330dfa62f 305 w[1]=0x02;
nyatla 57:bc4330dfa62f 306 *((NyLPC_TUInt16*)(&w[2]))=NyLPC_htons(i_code); //REASON
nyatla 57:bc4330dfa62f 307 //CloseFrame送信
nyatla 57:bc4330dfa62f 308 NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),w,4);
nyatla 57:bc4330dfa62f 309 NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection));
nyatla 57:bc4330dfa62f 310 }
nyatla 57:bc4330dfa62f 311
nyatla 57:bc4330dfa62f 312
nyatla 57:bc4330dfa62f 313 #define FLAGS_MASK_BIT 7
nyatla 57:bc4330dfa62f 314 /**
nyatla 57:bc4330dfa62f 315 * @return
nyatla 57:bc4330dfa62f 316 * n>0:データ受信
nyatla 57:bc4330dfa62f 317 * 0 :タイムアウト。コネクションの状態は変化しない。
nyatla 57:bc4330dfa62f 318 * -1 :エラー コネクションはNyLPC_TcModWebSocket_ST_CLOSEDへ遷移する。
nyatla 57:bc4330dfa62f 319 */
nyatla 57:bc4330dfa62f 320 NyLPC_TInt16 NyLPC_cModWebSocket_read(NyLPC_TcModWebSocket_t* i_inst,void* i_buf,NyLPC_TInt16 i_buf_len)
nyatla 57:bc4330dfa62f 321 {
nyatla 57:bc4330dfa62f 322 const NyLPC_TUInt8* rx;
nyatla 57:bc4330dfa62f 323 NyLPC_TInt32 rs,i;
nyatla 57:bc4330dfa62f 324 NyLPC_TUInt16 header_size;
nyatla 57:bc4330dfa62f 325 NyLPC_TUInt8 w8[2];
nyatla 57:bc4330dfa62f 326 if(i_inst->_payload_st==NyLPC_TcModWebSocket_ST_CLOSED){
nyatla 57:bc4330dfa62f 327 return -1;
nyatla 57:bc4330dfa62f 328 }
nyatla 57:bc4330dfa62f 329 START:
nyatla 57:bc4330dfa62f 330 rs=NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx);
nyatla 57:bc4330dfa62f 331 //Error?
nyatla 57:bc4330dfa62f 332 if(rs<0){
nyatla 57:bc4330dfa62f 333 NyLPC_OnErrorGoto(Error);
nyatla 57:bc4330dfa62f 334 }
nyatla 57:bc4330dfa62f 335 //Timeout?
nyatla 57:bc4330dfa62f 336 if(rs==0){
nyatla 57:bc4330dfa62f 337 goto Timeout;
nyatla 57:bc4330dfa62f 338 }
nyatla 57:bc4330dfa62f 339 switch(i_inst->_payload_st){
nyatla 57:bc4330dfa62f 340 case NyLPC_TcModWebSocket_ST_START_PAYLOAD:
nyatla 57:bc4330dfa62f 341 //ペイロード
nyatla 57:bc4330dfa62f 342 //2バイト溜まるまで待つ
nyatla 57:bc4330dfa62f 343 if(rs<2){
nyatla 57:bc4330dfa62f 344 //Timeout?
nyatla 57:bc4330dfa62f 345 goto Timeout;
nyatla 57:bc4330dfa62f 346 }
nyatla 57:bc4330dfa62f 347 //ペイロードサイズの分析
nyatla 57:bc4330dfa62f 348 if((0x7f&rx[1])<=125){
nyatla 57:bc4330dfa62f 349 header_size=2+(((rx[1]&0x80)==0x80)?4:0);
nyatla 57:bc4330dfa62f 350 i_inst->payload_size=(0x7f&rx[1]);
nyatla 57:bc4330dfa62f 351 }else if((0x7f&rx[1])==126){
nyatla 57:bc4330dfa62f 352 if(rs<4){
nyatla 57:bc4330dfa62f 353 //Timeout?
nyatla 57:bc4330dfa62f 354 goto Timeout;
nyatla 57:bc4330dfa62f 355 }
nyatla 57:bc4330dfa62f 356 header_size=2+2+(((rx[1]&0x80)==0x80)?4:0);
nyatla 57:bc4330dfa62f 357 i_inst->payload_size=(rx[2]<<8)|rx[3];
nyatla 57:bc4330dfa62f 358 }else{
nyatla 57:bc4330dfa62f 359 //CLOSEの送信
nyatla 57:bc4330dfa62f 360 writeClosePacket(i_inst,1009);
nyatla 57:bc4330dfa62f 361 NyLPC_OnErrorGoto(Error);
nyatla 57:bc4330dfa62f 362 }
nyatla 57:bc4330dfa62f 363 //十分なヘッダが集まったかチェック
nyatla 57:bc4330dfa62f 364 if(rs<header_size){
nyatla 57:bc4330dfa62f 365 goto Timeout;
nyatla 57:bc4330dfa62f 366 }
nyatla 57:bc4330dfa62f 367 i_inst->_frame_flags_bits=0;
nyatla 57:bc4330dfa62f 368 //FINがセットされていること.断片化禁止!
nyatla 57:bc4330dfa62f 369 if((rx[0]&0x80)!=0x80){
nyatla 57:bc4330dfa62f 370 NyLPC_OnErrorGoto(Error);
nyatla 57:bc4330dfa62f 371 }
nyatla 57:bc4330dfa62f 372 //必要ならMaskをコピー
nyatla 57:bc4330dfa62f 373 if((rx[1]&0x80)==0x80){
nyatla 57:bc4330dfa62f 374 memcpy(i_inst->_frame_mask,(rx+header_size-4),4);
nyatla 57:bc4330dfa62f 375 NyLPC_TUInt8_setBit(i_inst->_frame_flags_bits,FLAGS_MASK_BIT);
nyatla 57:bc4330dfa62f 376 }
nyatla 57:bc4330dfa62f 377 i_inst->payload_ptr=0;
nyatla 57:bc4330dfa62f 378
nyatla 57:bc4330dfa62f 379 //パケットサイズの確定(基本ヘッダ+マスク)
nyatla 57:bc4330dfa62f 380 switch(rx[0]&0x0f){
nyatla 57:bc4330dfa62f 381 case 0x00:
nyatla 57:bc4330dfa62f 382 //継続パケットは扱わない
nyatla 57:bc4330dfa62f 383 NyLPC_OnErrorGoto(Error);
nyatla 57:bc4330dfa62f 384 case 0x01:
nyatla 57:bc4330dfa62f 385 if(i_inst->_frame_type!=NyLPC_TcModWebSocket_FRAME_TYPE_TXT){
nyatla 57:bc4330dfa62f 386 NyLPC_OnErrorGoto(Error);
nyatla 57:bc4330dfa62f 387 }
nyatla 57:bc4330dfa62f 388 break;
nyatla 57:bc4330dfa62f 389 case 0x02:
nyatla 57:bc4330dfa62f 390 if(i_inst->_frame_type==NyLPC_TcModWebSocket_FRAME_TYPE_BIN){
nyatla 57:bc4330dfa62f 391 NyLPC_OnErrorGoto(Error);
nyatla 57:bc4330dfa62f 392 }
nyatla 57:bc4330dfa62f 393 break;
nyatla 57:bc4330dfa62f 394 case 0x08://close(非断片)
nyatla 57:bc4330dfa62f 395 //CloseFrame送信
nyatla 57:bc4330dfa62f 396 writeClosePacket(i_inst,1009);
nyatla 57:bc4330dfa62f 397 //Errorとして処理
nyatla 57:bc4330dfa62f 398 NyLPC_OnErrorGoto(Error);
nyatla 57:bc4330dfa62f 399 case 0x09://ping(非断片)
nyatla 57:bc4330dfa62f 400 //PONGを送信
nyatla 57:bc4330dfa62f 401 w8[0]=0x0a;
nyatla 57:bc4330dfa62f 402 NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),w8,1);
nyatla 57:bc4330dfa62f 403 NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),rx+1,header_size-1);
nyatla 57:bc4330dfa62f 404 NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection));
nyatla 57:bc4330dfa62f 405 NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),header_size);
nyatla 57:bc4330dfa62f 406 while(i_inst->payload_size!=i_inst->payload_ptr){
nyatla 57:bc4330dfa62f 407 rs=NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx);
nyatla 57:bc4330dfa62f 408 if(rs<=0){
nyatla 57:bc4330dfa62f 409 if(rs<0){
nyatla 57:bc4330dfa62f 410 //Error
nyatla 57:bc4330dfa62f 411 NyLPC_OnErrorGoto(Error);
nyatla 57:bc4330dfa62f 412 }
nyatla 57:bc4330dfa62f 413 //Timeout
nyatla 57:bc4330dfa62f 414 goto Timeout;
nyatla 57:bc4330dfa62f 415 }
nyatla 57:bc4330dfa62f 416 //読み込みサイズを決定
nyatla 57:bc4330dfa62f 417 rs=(rs<i_buf_len)?rs:i_buf_len;
nyatla 57:bc4330dfa62f 418 NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),rx,rs);
nyatla 57:bc4330dfa62f 419 NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),rs);
nyatla 57:bc4330dfa62f 420 i_inst->payload_ptr+=rs;
nyatla 57:bc4330dfa62f 421 }
nyatla 57:bc4330dfa62f 422 //Timeout(パケットスタートに戻る?)
nyatla 57:bc4330dfa62f 423 goto START;
nyatla 57:bc4330dfa62f 424 case 0x0a://pong(非断片)
nyatla 57:bc4330dfa62f 425 //パケットの読み捨て
nyatla 57:bc4330dfa62f 426 NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),header_size);
nyatla 57:bc4330dfa62f 427 while(i_inst->payload_size!=i_inst->payload_ptr){
nyatla 57:bc4330dfa62f 428 rs=NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx);
nyatla 57:bc4330dfa62f 429 if(rs<=0){
nyatla 57:bc4330dfa62f 430 if(rs<0){
nyatla 57:bc4330dfa62f 431 //Error
nyatla 57:bc4330dfa62f 432 NyLPC_OnErrorGoto(Error);
nyatla 57:bc4330dfa62f 433 }
nyatla 57:bc4330dfa62f 434 //Timeout
nyatla 57:bc4330dfa62f 435 goto Timeout;
nyatla 57:bc4330dfa62f 436 }
nyatla 57:bc4330dfa62f 437 //読み込みサイズを決定
nyatla 57:bc4330dfa62f 438 rs=(rs<i_buf_len)?rs:i_buf_len;
nyatla 57:bc4330dfa62f 439 NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),rs);
nyatla 57:bc4330dfa62f 440 i_inst->payload_ptr+=rs;
nyatla 57:bc4330dfa62f 441 }
nyatla 57:bc4330dfa62f 442 //Timeout(パケットスタートに戻る?)
nyatla 57:bc4330dfa62f 443 goto START;
nyatla 57:bc4330dfa62f 444 default:
nyatla 57:bc4330dfa62f 445 //知らないコードはエラー
nyatla 57:bc4330dfa62f 446 NyLPC_OnErrorGoto(Error);
nyatla 57:bc4330dfa62f 447 }
nyatla 57:bc4330dfa62f 448 //読み出し位置のシーク(Header部)
nyatla 57:bc4330dfa62f 449 NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),header_size);
nyatla 57:bc4330dfa62f 450 //ペイロード読み出しへ
nyatla 57:bc4330dfa62f 451 i_inst->_payload_st=NyLPC_TcModWebSocket_ST_READ_PAYLOAD;
nyatla 57:bc4330dfa62f 452 //継続してペイロード受信処理
nyatla 57:bc4330dfa62f 453 case NyLPC_TcModWebSocket_ST_READ_PAYLOAD:
nyatla 57:bc4330dfa62f 454 rs=NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx);
nyatla 57:bc4330dfa62f 455 if(rs<=0){
nyatla 57:bc4330dfa62f 456 if(rs<0){
nyatla 57:bc4330dfa62f 457 //Error
nyatla 57:bc4330dfa62f 458 NyLPC_OnErrorGoto(Error);
nyatla 57:bc4330dfa62f 459 }
nyatla 57:bc4330dfa62f 460 //Timeout
nyatla 57:bc4330dfa62f 461 goto Timeout;
nyatla 57:bc4330dfa62f 462 }
nyatla 57:bc4330dfa62f 463 //読み込みサイズを決定
nyatla 57:bc4330dfa62f 464 rs=(rs<i_buf_len)?rs:i_buf_len;
nyatla 57:bc4330dfa62f 465 //アンマスク
nyatla 57:bc4330dfa62f 466 if(NyLPC_TUInt8_isBitOn(i_inst->_frame_flags_bits,FLAGS_MASK_BIT)){
nyatla 57:bc4330dfa62f 467 for(i=0;i<rs;i++){
nyatla 57:bc4330dfa62f 468 *(((NyLPC_TUInt8*)i_buf)+i)=rx[i]^i_inst->_frame_mask[(i_inst->payload_ptr+i)%4];
nyatla 57:bc4330dfa62f 469 }
nyatla 57:bc4330dfa62f 470 }else{
nyatla 57:bc4330dfa62f 471 memcpy(i_buf,rx,rs);
nyatla 57:bc4330dfa62f 472 }
nyatla 57:bc4330dfa62f 473 //読取位置を移動
nyatla 57:bc4330dfa62f 474 NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),rs);
nyatla 57:bc4330dfa62f 475 i_inst->payload_ptr+=rs;
nyatla 57:bc4330dfa62f 476 if(i_inst->payload_size==i_inst->payload_ptr){
nyatla 57:bc4330dfa62f 477 i_inst->_payload_st=NyLPC_TcModWebSocket_ST_START_PAYLOAD;
nyatla 57:bc4330dfa62f 478 }
nyatla 57:bc4330dfa62f 479 return rs;
nyatla 57:bc4330dfa62f 480 }
nyatla 57:bc4330dfa62f 481 //処理されなければエラー
nyatla 57:bc4330dfa62f 482 Error:
nyatla 57:bc4330dfa62f 483 NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection);
nyatla 57:bc4330dfa62f 484 i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED;
nyatla 57:bc4330dfa62f 485 return -1;
nyatla 57:bc4330dfa62f 486 Timeout:
nyatla 57:bc4330dfa62f 487 return 0;
nyatla 57:bc4330dfa62f 488 }
nyatla 57:bc4330dfa62f 489
nyatla 57:bc4330dfa62f 490 static NyLPC_TBool fmt_handler(void* i_inst,const void* i_buf,NyLPC_TUInt32 i_len)
nyatla 57:bc4330dfa62f 491 {
nyatla 57:bc4330dfa62f 492 return NyLPC_iHttpPtrStream_write((NyLPC_TiHttpPtrStream_t*)i_inst,i_buf,i_len);
nyatla 57:bc4330dfa62f 493 }
nyatla 57:bc4330dfa62f 494
nyatla 57:bc4330dfa62f 495 NyLPC_TBool NyLPC_cModWebSocket_writeFormat(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,...)
nyatla 57:bc4330dfa62f 496 {
nyatla 57:bc4330dfa62f 497 va_list a;
nyatla 57:bc4330dfa62f 498 NyLPC_TInt16 l;
nyatla 57:bc4330dfa62f 499 NyLPC_TUInt16 s;
nyatla 57:bc4330dfa62f 500 NyLPC_TChar w[4];
nyatla 57:bc4330dfa62f 501 //データサイズで切り分け
nyatla 57:bc4330dfa62f 502 if(i_inst->_payload_st==NyLPC_TcModWebSocket_ST_CLOSED){
nyatla 57:bc4330dfa62f 503 return NyLPC_TBool_FALSE;
nyatla 57:bc4330dfa62f 504 }
nyatla 57:bc4330dfa62f 505 //書式文字列の長さを計算
nyatla 57:bc4330dfa62f 506 va_start(a,i_fmt);
nyatla 57:bc4330dfa62f 507 l=NyLPC_cFormatWriter_length(i_fmt,a);
nyatla 57:bc4330dfa62f 508 va_end(a);
nyatla 57:bc4330dfa62f 509 switch(i_inst->_frame_type)
nyatla 57:bc4330dfa62f 510 {
nyatla 57:bc4330dfa62f 511 case NyLPC_TcModWebSocket_FRAME_TYPE_TXT:
nyatla 57:bc4330dfa62f 512 w[0]=0x80|0x01;
nyatla 57:bc4330dfa62f 513 break;
nyatla 57:bc4330dfa62f 514 case NyLPC_TcModWebSocket_FRAME_TYPE_BIN:
nyatla 57:bc4330dfa62f 515 w[0]=0x80|0x02;
nyatla 57:bc4330dfa62f 516 break;
nyatla 57:bc4330dfa62f 517 default:
nyatla 57:bc4330dfa62f 518 NyLPC_OnErrorGoto(Error);
nyatla 57:bc4330dfa62f 519 }
nyatla 57:bc4330dfa62f 520 if(l<126){
nyatla 57:bc4330dfa62f 521 w[1]=(NyLPC_TUInt8)l;
nyatla 57:bc4330dfa62f 522 s=2;
nyatla 57:bc4330dfa62f 523 }else{
nyatla 57:bc4330dfa62f 524 w[1]=126;
nyatla 57:bc4330dfa62f 525 s=3;
nyatla 57:bc4330dfa62f 526 *((NyLPC_TUInt16*)(&(w[2])))=NyLPC_htons(l);
nyatla 57:bc4330dfa62f 527 }
nyatla 57:bc4330dfa62f 528 if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),w,s)){
nyatla 57:bc4330dfa62f 529 //CLOSE
nyatla 57:bc4330dfa62f 530 NyLPC_OnErrorGoto(Error);
nyatla 57:bc4330dfa62f 531 }
nyatla 57:bc4330dfa62f 532 va_start(a,i_fmt);
nyatla 57:bc4330dfa62f 533 if(!NyLPC_cFormatWriter_print(fmt_handler,NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),i_fmt,a)){
nyatla 57:bc4330dfa62f 534 va_end(a);
nyatla 57:bc4330dfa62f 535 NyLPC_OnErrorGoto(Error);
nyatla 57:bc4330dfa62f 536 }
nyatla 57:bc4330dfa62f 537 va_end(a);
nyatla 57:bc4330dfa62f 538 NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection));
nyatla 57:bc4330dfa62f 539 return NyLPC_TBool_TRUE;
nyatla 57:bc4330dfa62f 540 Error:
nyatla 57:bc4330dfa62f 541 NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection);
nyatla 57:bc4330dfa62f 542 i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED;
nyatla 57:bc4330dfa62f 543 return NyLPC_TBool_FALSE;
nyatla 57:bc4330dfa62f 544 }
nyatla 57:bc4330dfa62f 545
nyatla 57:bc4330dfa62f 546 NyLPC_TBool NyLPC_cModWebSocket_write(NyLPC_TcModWebSocket_t* i_inst,void* i_buf,NyLPC_TInt16 i_len)
nyatla 57:bc4330dfa62f 547 {
nyatla 57:bc4330dfa62f 548 NyLPC_TChar w[4];
nyatla 57:bc4330dfa62f 549 NyLPC_TUInt16 s;
nyatla 57:bc4330dfa62f 550 //データサイズで切り分け
nyatla 57:bc4330dfa62f 551 if(i_inst->_payload_st==NyLPC_TcModWebSocket_ST_CLOSED){
nyatla 57:bc4330dfa62f 552 return NyLPC_TBool_FALSE;
nyatla 57:bc4330dfa62f 553 }
nyatla 57:bc4330dfa62f 554 //OP CODE
nyatla 57:bc4330dfa62f 555 switch(i_inst->_frame_type)
nyatla 57:bc4330dfa62f 556 {
nyatla 57:bc4330dfa62f 557 case NyLPC_TcModWebSocket_FRAME_TYPE_TXT:
nyatla 57:bc4330dfa62f 558 w[0]=0x80|0x01;
nyatla 57:bc4330dfa62f 559 break;
nyatla 57:bc4330dfa62f 560 case NyLPC_TcModWebSocket_FRAME_TYPE_BIN:
nyatla 57:bc4330dfa62f 561 w[0]=0x80|0x02;
nyatla 57:bc4330dfa62f 562 break;
nyatla 57:bc4330dfa62f 563 default:
nyatla 57:bc4330dfa62f 564 NyLPC_OnErrorGoto(Error);
nyatla 57:bc4330dfa62f 565 }
nyatla 57:bc4330dfa62f 566 if(i_len<126){
nyatla 57:bc4330dfa62f 567 w[1]=(NyLPC_TUInt8)i_len;
nyatla 57:bc4330dfa62f 568 s=2;
nyatla 57:bc4330dfa62f 569 }else{
nyatla 57:bc4330dfa62f 570 w[1]=126;
nyatla 57:bc4330dfa62f 571 s=3;
nyatla 57:bc4330dfa62f 572 *((NyLPC_TUInt16*)(&(w[2])))=NyLPC_htons(i_len);
nyatla 57:bc4330dfa62f 573 }
nyatla 57:bc4330dfa62f 574 if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),w,s)){
nyatla 57:bc4330dfa62f 575 //CLOSE
nyatla 57:bc4330dfa62f 576 NyLPC_OnErrorGoto(Error);
nyatla 57:bc4330dfa62f 577 }
nyatla 57:bc4330dfa62f 578 if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),i_buf,i_len)){
nyatla 57:bc4330dfa62f 579 //CLOSE
nyatla 57:bc4330dfa62f 580 NyLPC_OnErrorGoto(Error);
nyatla 57:bc4330dfa62f 581 }
nyatla 57:bc4330dfa62f 582 NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection));
nyatla 57:bc4330dfa62f 583 return NyLPC_TBool_TRUE;
nyatla 57:bc4330dfa62f 584 Error:
nyatla 57:bc4330dfa62f 585 NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection);
nyatla 57:bc4330dfa62f 586 i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED;
nyatla 57:bc4330dfa62f 587 return NyLPC_TBool_FALSE;
nyatla 57:bc4330dfa62f 588 }
nyatla 57:bc4330dfa62f 589
nyatla 57:bc4330dfa62f 590 void NyLPC_cModWebSocket_close(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TUInt16 i_code)
nyatla 57:bc4330dfa62f 591 {
nyatla 57:bc4330dfa62f 592 if(i_inst->_payload_st==NyLPC_TcModWebSocket_ST_CLOSED){
nyatla 57:bc4330dfa62f 593 return;
nyatla 57:bc4330dfa62f 594 }
nyatla 57:bc4330dfa62f 595 //CLOSE送信
nyatla 57:bc4330dfa62f 596 writeClosePacket(i_inst,i_code);
nyatla 57:bc4330dfa62f 597 i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED;
nyatla 57:bc4330dfa62f 598 //切断
nyatla 57:bc4330dfa62f 599 NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection);
nyatla 57:bc4330dfa62f 600 }