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

Files at this revision

API Documentation at this revision

Comitter:
nyatla
Date:
Tue Jun 10 03:30:41 2014 +0000
Parent:
70:2ed02b798004
Child:
72:c118a7aa37a3
Commit message:
MiMic-core ?358???; modJsonRPC???????????;

Changed in this revision

core/NyLPC_cMiMicEnv.c Show annotated file Show diff for this revision Revisions of this file
core/http/json/NyLPC_cJsonRpcParser.c Show annotated file Show diff for this revision Revisions of this file
core/http/json/NyLPC_cJsonRpcParser.h Show annotated file Show diff for this revision Revisions of this file
core/include/NyLPC_http.h Show annotated file Show diff for this revision Revisions of this file
core/include/NyLPC_net.h Show annotated file Show diff for this revision Revisions of this file
core/net/httpd/mod/NyLPC_cModJsonRpc.c Show annotated file Show diff for this revision Revisions of this file
core/net/httpd/mod/NyLPC_cModJsonRpc.h Show annotated file Show diff for this revision Revisions of this file
core/net/httpd/mod/NyLPC_cModWebSocket.c Show annotated file Show diff for this revision Revisions of this file
core/net/httpd/mod/NyLPC_cModWebSocket.h Show annotated file Show diff for this revision Revisions of this file
core/net/httpd/mod/NyLPC_cModWebSocket_protected.h Show annotated file Show diff for this revision Revisions of this file
--- a/core/NyLPC_cMiMicEnv.c	Thu May 29 16:07:14 2014 +0000
+++ b/core/NyLPC_cMiMicEnv.c	Tue Jun 10 03:30:41 2014 +0000
@@ -1,7 +1,7 @@
 #include "NyLPC_cMiMicEnv.h"
 #include "../uip/NyLPC_cUipService_protected.h"
 
-const static char* VERSION="MiMic/1.5.0";
+const static char* VERSION="MiMic/1.5.2";
 
 #if NyLPC_MCU==NyLPC_MCU_LPC4088
 const static char* MCU="LPC4088";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/http/json/NyLPC_cJsonRpcParser.c	Tue Jun 10 03:30:41 2014 +0000
@@ -0,0 +1,645 @@
+#include "NyLPC_cJsonRpcParser.h"
+
+//
+//	NyLPC_TJsonRpcParserResult
+//
+
+
+NyLPC_TBool NyLPC_TJsonRpcParserResult_getUInt32(const union NyLPC_TJsonRpcParserResult* i_struct,NyLPC_TInt16 i_idx,NyLPC_TUInt32* o_val)
+{
+	if(i_struct->method.class_def->functions[i_struct->method.func_number].param_patt[i_idx]!=NyLPC_cJsonRpcParser_TYPE_UINT32){
+		return NyLPC_TBool_FALSE;
+	}
+	*o_val = *((NyLPC_TUInt32*)(i_struct->method.param_buf + i_struct->method.param_index[i_idx]));
+	return NyLPC_TBool_TRUE;
+}
+NyLPC_TBool NyLPC_TJsonRpcParserResult_getInt32(const union NyLPC_TJsonRpcParserResult* i_struct, NyLPC_TInt16 i_idx, NyLPC_TInt32* o_val)
+{
+	if (i_struct->method.class_def->functions[i_struct->method.func_number].param_patt[i_idx] != NyLPC_cJsonRpcParser_TYPE_INT32){
+		return NyLPC_TBool_FALSE;
+	}
+	*o_val = *((NyLPC_TInt32*)(i_struct->method.param_buf + i_struct->method.param_index[i_idx]));
+	return NyLPC_TBool_TRUE;
+}
+NyLPC_TBool NyLPC_TJsonRpcParserResult_getStr(const union NyLPC_TJsonRpcParserResult* i_struct, NyLPC_TInt16 i_idx, const NyLPC_TChar** o_val)
+{
+	if (i_struct->method.class_def->functions[i_struct->method.func_number].param_patt[i_idx] != NyLPC_cJsonRpcParser_TYPE_STRING){
+		return NyLPC_TBool_FALSE;
+	}
+	*o_val = ((NyLPC_TChar*)(i_struct->method.param_buf + i_struct->method.param_index[i_idx]));
+	return NyLPC_TBool_TRUE;
+}
+NyLPC_TBool NyLPC_TJsonRpcParserResult_getByte(const union NyLPC_TJsonRpcParserResult* i_struct, NyLPC_TInt16 i_idx, NyLPC_TUInt8* o_val)
+{
+	if (i_struct->method.class_def->functions[i_struct->method.func_number].param_patt[i_idx] != NyLPC_cJsonRpcParser_TYPE_BYTE){
+		return NyLPC_TBool_FALSE;
+	}
+	*o_val = *(i_struct->method.param_buf + i_struct->method.param_index[i_idx]);
+	return NyLPC_TBool_TRUE;
+}
+
+
+//
+//	NyLPC_cJsonRpcParser
+//
+
+
+
+#define NAME_ID_UNKNOWN		0
+#define NAME_ID_VERSION		1
+#define NAME_ID_METHOD		2
+#define NAME_ID_RESULT		3
+#define NAME_ID_PARAMS		4
+#define NAME_ID_ID			5
+
+const struct NyLPC_TTextIdTbl method_name_tbl[]=
+{
+	{"version",NAME_ID_VERSION},
+	{"method",NAME_ID_METHOD},
+	{"params",NAME_ID_PARAMS},
+	{"id",NAME_ID_ID},
+	{NULL,NAME_ID_UNKNOWN}
+};
+
+
+static const struct NyLPC_TJsonRpcClassDef* findFunction(const struct NyLPC_TJsonRpcClassDef** i_tbl, const NyLPC_TChar* i_method_path, NyLPC_TUInt8* o_function_idx);
+static void putchar_params(NyLPC_TcJsonRpcParser_t* i_inst, char i_c);
+static NyLPC_TUInt8 valTerminator2St(NyLPC_TChar i_c);
+
+
+void NyLPC_cJsonRpcParser_initialize(
+	NyLPC_TcJsonRpcParser_t* i_inst,
+	const struct NyLPC_TJsonRpcClassDef** i_class_def)
+{
+	i_inst->_class_def=i_class_def;
+}
+void NyLPC_cJsonRpcParser_initParser(NyLPC_TcJsonRpcParser_t* i_inst,union NyLPC_TJsonRpcParserResult* i_result)
+{
+	i_inst->_result=i_result;
+	i_result->type=NyLPC_TJsonRpcParserResult_TYPE_UNKNOWN;
+	i_inst->_st = NyLPC_TcJsonRpcParser_ST_START;
+	i_inst->_pcounter = 0;
+	memset(i_result->raw.param_index, 0xff, NyLPC_TJsonRpcParserResult_NUMBER_OF_PARAM_INDEX);
+}
+
+
+
+static const struct NyLPC_TJsonRpcClassDef* findFunction(const struct NyLPC_TJsonRpcClassDef** i_tbl,const NyLPC_TChar* i_method_path,NyLPC_TUInt8* o_function_idx)
+{
+	const NyLPC_TChar* ns;
+	const NyLPC_TChar* class_;
+	const NyLPC_TChar* method;
+	NyLPC_TUInt8 fidx;
+	int l;
+	//namespaceの抽出
+	ns=i_method_path;
+	class_=strchr(i_method_path,':');
+	if(class_==NULL){
+		return NULL;
+	}
+	class_++;
+	//functionの抽出
+	method=strchr(class_,':');
+	if(method==NULL){
+		return NULL;
+	}
+	method++;
+	while((*i_tbl)!=NULL){
+		l=class_-ns-1;
+		if(strncmp((*i_tbl)->names_pace,ns,l)!=0 || (*(ns+l))!=':'){
+			i_tbl++;
+			continue;
+		}
+		l=method-class_-1;
+		if(strncmp((*i_tbl)->class_name,class_,l)!=0 || (*(class_+l))!=':'){
+			i_tbl++;
+			continue;
+		}
+		fidx=0;
+		while(((*i_tbl)->functions+fidx)->name!=NULL){
+			if(strcmp(((*i_tbl)->functions+fidx)->name,method)!=0){
+				fidx++;
+				continue;
+			}
+			*o_function_idx=fidx;
+			return (*i_tbl);
+		}
+		break;
+	}
+	return NULL;
+}
+#define PARAM_ST_START	1
+#define PARAM_ST_VAL	2
+#define PARAM_ST_INT	3
+#define PARAM_ST_UINT	4
+#define PARAM_ST_STR	5
+#define PARAM_ST_NEXT	6
+#define PARAM_ST_BYTE	7
+
+static void putchar_params(NyLPC_TcJsonRpcParser_t* i_inst, char i_c)
+{
+
+	switch (i_inst->_pst){
+	case PARAM_ST_START:
+		if (i_c == '['){
+			//パース開始
+			i_inst->_work.str.n = 0;
+			i_inst->_pst = PARAM_ST_VAL;
+			return;
+		}
+		if (strchr(" ", i_c) != NULL){
+			//無視
+			return;
+		}
+		//エラー
+		goto ERROR;
+	case PARAM_ST_VAL:
+		if (i_inst->_pcounter >= NyLPC_TJsonRpcParserResult_NUMBER_OF_PARAM_INDEX){
+			goto ERROR;
+		}
+		if (strchr(" ", i_c) != NULL){
+			//無視
+			return;
+		}
+		if (strchr("]", i_c) != NULL){
+			i_inst->_st = NyLPC_TcJsonRpcParser_ST_NEXT;
+			i_inst->_pcounter = 0xff;
+			return;
+		}
+		switch (i_inst->_result->method.class_def->functions[i_inst->_result->method.func_number].param_patt[i_inst->_pcounter]){
+		case NyLPC_cJsonRpcParser_TYPE_INT32:
+			if (strchr("-0123456789", i_c) == NULL){
+				goto ERROR;
+			}
+			i_inst->_pst = PARAM_ST_INT;
+			i_inst->_work.int32.s = i_c == '-' ? -1 : 1;
+			i_inst->_work.int32.v = i_c == '-' ? 0 : (i_c - '0');
+			i_inst->_work.str.n = ((i_inst->_work.str.n + 3) / 4) * 4;
+			break;
+		case NyLPC_cJsonRpcParser_TYPE_UINT32:
+			if (strchr("0123456789", i_c) == NULL){
+				goto ERROR;
+			}
+			i_inst->_pst = PARAM_ST_UINT;
+			i_inst->_work.uint32 = (i_c - '0');
+			//開始位置を4バイト境界に
+			i_inst->_work.str.n = ((i_inst->_work.str.n + 3) / 4) * 4;
+			break;
+		case NyLPC_cJsonRpcParser_TYPE_BYTE:
+			if (strchr("0123456789", i_c) == NULL){
+				goto ERROR;
+			}
+			i_inst->_pst = PARAM_ST_BYTE;
+			i_inst->_work.uint32 = (i_c - '0');
+			break;
+		case NyLPC_cJsonRpcParser_TYPE_STRING:
+			if (i_c != '"'){
+				goto ERROR;
+			}
+			i_inst->_pst = PARAM_ST_STR;
+			break;
+		default:
+			goto ERROR;
+		}
+		i_inst->_result->method.param_index[i_inst->_pcounter] = i_inst->_work.str.n;
+		i_inst->_pcounter++;
+		return;
+	case PARAM_ST_STR:
+		if (i_c == '"'){
+			//完了
+			if (i_inst->_work.str.n >= NyLPC_TJsonRpcParserResult_PARAM_BUF){
+				goto ERROR;
+			}
+			i_inst->_result->method.param_buf[i_inst->_work.str.n] = '\0';
+			i_inst->_work.str.n++;
+			i_inst->_pst = PARAM_ST_NEXT;
+			return;
+		}
+		else{
+			if (i_inst->_work.str.n >= NyLPC_TJsonRpcParserResult_PARAM_BUF){
+				goto ERROR;
+			}
+			i_inst->_result->method.param_buf[i_inst->_work.str.n] = i_c;
+			i_inst->_work.str.n++;
+		}
+		return;
+	case PARAM_ST_INT:
+		if (strchr("0123456789", i_c) != NULL){
+			i_inst->_work.int32.v = i_inst->_work.int32.v * 10 + (i_c - '0');
+			return;
+		}
+		switch (i_c){
+		case ' ':
+			i_inst->_pst = PARAM_ST_NEXT; break;
+		case ',':
+			i_inst->_pst = PARAM_ST_VAL; break;
+		case ']':
+			i_inst->_st = NyLPC_TcJsonRpcParser_ST_NEXT; break;
+		default:
+			goto ERROR;
+		}
+		//4バイト境界に揃える
+		i_inst->_work.str.n += 4;
+		if (i_inst->_work.str.n > NyLPC_TJsonRpcParserResult_PARAM_BUF){
+			goto ERROR;
+		}
+		*((NyLPC_TInt32*)&(i_inst->_result->method.param_buf[i_inst->_work.str.n - 4])) = i_inst->_work.int32.v*i_inst->_work.int32.s;
+		return;
+	case PARAM_ST_UINT:
+		if (strchr("0123456789", i_c) != NULL){
+			i_inst->_work.uint32 = i_inst->_work.uint32 * 10 + (i_c - '0');
+			return;
+		}
+		switch (i_c){
+		case ' ':
+			i_inst->_pst = PARAM_ST_NEXT; break;
+		case ',':
+			i_inst->_pst = PARAM_ST_VAL; break;
+		case ']':
+			i_inst->_st = NyLPC_TcJsonRpcParser_ST_NEXT; break;
+		default:
+			goto ERROR;
+		}
+		i_inst->_work.str.n += 4;
+		if (i_inst->_work.str.n > NyLPC_TJsonRpcParserResult_PARAM_BUF){
+			goto ERROR;
+		}
+		*((NyLPC_TUInt32*)&(i_inst->_result->method.param_buf[i_inst->_work.str.n - 4])) = i_inst->_work.uint32;
+		return;
+	case PARAM_ST_BYTE:
+		if (strchr("0123456789", i_c) != NULL){
+			i_inst->_work.uint32 = i_inst->_work.uint32 * 10 + (i_c - '0');
+			return;
+		}
+		switch (i_c){
+		case ' ':
+			i_inst->_pst = PARAM_ST_NEXT; break;
+		case ',':
+			i_inst->_pst = PARAM_ST_VAL; break;
+		case ']':
+			i_inst->_st = NyLPC_TcJsonRpcParser_ST_NEXT; break;
+		default:
+			goto ERROR;
+		}
+		i_inst->_work.str.n ++;
+		if (i_inst->_work.str.n > NyLPC_TJsonRpcParserResult_PARAM_BUF){
+			goto ERROR;
+		}
+		*((NyLPC_TUInt8*)&(i_inst->_result->method.param_buf[i_inst->_work.str.n - 1])) = (NyLPC_TUInt8)(i_inst->_work.uint32&0xff);
+		return;
+	case PARAM_ST_NEXT:
+		switch (i_c){
+		case ' ':break;
+		case ',':
+			i_inst->_pst = PARAM_ST_VAL; break;
+		case ']':
+			i_inst->_st = NyLPC_TcJsonRpcParser_ST_NEXT; break;
+		default:
+			goto ERROR;
+		}
+		return;
+	}
+ERROR:
+	i_inst->_st = NyLPC_TcJsonRpcParser_ST_ERROR;
+	return;
+}
+
+
+/**
+* NyLPC_cJsonRpcParser_putCharのサブ関数
+*/
+static NyLPC_TUInt8 valTerminator2St(NyLPC_TChar i_c)
+{
+	switch (i_c){
+	case ' ':
+		return NyLPC_TcJsonRpcParser_ST_NEXT;
+	case '}':
+		return NyLPC_TcJsonRpcParser_ST_END;
+	case ',':
+		return NyLPC_TcJsonRpcParser_ST_NAME_Q;
+	default:
+		//ないはず
+		return NyLPC_TcJsonRpcParser_ST_ERROR;
+	}
+}
+
+/** 文字列をパーサに入力してパーサの状態を遷移させます。
+
+*/
+void NyLPC_cJsonRpcParser_putChar(NyLPC_TcJsonRpcParser_t* i_inst,char i_c)
+{
+	switch(i_inst->_st){
+	case NyLPC_TcJsonRpcParser_ST_PARAMS:
+		putchar_params(i_inst,i_c);
+		return;
+	case NyLPC_TcJsonRpcParser_ST_START:
+		if(i_c=='{'){
+			i_inst->_st=NyLPC_TcJsonRpcParser_ST_NAME_Q;
+			return;
+		}
+		if(strchr(" ",i_c)!=NULL){
+			//無視
+			return;
+		}
+		//エラー
+		goto ERROR;
+	case NyLPC_TcJsonRpcParser_ST_NAME_Q:
+		if(i_c=='"'){
+			i_inst->_st=NyLPC_TcJsonRpcParser_ST_NAME_STR;
+			i_inst->_work.str.n=0;
+			return;
+		}
+		if(strchr(" ",i_c)!=NULL){
+			//無視
+			return;
+		}
+		//エラー
+		goto ERROR;
+	case NyLPC_TcJsonRpcParser_ST_NAME_STR:
+		if(i_c=='"'){
+			//完了
+			i_inst->_work.str.buf[i_inst->_work.str.n]='\0';
+			//メソッドIDを記録
+			i_inst->_name_id=NyLPC_TTextIdTbl_getMatchId(i_inst->_work.str.buf,method_name_tbl);
+			i_inst->_st=NyLPC_TcJsonRpcParser_ST_NV_SEP;
+			switch(i_inst->_name_id){
+			case NAME_ID_METHOD:
+			case NAME_ID_RESULT:
+				if(i_inst->_result->type!=NyLPC_TJsonRpcParserResult_TYPE_UNKNOWN){
+					goto ERROR;
+				}
+				break;
+			case NAME_ID_PARAMS:
+				if (i_inst->_pcounter != 0){
+					goto ERROR;
+				}
+				break;
+			default:
+				break;
+			}
+			return;
+		}
+		i_inst->_work.str.n++;
+		if(i_inst->_work.str.n>=NyLPC_TcJsonRpcParser_WORK_MAX){
+			//文字列長すぎでござる。
+			goto ERROR;
+		}
+		i_inst->_work.str.buf[i_inst->_work.str.n-1]=i_c;
+		return;
+	case NyLPC_TcJsonRpcParser_ST_NV_SEP:
+		if(i_c==':'){
+			if (i_inst->_name_id == NAME_ID_PARAMS){
+				i_inst->_pst = PARAM_ST_START;
+				i_inst->_st = NyLPC_TcJsonRpcParser_ST_PARAMS;
+			}
+			else{
+				i_inst->_st = NyLPC_TcJsonRpcParser_ST_VAL;
+				i_inst->_work.str.n = 0;
+			}
+			return;
+		}
+		if(strchr(" ",i_c)!=NULL){
+			//無視
+			return;
+		}
+		//エラー
+		goto ERROR;
+	case NyLPC_TcJsonRpcParser_ST_VAL:
+		if(i_c=='"'){
+			i_inst->_st=NyLPC_TcJsonRpcParser_ST_VAL_STR;
+			i_inst->_work.str.n=0;
+			return;
+		}
+		if(strchr(" ",i_c)!=NULL){
+			//無視
+			return;
+		}
+		if(strchr("0123456789",i_c)!=NULL){
+			i_inst->_work.uint32=(i_c-'0');
+			i_inst->_st=NyLPC_TcJsonRpcParser_ST_VAL_UINT;
+			return;
+		}
+		//エラー
+		goto ERROR;
+	case NyLPC_TcJsonRpcParser_ST_VAL_UINT:
+		if(strchr("0123456789",i_c)!=NULL){
+			i_inst->_work.uint32=i_inst->_work.uint32*10+(i_c-'0');
+			return;
+		}
+		if(strchr(" ,}",i_c)!=NULL){
+			//確定
+			switch(i_inst->_name_id){
+			case NAME_ID_ID:
+				i_inst->_result->method.id=i_inst->_work.uint32;
+				break;
+			case NAME_ID_UNKNOWN:
+				//知らないIDは無視
+				break;
+			default:
+				//数値を受け入れないパラメータ
+				goto ERROR;
+			}
+			i_inst->_st=valTerminator2St(i_c);
+			return;
+		}
+		goto ERROR;
+	case NyLPC_TcJsonRpcParser_ST_VAL_STR:
+		if(i_c=='"'){
+			i_inst->_work.str.buf[i_inst->_work.str.n]='\0';
+			//確定
+			switch(i_inst->_name_id){
+			case NAME_ID_VERSION:
+				if(strcmp(i_inst->_work.str.buf,"2.0")!=0){
+					goto ERROR;
+				}
+				break;
+			case NAME_ID_METHOD:
+				i_inst->_result->method._type=NyLPC_TJsonRpcParserResult_TYPE_METHOD;
+				i_inst->_result->method.class_def=findFunction(i_inst->_class_def,i_inst->_work.str.buf,&(i_inst->_result->method.func_number));
+				if(i_inst->_result->method.class_def==NULL){
+					goto ERROR;
+				}
+				break;
+			case NAME_ID_UNKNOWN:
+				//知らないIDは無視
+				break;
+			default:
+				//文字列を受け入れないパラメータ
+				goto ERROR;
+			}
+			i_inst->_st=NyLPC_TcJsonRpcParser_ST_NEXT;
+			return;
+		}
+		i_inst->_work.str.n++;
+		if(i_inst->_work.str.n>=NyLPC_TcJsonRpcParser_WORK_MAX){
+			//文字列長すぎでござる。
+			goto ERROR;
+		}
+		i_inst->_work.str.buf[i_inst->_work.str.n-1]=i_c;
+		return;
+	case NyLPC_TcJsonRpcParser_ST_NEXT:
+		if(i_c==','){
+			i_inst->_st=NyLPC_TcJsonRpcParser_ST_NAME_Q;
+		}else if(i_c=='}'){
+			i_inst->_st=NyLPC_TcJsonRpcParser_ST_END;
+		}else if(strchr(" ",i_c)!=NULL){
+			//nothing to do
+		}else{
+			goto ERROR;
+		}
+		return;
+	default:
+		goto ERROR;
+	}
+ERROR:
+	i_inst->_st = NyLPC_TcJsonRpcParser_ST_ERROR;
+	return;
+}
+
+#define COMMENT_DEBUG
+#ifndef COMMENT_DEBUG
+
+const struct NyLPC_TJsonRpcMethodDef test_method[]=
+{
+	{ "func" , ""},
+	{ "func1", "d" },
+	{ "func2", "dd" },
+	{ "func3", "u" },
+	{ "func4", "uu" },
+	{ "func5", "uss" },
+	{ "func5", "uss" },
+	{ "func6", "s" },
+	{ "func7", "sd" },
+	{ "func8", "su" },
+	{ "func9", "ss" },
+	{ "f10", "suu" },
+	{ "f11", "bbbb" },
+	{ NULL, "" }
+};
+
+const struct NyLPC_TJsonRpcClassDef test_def=
+{
+	"ns","class",
+	test_method
+};
+
+/**
+ * テスト用のアレイ
+ */
+const struct NyLPC_TJsonRpcClassDef* test_def_array[]=
+{
+	&test_def,
+	NULL
+};
+
+void NyLPC_cJsonRpcParser_putText(NyLPC_TcJsonRpcParser_t* i_inst, const NyLPC_TChar* i_text,NyLPC_TUInt16 i_size)
+{
+	NyLPC_TUInt16 i;
+	NyLPC_TUInt32 u32;
+	NyLPC_TInt32 i32;
+	NyLPC_TChar* c;
+	NyLPC_TUInt8 u8;
+
+
+	for (i = 0; i < i_size; i++){
+		NyLPC_cJsonRpcParser_putChar(i_inst,i_text[i]);
+		if (i_inst->_st == NyLPC_TcJsonRpcParser_ST_ERROR){
+			break;
+		}
+		else if (i_inst->_st == NyLPC_TcJsonRpcParser_ST_END){
+			break;
+		}
+	}
+	if (i_inst->_st == NyLPC_TcJsonRpcParser_ST_ERROR){
+		printf("ERROR!\n");
+	}
+	else if (i_inst->_st == NyLPC_TcJsonRpcParser_ST_END){
+		printf("OK!\n");
+		for (int i = 0; i_inst->_result->method.param_index[i] != 0xff && i<i_inst->_pcounter; i++){
+			switch (i_inst->_result->method.class_def->functions[i_inst->_result->method.func_number].param_patt[i]){
+			case 'u':NyLPC_TJsonRpcParserResult_getUInt32(i_inst->_result,i, &u32); printf("%u,", u32); break;
+			case 'd':NyLPC_TJsonRpcParserResult_getInt32(i_inst->_result, i, &i32); printf("%d,", i32); break;
+			case 's':NyLPC_TJsonRpcParserResult_getStr(i_inst->_result, i, &c); printf("%s,", c); break;
+			case 'b':NyLPC_TJsonRpcParserResult_getByte(i_inst->_result, i, &u8); printf("%u,", u8); break;
+			}
+		}
+		printf("\n");
+	}
+	else{
+		printf("CONTINUE...\n");
+	}
+}
+
+void main(void)
+{
+	NyLPC_TcJsonRpcParser_t inst;
+	union NyLPC_TJsonRpcParserResult ret;
+
+//JSONCORE
+//#define JSONCORE 1
+#ifdef JSONCORE
+	const char* t[] = {
+		"{\"0123\"\"2.0\"}",//NO
+		"{\"01234567890123456789\":\"2.0\"}",//NO
+		"{\"0123\":\"01234567890123456789\"}",//NO
+		"{\"version\":\"2.0\"}",//YES
+		"{\"version\":\"2.1\"}",//NO
+		" {  \"version\"  :  \"2.0\"  }",//YES
+		"{\"version\":\"2.0\",}",//NO
+		"{\"version\":\"2.0\" \"test\":\"t\"}",//NO
+		"{\"version\":\"2.0\",\"method\":}",//NO
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func\"}",//YES
+		"{\"version\":\"2.0\",\"method\":\"ns2:class:func\"}",//NO
+		"{\"version\":\"2.0\",\"method\":\"ns:class2:func\"}",//NO
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func2\"}",//NO
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func\",\"method\":\"\"}",//NO
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func\",\"id\":0}",//YES
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func\",\"id\":\"123\"}",//YES
+		"{\"version\":\"2.0\",\"method\":123}",//NO
+		"{\"version\":\"2.0\",\"test\":123}",//YES
+		"{\"version\":\"2.0\",\"test\":123, \"test\":123 }",//YES
+		"{\"version\":\"2.0\",\"test\":123 ,\"test\":123 }",//YES
+		NULL
+	};
+#else
+	const char* t[] = {
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func\",\"params\":[]}",//YES
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func\",\"params\": [] }",//YES
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func1\",\"params\": [-123] }",//YES
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func1\",\"params\": [\"123\"] }",//NG
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func2\",\"params\": [ 1 , 456 ] }",//YES
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func2\",\"params\": [ 123 , 456 a] }",//NG
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func2\",\"params\": [ 123a] }",//NG
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func2\",\"params\": [ 123,456] }",//OK
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func2\",\"params\": [123,456] }",//YES
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func3\",\"params\": [123] }",//YES
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func3\",\"params\": [\"123\"] }",//NG
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func4\",\"params\": [ 123 , 456 ] }",//YES
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func4\",\"params\": [ 123 , 456 a] }",//NG
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func4\",\"params\": [ 123a] }",//NG
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func4\",\"params\": [ 123,456] }",//OK
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func5\",\"params\": [123, \"abc\" , \"abc\"] }",//OK
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func6\",\"params\": [\"01234567890123456789012\"] }",//OK
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func6\",\"params\": [1] }",//NG
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func8\",\"params\": [\"012345678901234567\",1,1] }",//OK
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func8\",\"params\": [\"012345678901234567\",1] }",//OK
+		"{\"version\":\"2.0\",\"method\":\"ns:class:func7\",\"params\": [\"012345678901234567\",1] }",//OK
+		"{\"version\":\"2.0\",\"method\":\"ns:class:f10\",\"params\": [\"01234567890123\",22,33] }",//OK
+		"{\"version\":\"2.0\",\"method\":\"ns:class:f11\",\"params\": [ 0 , 1 ,2,3] }",//OK
+		"{\"version\":\"2.0\",\"method\":\"ns:class:f11\",\"params\": [ 15 , 1 ,2,3a] }",//NG
+		NULL
+	};
+#endif
+	int i;
+
+	for (i = 0;t[i]!=NULL; i++){
+		NyLPC_cJsonRpcParser_initialize(&inst, test_def_array);
+		NyLPC_cJsonRpcParser_initParser(&inst, &ret);
+		NyLPC_cJsonRpcParser_putText(&inst, t[i], strlen(t[i]));
+	}
+	printf("end\n");
+	return;
+
+}
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/http/json/NyLPC_cJsonRpcParser.h	Tue Jun 10 03:30:41 2014 +0000
@@ -0,0 +1,251 @@
+#ifndef NYLPC_CJSONRPCPARSER_H_
+#define NYLPC_CJSONRPCPARSER_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "NyLPC_stdlib.h"
+
+/** 型定義*/
+union NyLPC_TJsonRpcParserResult;
+
+/**
+ * RPC関数ハンドラ型です。
+ * @param
+ */
+typedef NyLPC_TBool (*NyLPC_TJsonRpcHandler)(const union NyLPC_TJsonRpcParserResult* i_rpc,void* i_param);
+
+/**
+ * JSON RPC定義テーブルの一要素。
+ * メソッド名とパラメータパターンのセットを定義します。
+ * この構造体は配列としてNyLPC_TJsonRpcFunctionTableから参照されます。
+ */
+struct NyLPC_TJsonRpcMethodDef
+{
+	/**
+	 * 関数名
+	 */
+	const char* name;
+	/**
+	 * パラメータパターン
+	 * <ul>
+	 * <li>s - 文字列</li>
+	 * <li>i - signed int32</li>
+	 * <li>s - unsigned int32</li>
+	 * </ul>
+	 */
+	const char* param_patt;
+	/**
+	 * 外部のDispatch関数で使われるRPC関数ハンドラ。
+	 */
+	NyLPC_TJsonRpcHandler handler;
+};
+
+
+/**
+ * JsonRPCクラスの定義テーブル。
+ * JsonRPCは、 [namespace]::[]
+ */
+struct NyLPC_TJsonRpcClassDef
+{
+	const char* names_pace;
+	const char* class_name;
+	const struct NyLPC_TJsonRpcMethodDef* functions;
+};
+
+
+
+
+
+#define NyLPC_TJsonRpcParserResult_TYPE_UNKNOWN	0
+#define NyLPC_TJsonRpcParserResult_TYPE_RESULT	1
+#define NyLPC_TJsonRpcParserResult_TYPE_METHOD	2
+
+/** NyLPC_TJsonRpcParserResultが格納できる引数の最大数。パラメータの最大数に等しくなります。*/
+#define NyLPC_TJsonRpcParserResult_NUMBER_OF_PARAM_INDEX 16
+/**
+ * NyLPC_TJsonRpcParserResultが格納できるパラメータの総バイト数。
+ * (文字数+1)+(uint32|int32)*4+uint8の合計値です。
+ */
+#define NyLPC_TJsonRpcParserResult_PARAM_BUF 128
+
+/**
+ * JSONRPC構文のパース結果を格納します。
+ * 開発メモ
+ * 更新する場合は、param_indexまでの構造体のレイアウトを破壊しないようにしてください。
+ */
+union NyLPC_TJsonRpcParserResult
+{
+	NyLPC_TUInt8 	type;				//タイプ
+	/** この構造体は type==NyLPC_TJsonRpcParserResult_TYPE_METHODのときに有効です。*/
+	struct{
+		NyLPC_TUInt8 	_type;			//タイプ
+		NyLPC_TUInt8 	func_number;	//確定した関数番号。
+		NyLPC_TUInt8 	_padding[2];	//パディング
+		NyLPC_TInt32 	id;				//idパラメータの値
+		NyLPC_TChar		param_buf[NyLPC_TJsonRpcParserResult_PARAM_BUF];
+		NyLPC_TUInt8	param_index[NyLPC_TJsonRpcParserResult_NUMBER_OF_PARAM_INDEX];
+		/** 関数の含まれるクラスへのポインタ。*/
+		const struct NyLPC_TJsonRpcClassDef* class_def;
+	}method;
+	struct{
+		NyLPC_TUInt8 	_type;			//タイプ
+		NyLPC_TUInt8 	_padding[3];	//パディング
+		NyLPC_TInt32 	id;				//idパラメータの値
+		NyLPC_TChar		param_buf[NyLPC_TJsonRpcParserResult_PARAM_BUF];
+		NyLPC_TUInt8	param_index[NyLPC_TJsonRpcParserResult_NUMBER_OF_PARAM_INDEX];
+	}result;
+	struct{
+		NyLPC_TUInt8 	_type;		//タイプ
+		NyLPC_TInt8 	_padding[3];//
+		NyLPC_TInt32 	_id;		//idパラメータの値
+		NyLPC_TChar		param_buf[NyLPC_TJsonRpcParserResult_PARAM_BUF];
+		NyLPC_TUInt8	param_index[NyLPC_TJsonRpcParserResult_NUMBER_OF_PARAM_INDEX];
+	}raw;
+};
+/**
+ * Resultに格納される結果がハンドラを持っているかを返します。
+ */
+#define NyLPC_TJsonRpcParserResult_hasMethodHandler(i_struct) ((i_struct)->method.class_def->functions[(i_struct)->method.func_number].handler!=NULL)
+/**
+ * Resultに含まれるハンドラを呼び出します。
+ * @param i_struct
+ * Result構造体
+ * @param i_param
+ * ハンドラに引き渡すパラメータ
+ * @return
+ * FALSEの場合、ループを終了してください。
+ */
+#define NyLPC_TJsonRpcParserResult_callMethodHandler(i_struct,i_param) (i_struct)->method.class_def->functions[(i_struct)->method.func_number].handler((i_struct),(i_param))
+
+/**
+ * i_idx番目のパラメータをuint32としてo_valへ取り出します。
+ */
+NyLPC_TBool NyLPC_TJsonRpcParserResult_getUInt32(const union NyLPC_TJsonRpcParserResult* i_struct, NyLPC_TInt16 i_idx, NyLPC_TUInt32* o_val);
+/**
+ * i_idx番目のパラメータをint32としてo_valへ取り出します。
+ */
+NyLPC_TBool NyLPC_TJsonRpcParserResult_getInt32(const union NyLPC_TJsonRpcParserResult* i_struct, NyLPC_TInt16 i_idx, NyLPC_TInt32* o_val);
+/**
+ * i_idx番目のパラメータをchar[]としてo_valへ取り出します。
+ */
+NyLPC_TBool NyLPC_TJsonRpcParserResult_getStr(const union NyLPC_TJsonRpcParserResult* i_struct, NyLPC_TInt16 i_idx, const NyLPC_TChar** o_val);
+/**
+ * i_idx番目のパラメータをuint8としてo_valへ取り出します。
+ */
+NyLPC_TBool NyLPC_TJsonRpcParserResult_getByte(const union NyLPC_TJsonRpcParserResult* i_struct, NyLPC_TInt16 i_idx, NyLPC_TUInt8* o_val);
+
+/********************************************************************************
+ *
+ * NyLPC_TcJsonRpcParser
+ *
+ ********************************************************************************/
+/**
+ * JSONRPCの型定義定数です。
+ */
+#define NyLPC_cJsonRpcParser_TYPE_INT32		'd'
+#define NyLPC_cJsonRpcParser_TYPE_UINT32	'u'
+#define NyLPC_cJsonRpcParser_TYPE_STRING	's'
+#define NyLPC_cJsonRpcParser_TYPE_BYTE		'b'
+
+/**
+* JsonRPCメッセージをパースします。パース出来るメッセージは以下の通りです。
+* クラスは、RPC関数定義テーブルに従ってメッセージを分析し、テーブルに存在する関数のみを返却することができます。
+* <p>
+* メッセージ形式
+* <pre>
+* METHOD:
+* {"method":METHOD,"version":VERSION,"params":PARAMS,"id":ID}
+* METHOD VERSION as string
+* ID as uint32
+* PARAMS as Array of (string|uint32|int32)
+* </pre>
+* </p>
+*/
+typedef struct NyLPC_TcJsonRpcParser NyLPC_TcJsonRpcParser_t;
+
+
+
+
+/** パーサの状態値*/
+typedef NyLPC_TUInt8 NyLPC_TcJsonRpcParser_TStatus;
+
+#define NyLPC_TcJsonRpcParser_ST_START			0x01	//開始ブランケット受信待ち
+#define NyLPC_TcJsonRpcParser_ST_END			0x02	//終了受信済
+#define NyLPC_TcJsonRpcParser_ST_ERROR			0x03	//エラー発生
+#define NyLPC_TcJsonRpcParser_ST_NAME_Q			0x04	//名前クオート受信待ち
+#define NyLPC_TcJsonRpcParser_ST_NAME_STR		0x05	//名前受信中
+#define NyLPC_TcJsonRpcParser_ST_NV_SEP			0x06	//名前と値のセパレータ待ち
+#define NyLPC_TcJsonRpcParser_ST_VAL			0x07	//値開始待ち
+#define NyLPC_TcJsonRpcParser_ST_VAL_STR		0x08	//文字列受信
+#define NyLPC_TcJsonRpcParser_ST_VAL_UINT		0x09	//UINT受信中
+#define NyLPC_TcJsonRpcParser_ST_VAL_INT		0x10	//INT受信中
+#define NyLPC_TcJsonRpcParser_ST_NEXT			0x11	//次のNAMEもしくは終了ブランケット
+#define NyLPC_TcJsonRpcParser_ST_PARAMS			0x12	//PARAM要素パース中
+
+
+
+/** NyLPC_TcJsonRpcParserの定数値です。 字句解析ワークメモリの長さ。256未満8*n-1の数を指定してください。 */
+#define NyLPC_TcJsonRpcParser_WORK_MAX 47
+
+/**
+ * クラス構造体です。
+ */
+struct NyLPC_TcJsonRpcParser
+{
+	const struct NyLPC_TJsonRpcClassDef** _class_def;
+	union{
+		struct{
+			NyLPC_TChar 	buf[NyLPC_TcJsonRpcParser_WORK_MAX];	//文字解析メモリ
+			NyLPC_TUInt8 	n;										//字句解析の文字数
+		}str;
+		struct{
+			NyLPC_TInt32 v;
+			NyLPC_TInt8	s;
+		}int32;
+		NyLPC_TUInt32 uint32;
+	}_work;
+	NyLPC_TcJsonRpcParser_TStatus 	_st;		//パーサステータス
+	NyLPC_TUInt8 	_pst;		//PARAMS解析ステータス
+	NyLPC_TUInt8	_name_id;	//解析中のNAME_ID
+	NyLPC_TUInt8	_pcounter;	//パラメタ解析に使うワークカウンタ
+	union NyLPC_TJsonRpcParserResult* _result;//出力格納先
+};
+
+
+
+
+
+
+/**
+ * インスタンスを初期化します。
+ * @param i_class_def
+ * クラステーブルの配列です。NULLで終端します。
+ */
+void NyLPC_cJsonRpcParser_initialize(
+	NyLPC_TcJsonRpcParser_t* i_inst,
+	const struct NyLPC_TJsonRpcClassDef** i_class_def);
+
+#define NyLPC_cJsonRpcParser_finalize(i)
+/**
+ * パーサの状態を初期化します。
+ * @param i_result
+ * パース結果の出力先構造体のアドレスです。
+ */
+void NyLPC_cJsonRpcParser_initParser(NyLPC_TcJsonRpcParser_t* i_inst, union NyLPC_TJsonRpcParserResult* i_result);
+/**
+ * パーサに文字列を入力します。入力後は、NyLPC_cJsonRpcParser_getStatusでパーサの状態をチェックしてください。
+ */
+void NyLPC_cJsonRpcParser_putChar(NyLPC_TcJsonRpcParser_t* i_inst, char i_c);
+
+#define NyLPC_cJsonRpcParser_getStatus(i) ((i)->_st)
+/** クラス定義テーブルを返します。*/
+#define NyLPC_cJsonRpcParser_getClassDef(i) ((i)->_class_def)
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* NYLPC_CJSONRPCPARSER4_H_ */
+
--- a/core/include/NyLPC_http.h	Thu May 29 16:07:14 2014 +0000
+++ b/core/include/NyLPC_http.h	Tue Jun 10 03:30:41 2014 +0000
@@ -42,6 +42,7 @@
 #include "../http/NyLPC_cHttpBasicBodyParser.h"
 #include "../http/NyLPC_cHttpBodyParser.h"
 #include "../http/NyLPC_cBase64.h"
+#include "../http/json/NyLPC_cJsonRpcParser.h"
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
--- a/core/include/NyLPC_net.h	Thu May 29 16:07:14 2014 +0000
+++ b/core/include/NyLPC_net.h	Tue Jun 10 03:30:41 2014 +0000
@@ -45,6 +45,7 @@
 #include "../net/httpd/mod/NyLPC_cModRomFiles.h"
 #include "../net/httpd/mod/NyLPC_cModUrl.h"
 #include "../net/httpd/mod/NyLPC_cModUPnPDevice.h"
+#include "../net/httpd/mod/NyLPC_cModJsonRpc.h"
 
 #include "../net/httpcl/NyLPC_cHttpClient.h"
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/net/httpd/mod/NyLPC_cModJsonRpc.c	Tue Jun 10 03:30:41 2014 +0000
@@ -0,0 +1,112 @@
+#include "NyLPC_cModJsonRpc.h"
+
+
+
+
+void NyLPC_cModJsonRpc_initialize(NyLPC_TcModJsonRpc_t* i_inst,const NyLPC_TChar* i_ref_root_path,const struct NyLPC_TJsonRpcClassDef** i_class_tbl)
+{
+	NyLPC_cModWebSocket_initialize(&i_inst->super,i_ref_root_path);
+	NyLPC_cJsonRpcParser_initialize(&i_inst->_rpc_parser,i_class_tbl);
+}
+void NyLPC_cModJsonRpc_finalize(NyLPC_TcModJsonRpc_t* i_inst)
+{
+	NyLPC_cJsonRpcParser_finalize(&i_inst->_rpc_parser);
+	NyLPC_cModWebSocket_finalize(&i_inst->super);
+}
+#define NyLPC_cModJsonRpc_canHandle(i,c) NyLPC_cModWebSocket_canHandle(&((i)->super),(c))
+
+#define NyLPC_cModJsonRpc_close(i,t) NyLPC_cModWebSocket_close(&((i)->super),(t))
+
+
+NyLPC_TBool NyLPC_cModJsonRpc_execute(NyLPC_TcModJsonRpc_t* i_inst,NyLPC_TcHttpdConnection_t* i_connection)
+{
+	//executeで強制初期化
+	NyLPC_cJsonRpcParser_initParser(&i_inst->_rpc_parser,&i_inst->_result);
+	return NyLPC_cModWebSocket_execute(&((i_inst)->super),i_connection);
+}
+
+static NyLPC_TInt32 readHandler(void* i_param,NyLPC_TChar i_c)
+{
+	NyLPC_TcModJsonRpc_t* inst=(NyLPC_TcModJsonRpc_t*)i_param;
+	NyLPC_cJsonRpcParser_putChar(&inst->_rpc_parser,i_c);
+	switch(NyLPC_cJsonRpcParser_getStatus(&(inst->_rpc_parser))){
+	case NyLPC_TcJsonRpcParser_ST_END:
+		return 0;//終端到達。中断
+	case NyLPC_TcJsonRpcParser_ST_ERROR:
+		return -1;//エラー
+	default:
+		return 1;//次の文字をリクエスト
+	}
+}
+
+
+NyLPC_TBool NyLPC_cModJsonRpc_processRpcMessage(NyLPC_TcModJsonRpc_t* i_inst)
+{
+	//終了した場合のみパーサステータスを初期化。
+	switch(NyLPC_cJsonRpcParser_getStatus(&i_inst->_rpc_parser)){
+	case NyLPC_TcJsonRpcParser_ST_END:
+		NyLPC_cJsonRpcParser_initParser(&i_inst->_rpc_parser,&i_inst->_result);
+		break;
+	case NyLPC_TcJsonRpcParser_ST_ERROR:
+		//パーサがエラーを検出してたら何もしない。
+		return NyLPC_TBool_FALSE;
+	}
+	//コールバックハンドラで受信
+	if(NyLPC_cModWebSocket_readCB(&(i_inst->super),readHandler,i_inst)<0){
+		return NyLPC_TBool_FALSE;
+	}
+	return NyLPC_TBool_TRUE;
+}
+
+const union NyLPC_TJsonRpcParserResult* NyLPC_cModJsonRpc_getMessage(NyLPC_TcModJsonRpc_t* i_inst)
+{
+	return (NyLPC_cJsonRpcParser_getStatus(&i_inst->_rpc_parser)!=NyLPC_TcJsonRpcParser_ST_END)?NULL:(&i_inst->_result);
+}
+
+NyLPC_TBool NyLPC_cModJsonRpc_putRawMessageV(NyLPC_TcModJsonRpc_t* i_inst,const NyLPC_TChar* i_fmt,va_list i_args)
+{
+	return NyLPC_cModWebSocket_writeFormatV(&i_inst->super,i_fmt,i_args);
+}
+NyLPC_TBool NyLPC_cModJsonRpc_putRawMessage(NyLPC_TcModJsonRpc_t* i_inst,const NyLPC_TChar* i_fmt,...)
+{
+	NyLPC_TBool r;
+	va_list a;
+	va_start(a,i_fmt);
+	r=NyLPC_cModWebSocket_writeFormatV(&i_inst->super,i_fmt,a);
+	va_end(a);
+	return r;
+}
+
+
+
+/**
+ * @param i_params_fmt
+ * パラメータ部のフォーマット文字列です。NyLPC_cFormatWriterと同等の構文を使用できます。
+ * ここで指定した書式文字列は、"そのまま"パラメータ部に表示されます。文字列を返す場合は、次のように\"でエスケープしてください。
+ * '0,1,2,-1,\"result\",3'
+ */
+NyLPC_TBool NyLPC_cModJsonRpc_putResult(NyLPC_TcModJsonRpc_t* i_inst,NyLPC_TUInt32 i_id,NyLPC_TInt32 i_result,const NyLPC_TChar* i_params_fmt,...)
+{
+	NyLPC_TBool r;
+	va_list a;
+	NyLPC_TInt16 l;
+
+	//書き込み文字数の事前計算
+	va_start(a,i_params_fmt);
+	l=NyLPC_cModWebSocket_testFormat(&i_inst->super,"{\"result\":%d,\"params\":[",i_result);
+	l+=NyLPC_cModWebSocket_testFormatV(&i_inst->super,i_params_fmt,a);
+	l+=NyLPC_cModWebSocket_testFormat(&i_inst->super,"],\"id\":%d}",i_id);
+	va_end(a);
+
+	//バルク書き込み
+	va_start(a,i_params_fmt);
+	NyLPC_cModWebSocket_startBulkWrite(&i_inst->super,l);
+	r=NyLPC_cModWebSocket_writeBulkFormat(&i_inst->super,"{\"result\":%d,\"params\":[",i_result);
+	r=r&&NyLPC_cModWebSocket_writeBulkFormatV(&i_inst->super,i_params_fmt,a);
+	r=r&&NyLPC_cModWebSocket_writeBulkFormat(&i_inst->super,"],\"id\":%d}",i_id);
+	r=r&&NyLPC_cModWebSocket_endBulkWrite(&i_inst->super);
+	va_end(a);
+	return r;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/net/httpd/mod/NyLPC_cModJsonRpc.h	Tue Jun 10 03:30:41 2014 +0000
@@ -0,0 +1,84 @@
+/*********************************************************************************
+ * PROJECT: MiMic
+ * --------------------------------------------------------------------------------
+ *
+ * This file is part of MiMic
+ * Copyright (C)2011 Ryo Iizuka
+ *
+ * MiMic is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * For further information please contact.
+ *	http://nyatla.jp/
+ *	<airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
+ *
+ *********************************************************************************/
+#ifndef NYLPC_CMODJSONRPC_H_
+#define NYLPC_CMODJSONRPC_H_
+#include "NyLPC_http.h"
+#include "../NyLPC_cHttpdConnection.h"
+#include "NyLPC_cModWebSocket.h"
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * WebSocketストリームからJSONRPC電文を取り込むモジュールです。
+ */
+typedef struct NyLPC_TcModJsonRpc NyLPC_TcModJsonRpc_t;
+
+
+/**
+ * クラス構造体
+ */
+struct NyLPC_TcModJsonRpc
+{
+	NyLPC_TcModWebSocket_t super;
+	NyLPC_TcJsonRpcParser_t _rpc_parser;
+	union NyLPC_TJsonRpcParserResult _result;
+};
+
+
+void NyLPC_cModJsonRpc_initialize(NyLPC_TcModJsonRpc_t* i_inst,const NyLPC_TChar* i_ref_root_path,const struct NyLPC_TJsonRpcClassDef** i_class_tbl);
+void NyLPC_cModJsonRpc_finalize(NyLPC_TcModJsonRpc_t* i_inst);
+#define NyLPC_cModJsonRpc_canHandle(i,c) NyLPC_cModWebSocket_canHandle(&((i)->super),(c))
+#define NyLPC_cModJsonRpc_close(i,t) NyLPC_cModWebSocket_close(&((i)->super),(t))
+
+
+NyLPC_TBool NyLPC_cModJsonRpc_execute(NyLPC_TcModJsonRpc_t* i_inst,NyLPC_TcHttpdConnection_t* i_connection);
+
+/**
+ * Execute実行後に繰り返し実行できます。
+ * trueを返却した場合は、NyLPC_cModJsonRpc_getRpcCall関数で結果を取得できるか調べてください。
+ * @return
+ * JSONRPCの処理を継続して行えるかを返します。
+ * falseの場合、JSONRPCの構文解析は失敗し、Websocketは閉じられます。Websocketの受信ループを終了してください。
+ */
+NyLPC_TBool NyLPC_cModJsonRpc_processRpcMessage(NyLPC_TcModJsonRpc_t* i_inst);
+
+/**
+ * JSONRPCの構文解析結果を返します。
+ * @return
+ * JSONRPC電文が確定した場合、結果を格納した構造体を返します。構造体の有効期限は、次回にNyLPC_cModJsonRpc_processRpcMessageを実行するまでです。
+ * NULLを返した場合は、引き続きNyLPC_cModJsonRpc_processRpcMessageを実行する必要があります。
+ */
+const union NyLPC_TJsonRpcParserResult* NyLPC_cModJsonRpc_getMessage(NyLPC_TcModJsonRpc_t* i_inst);
+
+NyLPC_TBool NyLPC_cModJsonRpc_putResult(NyLPC_TcModJsonRpc_t* i_inst,NyLPC_TUInt32 i_id,NyLPC_TInt32 i_result,const NyLPC_TChar* i_params_fmt,...);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* NYLPC_CMODJSONRPC_H_ */
+
--- a/core/net/httpd/mod/NyLPC_cModWebSocket.c	Thu May 29 16:07:14 2014 +0000
+++ b/core/net/httpd/mod/NyLPC_cModWebSocket.c	Tue Jun 10 03:30:41 2014 +0000
@@ -467,6 +467,86 @@
 	return;
 }
 
+
+/**
+ * 受信データをコールバック関数に通知するNyLPC_cModWebSocket_readです。
+ * @return
+ * n>0:データ受信
+ * 0  :タイムアウト。コネクションの状態は変化しない。
+ * -1 :エラー コネクションはNyLPC_TcModWebSocket_ST_CLOSEDへ遷移する。
+ */
+NyLPC_TInt16 NyLPC_cModWebSocket_readCB(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TcModWebSocket_onRreadCB i_cb,void* i_cb_param)
+{
+	const NyLPC_TUInt8* rx;
+	NyLPC_TInt32 rs,rd,i;
+	//ストリームの状態を更新する。
+	NyLPC_cModWebSocket_update(i_inst,HTTP_TIMEOUT);
+
+	switch(i_inst->_payload_st)
+	{
+	case NyLPC_TcModWebSocket_ST_READ_PAYLOAD:
+		break;//処理継続
+	case NyLPC_TcModWebSocket_ST_START_PAYLOAD:
+		//タイムアウト扱い
+		return 0;
+	default:
+		return -1;
+	}
+	//読み出し可能なデータをパース
+	rs=NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx,HTTP_TIMEOUT);
+	if(rs<=0){
+		if(rs<0){
+			//Error
+			NyLPC_OnErrorGoto(Error);
+		}
+		//Timeout
+		goto Timeout;
+	}
+	rd=0;//読みだしたバイト数
+	//アンマスク
+	if(NyLPC_TUInt8_isBitOn(i_inst->_frame_flags_bits,FLAGS_MASK_BIT)){
+		//マスク有の時
+		for(i=0;i<rs;i++){
+			rd++;
+			switch(i_cb(i_cb_param,rx[i]^i_inst->_frame_mask[(i_inst->payload_ptr+i)%4])){
+			case 1:
+				continue;
+			case 0:
+				break;
+			default:
+				NyLPC_OnErrorGoto(Error);
+			}
+		}
+	}else{
+		//マスクなしの時
+		for(i=0;i<rs;i++){
+			rd++;
+			switch(i_cb(i_cb_param,rx[i])){
+			case 1:
+				continue;
+			case 0:
+				break;
+			default:
+				NyLPC_OnErrorGoto(Error);
+			}
+		}
+	}
+	//読取位置を移動
+	NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),rd);
+	i_inst->payload_ptr+=rd;
+	if(i_inst->payload_size==i_inst->payload_ptr){
+		i_inst->_payload_st=NyLPC_TcModWebSocket_ST_START_PAYLOAD;
+	}
+	return rd;
+	//処理されなければエラー
+Error:
+	NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection);
+	i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED;
+	return -1;
+Timeout:
+	return 0;
+}
+
 /**
  * @return
  * n>0:データ受信
@@ -578,10 +658,11 @@
 	return NyLPC_TBool_FALSE;
 }
 
-
+#ifndef va_copy
+#    define va_copy(dest, src) ((dest) = (src))
+#endif
 
-
-NyLPC_TBool NyLPC_cModWebSocket_writeFormat(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,...)
+NyLPC_TBool NyLPC_cModWebSocket_writeFormatV(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,va_list args)
 {
 	NyLPC_TInt16 l;
 	va_list a;
@@ -589,19 +670,16 @@
 	NyLPC_cModWebSocket_update(i_inst,0);
 
 	//書式文字列の長さを計算
-	va_start(a,i_fmt);
+	va_copy(a,args);
 	l=NyLPC_cFormatWriter_length(i_fmt,a);
 	va_end(a);
 	if(!NyLPC_cModWebSocket_writePayloadHeader(i_inst,l)){
 		//CLOSE
 		NyLPC_OnErrorGoto(Error);
 	}
-	va_start(a,i_fmt);
-	if(!NyLPC_cFormatWriter_print(fmt_handler,NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),i_fmt,a)){
-		va_end(a);
+	if(!NyLPC_cFormatWriter_print(fmt_handler,NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),i_fmt,args)){
 		NyLPC_OnErrorGoto(Error);
 	}
-	va_end(a);
 	NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection));
 	return NyLPC_TBool_TRUE;
 Error:
@@ -610,6 +688,16 @@
 	return NyLPC_TBool_FALSE;
 }
 
+NyLPC_TBool NyLPC_cModWebSocket_writeFormat(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,...)
+{
+	NyLPC_TBool r;
+	va_list a;
+	va_start(a,i_fmt);
+	r=NyLPC_cModWebSocket_writeFormatV(i_inst,i_fmt,a);
+	va_end(a);
+	return r;
+}
+
 
 
 
@@ -647,3 +735,73 @@
 	//切断
 	NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection);
 }
+
+
+NyLPC_TInt16 NyLPC_cModWebSocket_testFormatV(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,va_list args)
+{
+	return NyLPC_cFormatWriter_length(i_fmt,args);
+}
+NyLPC_TInt16 NyLPC_cModWebSocket_testFormat(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,...)
+{
+	NyLPC_TInt16 r;
+	va_list a;
+	va_start(a,i_fmt);
+	r=NyLPC_cFormatWriter_length(i_fmt,a);
+	va_end(a);
+	return r;
+}
+
+
+NyLPC_TBool NyLPC_cModWebSocket_startBulkWrite(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TInt16 i_len)
+{
+	//ストリームの状態を更新する。
+	NyLPC_cModWebSocket_update(i_inst,0);
+	//ペイロードヘッダの出力
+	if(!NyLPC_cModWebSocket_writePayloadHeader(i_inst,i_len)){
+		//CLOSE
+		NyLPC_OnErrorGoto(Error);
+	}
+	return NyLPC_TBool_TRUE;
+Error:
+	NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection);
+	i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED;
+	return NyLPC_TBool_FALSE;
+}
+/**
+ * バルク書き込みを終了します。
+ * この関数をコールする前に、startBulkWrite関数のi_lenで指定した大きさのデータを入力し終えている必要があります。
+ * 過不足があった場合、関数は失敗するか、WebSocketセッションが破壊されます。
+ */
+NyLPC_TBool NyLPC_cModWebSocket_endBulkWrite(NyLPC_TcModWebSocket_t* i_inst)
+{
+	if(i_inst->_payload_st==NyLPC_TcModWebSocket_ST_CLOSED){
+		return NyLPC_TBool_FALSE;
+	}
+	//送信サイズ確認?
+	NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection));
+	return NyLPC_TBool_TRUE;
+}
+
+NyLPC_TBool NyLPC_cModWebSocket_writeBulkFormatV(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,va_list args)
+{
+	if(i_inst->_payload_st==NyLPC_TcModWebSocket_ST_CLOSED){
+		return NyLPC_TBool_FALSE;
+	}
+	if(!NyLPC_cFormatWriter_print(fmt_handler,NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),i_fmt,args)){
+		NyLPC_OnErrorGoto(Error);
+	}
+	return NyLPC_TBool_TRUE;
+Error:
+	NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection);
+	i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED;
+	return NyLPC_TBool_FALSE;
+}
+NyLPC_TBool NyLPC_cModWebSocket_writeBulkFormat(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,...)
+{
+	NyLPC_TBool ret;
+	va_list a;
+	va_start(a,i_fmt);
+	ret=NyLPC_cModWebSocket_writeBulkFormatV(i_inst,i_fmt,a);
+	va_end(a);
+	return ret;
+}
--- a/core/net/httpd/mod/NyLPC_cModWebSocket.h	Thu May 29 16:07:14 2014 +0000
+++ b/core/net/httpd/mod/NyLPC_cModWebSocket.h	Tue Jun 10 03:30:41 2014 +0000
@@ -30,7 +30,7 @@
 #include "NyLPC_http.h"
 #include "../NyLPC_cHttpdConnection_protected.h"
 #include "../NyLPC_cHttpdUtils.h"
-#include "NyLPC_net.h"
+#include "NyLPC_cModRomFiles.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -85,6 +85,16 @@
 	NyLPC_TcHttpdConnection_t* _ref_connection;
 };
 
+
+/**
+ * NyLPC_cModWebSocket_readCB関数のコールバックハンドラです。
+ * @return
+ * -1    :エラーが発生したことを通知します。NyLPC_cModWebSocket_readCBは負数を返してクローズします。
+ *  0    :読出しの中断を通知します。NyLPC_cModWebSocket_readCBは読み取ったデータ数を記録して正常終了します。
+ *  1    :読出しの継続を通知します。NyLPC_cModWebSocket_readCBは継続してデータを通知します。
+ */
+typedef NyLPC_TInt32 (*NyLPC_TcModWebSocket_onRreadCB)(void* i_param,NyLPC_TChar i_c);
+
 /**
  * コンストラクタ。
  */
@@ -110,6 +120,17 @@
 NyLPC_TBool NyLPC_cModWebSocket_canRead(const NyLPC_TcModWebSocket_t* i_inst);
 
 
+/**
+ * 受信データをコールバック関数に通知するNyLPC_cModWebSocket_readです。
+ * @param i_cb
+ * NyLPC_TcModWebSocket_onRreadCBのi_paramに設定する数値です。
+ * @return
+ * n>0:データ受信
+ * 0  :タイムアウト。コネクションの状態は変化しない。
+ * -1 :エラー コネクションはNyLPC_TcModWebSocket_ST_CLOSEDへ遷移する。
+ */
+NyLPC_TInt16 NyLPC_cModWebSocket_readCB(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TcModWebSocket_onRreadCB i_cb,void* i_cb_param);
+
 
 /**
  * ストリームからデータを受信して、可能ならi_bufに最大i_buf_lenバイトのデータを受信します。
@@ -132,9 +153,34 @@
  * 書式文字列を出力します。
  */
 NyLPC_TBool NyLPC_cModWebSocket_writeFormat(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,...);
+NyLPC_TBool NyLPC_cModWebSocket_writeFormatV(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,va_list args);
 
 
 /**
+ * 書式文字列を出力した場合の文字数を返します。
+ * この関数は、startBulkWrite関数のi_lenパラメータに渡す値を計算するときに使います。
+ */
+NyLPC_TInt16 NyLPC_cModWebSocket_testFormatV(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,va_list args);
+NyLPC_TInt16 NyLPC_cModWebSocket_testFormat(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,...);
+
+/**
+ * バルク書き込みを開始します。
+ * バルク書き込みは、endBulkWrite関数をコールするまでにwriteBulk関数で入力されたデータを、1つのi_lenサイズのWebsocketパケットとして送信します。
+ * バルク書き込み中は、通常のwrite関数を使用することができません。
+ * @param i_len
+ * NyLPC_cModWebSocket_endBulkFormatでバルク書き込みを終了するまでに入力するデータサイズを指定します。
+ */
+NyLPC_TBool NyLPC_cModWebSocket_startBulkWrite(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TInt16 i_len);
+/**
+ * バルク書き込みを終了します。
+ * この関数をコールする前に、startBulkWrite関数のi_lenで指定した大きさのデータを入力し終えている必要があります。
+ * 過不足があった場合、WebSocketセッションが破壊されます。
+ */
+NyLPC_TBool NyLPC_cModWebSocket_endBulkWrite(NyLPC_TcModWebSocket_t* i_inst);
+NyLPC_TBool NyLPC_cModWebSocket_writeBulkFormatV(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,va_list args);
+NyLPC_TBool NyLPC_cModWebSocket_writeBulkFormat(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,...);
+
+/**
  * CLOSEパケットを送信してコネクションを閉じます。
  * この関数はデータ以外のパケットも処理します。
  * i_codeにはWebsocketのコード
--- a/core/net/httpd/mod/NyLPC_cModWebSocket_protected.h	Thu May 29 16:07:14 2014 +0000
+++ b/core/net/httpd/mod/NyLPC_cModWebSocket_protected.h	Tue Jun 10 03:30:41 2014 +0000
@@ -40,6 +40,8 @@
 
 void NyLPC_cModWebSocket_update(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TUInt32 i_time_out);
 
+
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */