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:
Fri Sep 13 06:38:16 2013 +0000
Parent:
56:d38b6ce8c63b
Child:
58:03b89038b21a
Commit message:
update mimic core r329;

Changed in this revision

core/NyLPC_cMiMicEnv.h Show annotated file Show diff for this revision Revisions of this file
core/NyLPC_cRingBuffer.c Show annotated file Show diff for this revision Revisions of this file
core/NyLPC_cRomPtrStream.c Show annotated file Show diff for this revision Revisions of this file
core/NyLPC_cStr.h Show annotated file Show diff for this revision Revisions of this file
core/NyLPC_stdlib.c Show annotated file Show diff for this revision Revisions of this file
core/flash/NyLPC_cOnchipFlashWriter.c Show annotated file Show diff for this revision Revisions of this file
core/http/NyLPC_cBase64.c Show annotated file Show diff for this revision Revisions of this file
core/http/NyLPC_cBase64.h Show annotated file Show diff for this revision Revisions of this file
core/http/NyLPC_cHttpBasicHeaderParser.c Show annotated file Show diff for this revision Revisions of this file
core/http/NyLPC_cHttpBasicHeaderParser.h Show annotated file Show diff for this revision Revisions of this file
core/http/NyLPC_cHttpBodyWriter.c Show annotated file Show diff for this revision Revisions of this file
core/http/NyLPC_cHttpHeaderWriter.c Show annotated file Show diff for this revision Revisions of this file
core/http/NyLPC_cHttpHeaderWriter.h Show annotated file Show diff for this revision Revisions of this file
core/http/NyLPC_cHttpStream.c 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/include/NyLPC_stdlib.h Show annotated file Show diff for this revision Revisions of this file
core/include/NyLPC_utils.h Show annotated file Show diff for this revision Revisions of this file
core/net/httpcl/NyLPC_cHttpClient.c Show annotated file Show diff for this revision Revisions of this file
core/net/httpcl/NyLPC_cHttpClient.h Show annotated file Show diff for this revision Revisions of this file
core/net/httpd/NyLPC_cHttpdConnection.c Show annotated file Show diff for this revision Revisions of this file
core/net/httpd/NyLPC_cHttpdConnection_protected.h Show annotated file Show diff for this revision Revisions of this file
core/net/httpd/mod/NyLPC_cModFileIoBaseClass.c Show annotated file Show diff for this revision Revisions of this file
core/net/httpd/mod/NyLPC_cModRomFiles.c 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/upnp/NyLPC_cSsdpSocket.c Show annotated file Show diff for this revision Revisions of this file
core/uip/NyLPC_cBaseSocket.c Show annotated file Show diff for this revision Revisions of this file
core/uip/NyLPC_cBaseSocket.h Show annotated file Show diff for this revision Revisions of this file
core/uip/NyLPC_cIPv4.c Show annotated file Show diff for this revision Revisions of this file
core/uip/NyLPC_cIPv4.h Show annotated file Show diff for this revision Revisions of this file
core/uip/NyLPC_cIPv4Config.h Show annotated file Show diff for this revision Revisions of this file
core/uip/NyLPC_cIPv4_typedef.h Show annotated file Show diff for this revision Revisions of this file
core/uip/NyLPC_cTcpListener.c Show annotated file Show diff for this revision Revisions of this file
core/uip/NyLPC_cTcpListener.h Show annotated file Show diff for this revision Revisions of this file
core/uip/NyLPC_cTcpSocket.c Show annotated file Show diff for this revision Revisions of this file
core/uip/NyLPC_cTcpSocket.h Show annotated file Show diff for this revision Revisions of this file
core/uip/NyLPC_cUipService.c Show annotated file Show diff for this revision Revisions of this file
core/uip/NyLPC_uip.c Show annotated file Show diff for this revision Revisions of this file
core/uip/NyLPC_uip.h Show annotated file Show diff for this revision Revisions of this file
core/utils/NyLPC_cFormatWriter.c Show annotated file Show diff for this revision Revisions of this file
core/utils/NyLPC_cFormatWriter.h Show annotated file Show diff for this revision Revisions of this file
core/utils/sha1/sha1.c Show annotated file Show diff for this revision Revisions of this file
core/utils/sha1/sha1.h Show annotated file Show diff for this revision Revisions of this file
--- a/core/NyLPC_cMiMicEnv.h	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/NyLPC_cMiMicEnv.h	Fri Sep 13 06:38:16 2013 +0000
@@ -13,7 +13,7 @@
 #endif /* __cplusplus */
 
 
-#define NyLPC_cMiMicEnv_VERSION "MiMic/1.4.52"
+#define NyLPC_cMiMicEnv_VERSION "MiMic/1.4.62"
 
 
 #ifdef __cplusplus
--- a/core/NyLPC_cRingBuffer.c	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/NyLPC_cRingBuffer.c	Fri Sep 13 06:38:16 2013 +0000
@@ -119,7 +119,7 @@
         }
         //右側の書込みサイズの計算
         rw=i_inst->bl-wo;
-        l=wsize<rw?wsize:rw;
+        l=(wsize<rw)?wsize:rw;
         //書込みポインタを設定
         p=(s+wo);
         for(i=l-1;i>=0;i--){
@@ -178,8 +178,8 @@
         NyLPC_cRingBuffer_dump(s);
         b=NyLPC_cRingBuffer_getReadPtr(s,&l);
         printf("readable:%d\n",l);
-        NyLPC_cRingBuffer_seekReadPtr(s,l>1?l-1:1);
-        printf("read:%d\n",l>1?l-1:1);
+        NyLPC_cRingBuffer_seekReadPtr(s,(l>1)?l-1:1);
+        printf("read:%d\n",(l>1)?l-1:1);
         NyLPC_cRingBuffer_dump(s);
     }
 
--- a/core/NyLPC_cRomPtrStream.c	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/NyLPC_cRomPtrStream.c	Fri Sep 13 06:38:16 2013 +0000
@@ -101,7 +101,7 @@
     NyLPC_Assert(inst->_rom!=NULL);
 
     size=inst->_rom_size-inst->_ed;     //残り長さ計算
-    psize=size>inst->_packet_size?inst->_packet_size:size;  //パケットサイズ計算
+    psize=(size>inst->_packet_size)?inst->_packet_size:size;    //パケットサイズ計算
     *o_buf_ptr=(inst->_rom+inst->_ed);  //現在位置を返す
     inst->_ed+=psize;//読出し位置更新
     return psize;
--- a/core/NyLPC_cStr.h	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/NyLPC_cStr.h	Fri Sep 13 06:38:16 2013 +0000
@@ -82,10 +82,16 @@
 */
 #define NyLPC_cStr_clear(i_inst) (i_inst)->l=0
 /**
-文字列が同一か返します。
-*/
+ * NULL terminated文字列が同一か返します。
+ */
 #define NyLPC_cStr_isEqual(i_inst,i_str) (strcmp(NyLPC_cStr_str(i_inst),(i_str))==0)
 /**
+ * NULL terminated文字列が同一か返します。
+ * 大文字小文字を区別しません。
+ */
+#define NyLPC_cStr_isEqualIgnoreCase(i_inst,i_str) (NyLPC_stricmp(NyLPC_cStr_str(i_inst),(i_str))==0)
+
+/**
  * 文字列を大文字にします。
  *
  *
--- a/core/NyLPC_stdlib.c	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/NyLPC_stdlib.c	Fri Sep 13 06:38:16 2013 +0000
@@ -149,7 +149,7 @@
      i = 0;
      do{
          v=(NyLPC_TInt8)(i_n % i_base);
-         o_out[i++] = v<10?(v+'0'):(v+'a'-10);
+         o_out[i++] = (v<10)?(v+'0'):(v+'a'-10);
      }while ((i_n /= i_base) > 0);
      if (sign < 0){
          o_out[i++] = '-';
@@ -164,7 +164,7 @@
     NyLPC_TInt8 v;
      do{
          v=(NyLPC_TInt8)(i_n % i_base);
-         o_out[i++] = v<10?(v+'0'):(v+'a'-10);
+         o_out[i++] = (v<10)?(v+'0'):(v+'a'-10);
      }while ((i_n /= i_base) > 0);
      o_out[i] = '\0';
      NyLPC_reverse(o_out);
@@ -180,7 +180,7 @@
      NyLPC_TInt8 v;
      do{
          v=(NyLPC_TInt8)(i_n % i_base);
-         o_out[i++] = v<10?(v+'0'):(v+'a'-10);
+         o_out[i++] = (v<10)?(v+'0'):(v+'a'-10);
      }while ((i_n /= i_base) > 0);
      while(i<i_digit){
          o_out[i++] = '0';
--- a/core/flash/NyLPC_cOnchipFlashWriter.c	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/flash/NyLPC_cOnchipFlashWriter.c	Fri Sep 13 06:38:16 2013 +0000
@@ -41,7 +41,7 @@
         //書込み可能サイズを計算
         free_size=256-s_padding;
         //書込みサイズを決定
-        wsize=free_size>size?size:free_size;
+        wsize=(free_size>size)?size:free_size;
         //Flashから一時RAMへ前方パディングを読む
         if(s_padding>0){
             memcpy(_work,fblock_addr,s_padding);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/http/NyLPC_cBase64.c	Fri Sep 13 06:38:16 2013 +0000
@@ -0,0 +1,52 @@
+/*
+ * NyLPC_cBase64.c
+ *
+ *  Created on: 2013/09/04
+ *      Author: nyatla
+ */
+
+#ifndef NYLPC_CBASE64_C_
+#define NYLPC_CBASE64_C_
+
+#include "NyLPC_cBase64.h"
+
+/**
+ * @param i_src
+ * @param length
+ * @param i_dest
+ * Base64文字列の出力領域. length/3*4+1の長さが必要。
+ */
+void NyLPC_cBase64_encode(const NyLPC_TChar* i_src,NyLPC_TUInt16 length,char* i_dest)
+{
+	const static char* B64CODE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+	NyLPC_TUInt16 s,d;
+	d=0;
+    for(s=0; s<(length-2); s+=3){
+    	i_dest[d++]=B64CODE[((0xfc&i_src[s+0])>>2)];
+		i_dest[d++]=B64CODE[((0x03&i_src[s+0])<<4)|((0xf0&i_src[s+1])>>4)];
+		i_dest[d++]=B64CODE[((0x0f&i_src[s+1])<<2)|((0xc0&i_src[s+2])>>6)];
+		i_dest[d++]=B64CODE[((0x3f&i_src[s+2])>>0)];
+    }
+	s=length-length%3;
+    switch(length%3){
+	case 1:
+    	i_dest[d++]=B64CODE[((0xfc&i_src[s+0])>>2)];
+		i_dest[d++]=B64CODE[((0x03&i_src[s+0])<<4)];
+		break;
+	case 2:
+    	i_dest[d++]=B64CODE[((0xfc&i_src[s+0])>>2)];
+		i_dest[d++]=B64CODE[((0x03&i_src[s+0])<<4)|((0xf0&i_src[s+1])>>4)];
+		i_dest[d++]=B64CODE[((0x0f&i_src[s+1])<<2)];
+		break;
+    }
+    //文字数
+    while(d%4!=0){
+    	i_dest[d++]='=';
+    }
+	i_dest[d]='\0';
+}
+
+
+
+#endif /* NYLPC_CBASE64_C_ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/http/NyLPC_cBase64.h	Fri Sep 13 06:38:16 2013 +0000
@@ -0,0 +1,29 @@
+/*
+ * NyLPC_cBase64.h
+ *
+ *  Created on: 2013/09/04
+ *      Author: nyatla
+ */
+
+#ifndef NYLPC_CBASE64_H_
+#define NYLPC_CBASE64_H_
+#include "NyLPC_stdlib.h"
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @param i_src
+ * @param length
+ * @param i_dest
+ * Base64文字列の出力領域. length/3*4+1の長さが必要。
+ */
+void NyLPC_cBase64_encode(const NyLPC_TChar* i_src,NyLPC_TUInt16 length,char* i_dest);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* NYLPC_CBASE64_H_ */
+
--- a/core/http/NyLPC_cHttpBasicHeaderParser.c	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/http/NyLPC_cHttpBasicHeaderParser.c	Fri Sep 13 06:38:16 2013 +0000
@@ -135,7 +135,7 @@
 void NyLPC_cHttpBasicHeaderParser_initialize(NyLPC_TcHttpBasicHeaderParser_t* i_inst,const struct NyLPC_TcHttpBasicHeaderParser_Handler* i_handler)
 {
     NyLPC_cStr_initialize(&(i_inst->_wsb),i_inst->_wsb_buf,NyLPC_cHttpBasicHeaderParser_SIZE_OF_WBS);
-    i_inst->_handler=(i_handler==NULL?&_default_handler:i_handler);
+    i_inst->_handler=((i_handler==NULL)?&_default_handler:i_handler);
 }
 
 /**
@@ -450,7 +450,18 @@
 
 static NyLPC_TcHttpBasicHeaderParser_ST parseMessage_Connection(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out)
 {
-
+    const static NyLPC_TUInt8 id[]={
+        NyLPC_THttpMessgeHeader_Connection_CLOSE,
+        NyLPC_THttpMessgeHeader_Connection_KEEPALIVE,
+        NyLPC_THttpMessgeHeader_Connection_UPGRADE,
+        NyLPC_THttpMessgeHeader_Connection_UNKNOWN
+    };
+    const static NyLPC_TChar* str[]={
+        "CLOSE",
+        "KEEP-ALIVE",
+        "UPGRADE"
+    };
+    NyLPC_TUInt8 i;
     //先頭のスペース除外
     if(NyLPC_cStr_len(&(i_inst->_wsb))==0){
         if(i_c==HTTP_SP){
@@ -463,13 +474,13 @@
     }else if(i_c==HTTP_LF){
         //大文字化
         NyLPC_cStr_toUpper(&(i_inst->_wsb));
-        //close?
-        if(NyLPC_cStr_isEqual(&(i_inst->_wsb),"CLOSE")){
-            o_out->connection=NyLPC_THttpMessgeHeader_Connection_CLOSE;
-        }else if(NyLPC_cStr_isEqual(&(i_inst->_wsb),"KEEP-ALIVE")){
-            o_out->connection=NyLPC_THttpMessgeHeader_Connection_KEEPALIVE;
-        }else{
-            o_out->connection=NyLPC_THttpMessgeHeader_Connection_UNKNOWN;
+        //Convert to ID
+        o_out->connection=NyLPC_THttpMessgeHeader_Connection_UNKNOWN;
+        for(i=0;id[i]!=NyLPC_THttpMessgeHeader_Connection_UNKNOWN;i++){
+            if(NyLPC_cStr_isEqual(&(i_inst->_wsb),str[i])){
+                o_out->connection=id[i];
+                break;
+            }
         }
         NyLPC_cStr_clear(&(i_inst->_wsb));
         return NyLPC_TcHttpBasicHeaderParser_ST_MSGHEAD;
@@ -638,6 +649,7 @@
                 i_inst->_rcode=500;
                 NyLPC_OnErrorGoto(Error);
             }
+            NyLPC_cStr_clear(&(i_inst->_wsb));
         }
         //カスタムヘッダ解析へ。
         return NyLPC_TcHttpBasicHeaderParser_ST_MSGPARAM;
--- a/core/http/NyLPC_cHttpBasicHeaderParser.h	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/http/NyLPC_cHttpBasicHeaderParser.h	Fri Sep 13 06:38:16 2013 +0000
@@ -97,6 +97,7 @@
 #define NyLPC_THttpMessgeHeader_Connection_NONE  ((NyLPC_THttpMessgeHeader_Connection)0x01)
 #define NyLPC_THttpMessgeHeader_Connection_CLOSE ((NyLPC_THttpMessgeHeader_Connection)0x02)
 #define NyLPC_THttpMessgeHeader_Connection_KEEPALIVE ((NyLPC_THttpMessgeHeader_Connection)0x03)
+#define NyLPC_THttpMessgeHeader_Connection_UPGRADE ((NyLPC_THttpMessgeHeader_Connection)0x04)
 #define NyLPC_THttpMessgeHeader_Connection_UNKNOWN ((NyLPC_THttpMessgeHeader_Connection)0x10)
 
 typedef NyLPC_TUInt8 NyLPC_THttpMessgeHeader_TransferEncoding;
--- a/core/http/NyLPC_cHttpBodyWriter.c	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/http/NyLPC_cHttpBodyWriter.c	Fri Sep 13 06:38:16 2013 +0000
@@ -210,7 +210,7 @@
 //      NyLPC_cHttpResponseWriter_setClose(&hw);
         body_len=100;
         NyLPC_cHttpHeaderWriter_setContentLength(&hw,body_len);
-        NyLPC_cHttpHeaderWriter_writeHeader(&hw,500);
+        NyLPC_cHttpHeaderWriter_writeResponseHeader(&hw,500);
         NyLPC_cHttpHeaderWriter_close(&hw);
 
         NyLPC_cHttpBodyWriter_initialize(&bw,&st);
--- a/core/http/NyLPC_cHttpHeaderWriter.c	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/http/NyLPC_cHttpHeaderWriter.c	Fri Sep 13 06:38:16 2013 +0000
@@ -117,13 +117,84 @@
 }
 
 
+NyLPC_TBool NyLPC_cHttpHeaderWriter_writeRequestHeader(NyLPC_TcHttpHeaderWriter_t* i_inst,NyLPC_THttpMethodType i_method,const struct NyLPC_TIPv4Addr* i_host,NyLPC_TUInt16 i_port,const NyLPC_TChar* i_path)
+{
+    const NyLPC_TChar* t;
+    NyLPC_TChar v[16];
+    //エラー状態ならなにもしない。
+    if(i_inst->_is_error){
+        return NyLPC_TBool_FALSE;
+    }
 
-#define TIMEOUT 10*1000
+    t=NyLPC_THttpMethodType_toString(i_method);
+    if(t==NULL){
+        return NyLPC_TBool_FALSE;
+    }
+    //リクエストラインの記述
+    //Method
+    if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,t,-1)){
+        NyLPC_OnErrorGoto(Error);
+    }
+    if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream," ",1)){
+        NyLPC_OnErrorGoto(Error);
+    }
+    //Path
+    if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,i_path,-1)){
+        NyLPC_OnErrorGoto(Error);
+    }
+    if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream," HTTP/1.1\r\n",11)){
+        NyLPC_OnErrorGoto(Error);
+    }
+    //HOSTの記述
+    if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,"Host: ",6)){
+        NyLPC_OnErrorGoto(Error);
+    }
+    NyLPC_TIPv4Addr_toString(i_host,v);
+    if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,v,-1)){
+        NyLPC_OnErrorGoto(Error);
+    }
+    if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,":",1)){
+        NyLPC_OnErrorGoto(Error);
+    }
+    NyLPC_uitoa(i_port,v,10);
+    if(!writeln(i_inst->_ref_stream,v,-1)){
+        NyLPC_OnErrorGoto(Error);
+    }
+
+    //close
+    if(i_inst->_is_close){
+        if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,"Connection: CLOSE\r\n",-1)){
+            NyLPC_OnErrorGoto(Error);
+        }
+    }
+
+    //chunked
+    if(i_inst->_is_chunked){
+        if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,"Transfer-Encoding: chunked\r\n",-1)){
+            NyLPC_OnErrorGoto(Error);
+        }
+    }else{
+        if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,"Content-Length: ",-1)){
+            NyLPC_OnErrorGoto(Error);
+        }
+        NyLPC_uitoa(i_inst->_content_length,v,10);
+        if(!writeln(i_inst->_ref_stream,v,-1)){
+            NyLPC_OnErrorGoto(Error);
+        }
+    }
+    //送信サイズをリセット
+    i_inst->_size_of_sent=0;
+    return NyLPC_TBool_TRUE;
+Error:
+    i_inst->_is_error=NyLPC_TUInt8_FALSE;
+    return NyLPC_TBool_FALSE;
+
+}
 
 /**
  * ステータスラインと、標準メッセージヘッダを出力します。
  */
-NyLPC_TBool NyLPC_cHttpHeaderWriter_writeHeader(NyLPC_TcHttpHeaderWriter_t* i_inst,NyLPC_TUInt16 i_status)
+NyLPC_TBool NyLPC_cHttpHeaderWriter_writeResponseHeader(NyLPC_TcHttpHeaderWriter_t* i_inst,NyLPC_TUInt16 i_status)
 {
     NyLPC_TChar v[12];
     const char* m=getStatusMessage(i_status);
--- a/core/http/NyLPC_cHttpHeaderWriter.h	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/http/NyLPC_cHttpHeaderWriter.h	Fri Sep 13 06:38:16 2013 +0000
@@ -27,6 +27,7 @@
 #define NYLPC_CHTTPHEADERWRITER_H_
 
 #include "NyLPC_stdlib.h"
+#include "NyLPC_uipService.h"
 #include "NyLPC_cHttpStream.h"
 #include "NyLPC_cHttpBasicHeaderParser.h"
 #include "NyLPC_cHttpdConfig.h"
@@ -60,8 +61,8 @@
 NyLPC_TBool NyLPC_cHttpHeaderWriter_initialize(NyLPC_TcHttpHeaderWriter_t* i_inst,NyLPC_TiHttpPtrStream_t* i_ref_stream,const struct NyLPC_THttpBasicHeader* i_req_header);
 
 #define NyLPC_cHttpHeaderWriter_finalize(i)
-
-NyLPC_TBool NyLPC_cHttpHeaderWriter_writeHeader(NyLPC_TcHttpHeaderWriter_t* i_inst,NyLPC_TUInt16 i_status);
+NyLPC_TBool NyLPC_cHttpHeaderWriter_writeRequestHeader(NyLPC_TcHttpHeaderWriter_t* i_inst,NyLPC_THttpMethodType i_method,const struct NyLPC_TIPv4Addr* i_host,NyLPC_TUInt16 i_port,const NyLPC_TChar* i_path);
+NyLPC_TBool NyLPC_cHttpHeaderWriter_writeResponseHeader(NyLPC_TcHttpHeaderWriter_t* i_inst,NyLPC_TUInt16 i_status);
 NyLPC_TBool NyLPC_cHttpHeaderWriter_writeMessage(NyLPC_TcHttpHeaderWriter_t* i_inst,const NyLPC_TChar* i_name,const NyLPC_TChar* i_field);
 /**
  * \r\n区切りのメッセージをそのままヘッダに挿入します。i_additional_headerの終端は\r\nで閉じてください。
--- a/core/http/NyLPC_cHttpStream.c	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/http/NyLPC_cHttpStream.c	Fri Sep 13 06:38:16 2013 +0000
@@ -50,7 +50,7 @@
 }
 NyLPC_TInt32 NyLPC_cTcpSocket_precv(void* i_inst,const void** o_buf_ptr,NyLPC_TUInt32 i_wait_msec)
 {
-    int l=_rbuf_len>100?100:_rbuf_len;
+    int l=(_rbuf_len>100)?100:_rbuf_len;
     *o_buf_ptr=_rbuf;
     return l;
 }
@@ -142,7 +142,7 @@
     NyLPC_TUInt16 s,free_size;
     NyLPC_TUInt32 l;
     const char* src=(const char*)i_data;
-    l=(i_length<0?strlen(src):i_length);
+    l=((i_length<0)?strlen(src):i_length);
     while(l>0){
         //送信バッファがNULLなら、割り当て。
         if(inst->txb==NULL){
--- a/core/include/NyLPC_http.h	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/include/NyLPC_http.h	Fri Sep 13 06:38:16 2013 +0000
@@ -41,6 +41,7 @@
 #include "../http/NyLPC_cUrlEncode.h"
 #include "../http/NyLPC_cHttpBasicBodyParser.h"
 #include "../http/NyLPC_cHttpBodyParser.h"
+#include "../http/NyLPC_cBase64.h"
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
--- a/core/include/NyLPC_net.h	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/include/NyLPC_net.h	Fri Sep 13 06:38:16 2013 +0000
@@ -41,10 +41,14 @@
 #include "../net/httpd/mod/NyLPC_cModFileIoBaseClass.h"
 #include "../net/httpd/mod/NyLPC_cModRemoteMcu.h"
 #include "../net/httpd/mod/NyLPC_cModMiMicSetting.h"
+#include "../net/httpd/mod/NyLPC_cModWebSocket.h"
 #include "../net/httpd/mod/NyLPC_cModRomFiles.h"
 #include "../net/httpd/mod/NyLPC_cModUrl.h"
 #include "../net/httpd/mod/NyLPC_cModUPnPDevice.h"
 
+#include "../net/httpcl/NyLPC_cHttpClient.h"
+
+
 #include "../net/upnp/NyLPC_cSsdpSocket.h"
 #include "../net/upnp/NyLPC_cUPnP.h"
 
--- a/core/include/NyLPC_stdlib.h	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/include/NyLPC_stdlib.h	Fri Sep 13 06:38:16 2013 +0000
@@ -74,19 +74,19 @@
      * Abortマクロです。eが偽の時に、異常終了します。
      * デバック時/リリース時のどちらでも有効です。
      * @param e
-     * 評価式です。
+     * 評価式です.
      */
     #define NyLPC_AbortIfNot(e) if(!(e)){NyLPC_abortHook(__FILE__,__LINE__);};
 
     /**
-     * 警告表示用のマクロです。デバックに使います。
-     * デバック時のみ有効です。
+     * 警告表示用のマクロです.デバックに使います.
+     * デバック時のみ有効です.
      */
     #define NyLPC_Warning() {NyLPC_debugHook(__FILE__,__LINE__);};
 
     /**
-     * 警告表示用のマクロです。eが偽の時に、警告を出します。
-     * デバック時のみ有効です。
+     * 警告表示用のマクロです.eが偽の時に、警告を出します.
+     * デバック時のみ有効です.
      * @param e
      * 評価式です。
      */
@@ -95,7 +95,7 @@
     /*
      * トレースマクロです。デバックに使います。
      * 内部変数に、最後にコールされたファイル名と、行番号を保存します。
-     * デバック時のみ有効です。
+     * デバック時のみ有効です.
      */
     #define NyLPC_Trace() {NyLPC_debugHook(__FILE__,__LINE__);};
 #else
@@ -480,9 +480,9 @@
  */
 NyLPC_TUInt8 NyLPC_TTextIdTbl_getMatchIdIgnoreCase(const NyLPC_TChar* i_str,const struct NyLPC_TTextIdTbl i_tbl[]);
 /**
- * テーブルからIDに一致する文字列を返す。
+ * テーブルからIDに一致する文字列を返す.
  * @return
- * IDに一致する文字列。
+ * IDに一致する文字列.
  * 存在しなければNULL
  */
 const NyLPC_TChar* NyLPC_TTextIdTbl_getTextById(NyLPC_TUInt8 i_id,const struct NyLPC_TTextIdTbl i_tbl[]);
--- a/core/include/NyLPC_utils.h	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/include/NyLPC_utils.h	Fri Sep 13 06:38:16 2013 +0000
@@ -35,6 +35,8 @@
 #include "../utils/NyLPC_cFormatWriter.h"
 #include "../utils/NyLPC_cUuid.h"
 
+#include "../utils/sha1/sha1.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/net/httpcl/NyLPC_cHttpClient.c	Fri Sep 13 06:38:16 2013 +0000
@@ -0,0 +1,263 @@
+/*
+ * NyLPC_cHttpClient.c
+ *
+ *  Created on: 2013/08/24
+ *      Author: nyatla
+ */
+#include "NyLPC_cHttpClient.h"
+typedef NyLPC_TUInt8 NyLPC_TcHttpClient_ST;
+#define NyLPC_TcHttpClient_ST_CLOSED 0x00	//ソケット切断
+#define NyLPC_TcHttpClient_ST_IDLE   0x01	//メソッド選択待ち
+
+#define NyLPC_TcHttpClient_ST_SEND_REQ_BODY	0x21 //POSTリクエスト送信中
+#define NyLPC_TcHttpClient_ST_RECV_RES_HEAD	0x23
+#define NyLPC_TcHttpClient_ST_RECV_RES_BODY	0x24
+
+
+
+void NyLPC_cHttpClient_initialize(NyLPC_TcHttpClient_t* i_inst,void* i_rx_buf,NyLPC_TUInt16 i_rx_size)
+{
+	NyLPC_cTcpSocket_initialize(&i_inst->_sock,i_rx_buf,i_rx_size);
+	i_inst->_state=NyLPC_TcHttpClient_ST_CLOSED;
+}
+void NyLPC_cHttpClient_finalize(NyLPC_TcHttpClient_t* i_inst)
+{
+	NyLPC_cHttpClient_close(i_inst);
+	NyLPC_cTcpSocket_finalize(&i_inst->_sock);
+}
+
+void NyLPC_cHttpClient_close(NyLPC_TcHttpClient_t* i_inst)
+{
+	//ステータスをclosedへ遷移
+	switch(i_inst->_state){
+	case NyLPC_TcHttpClient_ST_RECV_RES_BODY:
+		NyLPC_cHttpBodyParser_finalize(&i_inst->pw.body_parser);
+		break;
+	case NyLPC_TcHttpClient_ST_SEND_REQ_BODY:
+		NyLPC_cHttpBodyWriter_finalize(&(i_inst->pw.body_writer));
+		break;
+	case NyLPC_TcHttpClient_ST_RECV_RES_HEAD:
+		//開放するものとくにない
+		break;
+	case NyLPC_TcHttpClient_ST_IDLE:
+		break;
+	case NyLPC_TcHttpClient_ST_CLOSED:
+		return;
+	}
+	NyLPC_cTcpSocket_close(&i_inst->_sock,1000);
+	i_inst->_state=NyLPC_TcHttpClient_ST_CLOSED;
+}
+
+/**
+ * サーバに接続する。
+ * 関数はステータスをIDLEへ遷移する。
+ * インスタンスのステータスは何でも構わない。
+ * @return
+ * TRUE - ステータスはIDLEへ遷移する。
+ * FALSE - ステータスはCLOSEDへ遷移する。
+ */
+NyLPC_TBool NyLPC_cHttpClient_connect(NyLPC_TcHttpClient_t* i_inst,struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_port)
+{
+	//ステータスをclosedへ遷移
+	NyLPC_cHttpClient_close(i_inst);
+	//接続
+	if(!NyLPC_cTcpSocket_connect(&i_inst->_sock,i_addr,i_port,3000)){
+		return NyLPC_TBool_FALSE;
+	}
+	//streamの生成
+	if(!NyLPC_cHttpStream_initialize(&i_inst->_stream,&(i_inst->_sock))){
+		NyLPC_OnErrorGoto(ERROR);
+	}
+	//ステータス遷移
+	i_inst->_state=NyLPC_TcHttpClient_ST_IDLE;
+	return NyLPC_TBool_TRUE;
+ERROR:
+	return NyLPC_TBool_FALSE;
+}
+
+
+
+/**
+ * POSTリクエストを送信する。
+ * @return
+ * 引き続き処理が可能かを返す。
+ */
+NyLPC_TBool NyLPC_cHttpClient_sendMethod(
+	NyLPC_TcHttpClient_t* i_inst,
+	NyLPC_THttpMethodType i_method,
+	const NyLPC_TChar* i_path,
+	NyLPC_TUInt32 i_content_length,
+	const NyLPC_TChar* i_mime_type,
+	const NyLPC_TChar* i_additional_header)
+{
+	//ステータスチェック
+	if(i_inst->_state!=NyLPC_TcHttpClient_ST_IDLE){
+		NyLPC_OnErrorGoto(Error_0);
+	}
+	//POSTリクエストの送信
+	if(!NyLPC_cHttpHeaderWriter_initialize(&i_inst->pw.head_writer,&i_inst->_stream.super,NULL)){
+		NyLPC_OnErrorGoto(Error_0);
+	}
+	//ヘッダを送信
+	NyLPC_cHttpHeaderWriter_setConnectionClose(&i_inst->pw.head_writer,NyLPC_TBool_TRUE);//Connection closeを強制
+	if(i_content_length==NyLPC_cHttpHeaderWriter_CONTENT_LENGTH_UNLIMITED){
+		NyLPC_cHttpHeaderWriter_setChunked(&i_inst->pw.head_writer);
+	}else{
+		NyLPC_cHttpHeaderWriter_setContentLength(&i_inst->pw.head_writer,i_content_length);
+	}
+	if(!NyLPC_cHttpHeaderWriter_writeRequestHeader(
+		&i_inst->pw.head_writer,
+		i_method,
+		NyLPC_cTcpSocket_getPeerAddr(&(i_inst->_sock)),
+		NyLPC_cTcpSocket_getPeerPort(&(i_inst->_sock)),i_path)){
+		NyLPC_OnErrorGoto(Error_1);
+	}
+	//MimeType
+	if(i_mime_type!=NULL){
+		if(!NyLPC_cHttpHeaderWriter_writeMessage(&i_inst->pw.head_writer,"Content-type",i_mime_type)){
+			NyLPC_OnErrorGoto(Error_1);
+		}
+	}
+	if(i_additional_header!=NULL){
+		if(!NyLPC_cHttpHeaderWriter_writeRawMessage(&i_inst->pw.head_writer,i_additional_header)){
+			NyLPC_OnErrorGoto(Error_1);
+		}
+	}
+	NyLPC_cHttpHeaderWriter_close(&i_inst->pw.head_writer);
+	NyLPC_cHttpHeaderWriter_finalize(&i_inst->pw.head_writer);
+
+	//BodyWriter生成
+	NyLPC_cHttpBodyWriter_initialize(&(i_inst->pw.body_writer),&(i_inst->_stream));
+	//bodyのchunkedもセット
+	if(i_content_length==0xffffffff){
+		NyLPC_cHttpBodyWriter_setChunked(&(i_inst->pw.body_writer));
+	}else{
+		NyLPC_cHttpBodyWriter_setContentLength(&(i_inst->pw.body_writer),i_content_length);
+	}
+	i_inst->_state=NyLPC_TcHttpClient_ST_SEND_REQ_BODY;
+	return NyLPC_TBool_TRUE;
+Error_0:
+	return NyLPC_TBool_FALSE;
+Error_1:
+	NyLPC_cHttpHeaderWriter_finalize(&i_inst->pw.head_writer);
+	return NyLPC_TBool_FALSE;
+}
+
+/**
+ * POSTリクエストのデータを送信する。
+ * @return
+ * 0:EOF
+ */
+NyLPC_TBool NyLPC_cHttpClient_write(NyLPC_TcHttpClient_t* i_inst,void* i_buf,NyLPC_TUInt32 i_buf_size)
+{
+	if(i_inst->_state!=NyLPC_TcHttpClient_ST_SEND_REQ_BODY){
+		return NyLPC_TBool_FALSE;
+	}
+	if(!NyLPC_cHttpBodyWriter_write(&i_inst->pw.body_writer,i_buf,i_buf_size)){
+		//ERROR
+		NyLPC_cHttpClient_close(i_inst);
+		NyLPC_OnErrorGoto(Error);
+	}
+	return NyLPC_TBool_TRUE;
+Error:
+	return NyLPC_TBool_FALSE;
+}
+
+NyLPC_TBool NyLPC_cHttpClient_writeFormat(NyLPC_TcHttpClient_t* i_inst,const NyLPC_TChar* i_fmt,...)
+{
+	NyLPC_TBool ret;
+	va_list a;
+	if(i_inst->_state!=NyLPC_TcHttpClient_ST_SEND_REQ_BODY){
+		return NyLPC_TBool_FALSE;
+	}
+	va_start(a,i_fmt);
+	ret=NyLPC_cHttpBodyWriter_formatV(&i_inst->pw.body_writer,i_fmt,a);
+	va_end(a);
+	if(!ret){
+		NyLPC_cHttpClient_close(i_inst);
+	}
+	return ret;
+}
+NyLPC_TBool NyLPC_cHttpClient_writeFormatV(NyLPC_TcHttpClient_t* i_inst,const NyLPC_TChar* i_fmt,va_list i_args)
+{
+	NyLPC_TBool ret;
+	if(i_inst->_state!=NyLPC_TcHttpClient_ST_SEND_REQ_BODY){
+		return NyLPC_TBool_FALSE;
+	}
+	ret=NyLPC_cHttpBodyWriter_formatV(&i_inst->pw.body_writer,i_fmt,i_args);
+	if(!ret){
+		NyLPC_cHttpClient_close(i_inst);
+	}
+	return ret;
+}
+
+
+/**
+ * ステータスコードを返す。
+ * @return
+ * ステータスコード
+ */
+NyLPC_TUInt16 NyLPC_cHttpClient_getStatus(NyLPC_TcHttpClient_t* i_inst)
+{
+	struct NyLPC_THttpBasicHeader header;
+	if(i_inst->_state!=NyLPC_TcHttpClient_ST_SEND_REQ_BODY){
+		return 0;
+	}
+	//
+	if(!NyLPC_cHttpBodyWriter_close(&i_inst->pw.body_writer)){
+		NyLPC_OnErrorGoto(Error_1);
+	}
+	i_inst->_state=NyLPC_TcHttpClient_ST_RECV_RES_HEAD;
+	//100を無視してHTTPヘッダをパース
+	//@todo POSTの時だけに制限したら?
+	do{
+		NyLPC_cHttpBasicHeaderParser_initialize(&i_inst->pw.head_parser,NULL);
+		NyLPC_cHttpBasicHeaderParser_parseInit(&i_inst->pw.head_parser,&header);
+		if(!NyLPC_cHttpBasicHeaderParser_parseStream(&i_inst->pw.head_parser,&i_inst->_stream.super,&header)){
+			NyLPC_OnErrorGoto(Error_2);
+		}
+		if(!NyLPC_cHttpBasicHeaderParser_parseFinish(&i_inst->pw.head_parser,&header)){
+			NyLPC_OnErrorGoto(Error_2);
+		}
+		NyLPC_cHttpBasicHeaderParser_finalize(&i_inst->pw.head_parser);
+		//レスポンスヘッダか確認
+		if(header.type!=NyLPC_THttpHeaderType_RESPONSE){
+			NyLPC_OnErrorGoto(Error_1);
+		}
+	}while(header.startline.res.status==100);
+	//BodyParserを起動
+	NyLPC_cHttpBodyParser_initialize(&i_inst->pw.body_parser);
+	NyLPC_cHttpBodyParser_parseInit(&i_inst->pw.body_parser,&header);
+	i_inst->_state=NyLPC_TcHttpClient_ST_RECV_RES_BODY;
+	return header.startline.res.status;
+Error_1:
+	NyLPC_cHttpClient_close(i_inst);
+	return 0;
+Error_2:
+	NyLPC_cHttpBasicHeaderParser_finalize(&i_inst->pw.head_parser);
+	NyLPC_cHttpClient_close(i_inst);
+	return 0;
+}
+
+
+/**
+ * GET/POSTリクエストで受信したデータを読み出す。
+ * @param o_read_len
+ * 戻り値TRUEの場合のみ有効。
+ * 終端の場合は0
+ * @return
+ * TRUE:正常読み出し。o_read_lenの値で終端判定
+ * FALSE:失敗。コネクションはクローズされる。
+ */
+NyLPC_TBool NyLPC_cHttpClient_read(NyLPC_TcHttpClient_t* i_inst,void* i_buf,NyLPC_TUInt32 i_buf_size,NyLPC_TInt16* o_read_len)
+{
+	if(i_inst->_state!=NyLPC_TcHttpClient_ST_RECV_RES_BODY){
+		return NyLPC_TBool_FALSE;
+	}
+	if(!NyLPC_cHttpBodyParser_parseStream(&i_inst->pw.body_parser,&i_inst->_stream.super,i_buf,i_buf_size,o_read_len)){
+		NyLPC_cHttpClient_close(i_inst);
+		return NyLPC_TBool_FALSE;
+	}
+	return NyLPC_TBool_TRUE;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/net/httpcl/NyLPC_cHttpClient.h	Fri Sep 13 06:38:16 2013 +0000
@@ -0,0 +1,133 @@
+/*
+ * NyLPC_cHttpClient.h
+ *
+ *  Created on: 2013/08/24
+ *      Author: nyatla
+ */
+
+#ifndef NYLPC_CHTTPCLIENT_H_
+#define NYLPC_CHTTPCLIENT_H_
+
+#include "NyLPC_stdlib.h"
+#include "NyLPC_net.h"
+#include "NyLPC_http.h"
+#include "NyLPC_uipService.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct NyLPC_TcHttpClient NyLPC_TcHttpClient_t;
+
+#define NyLPC_cHttpHeaderWriter_CONTENT_LENGTH_UNLIMITED 0xffffffff
+struct NyLPC_TcHttpClient
+{
+	NyLPC_TUInt8 _state;
+	NyLPC_TUInt8 _padding1;
+	NyLPC_TcTcpSocket_t _sock;
+	NyLPC_TcHttpStream_t _stream;
+	union{
+		NyLPC_TcHttpHeaderWriter_t head_writer;
+		NyLPC_TcHttpBodyWriter_t body_writer;
+		NyLPC_TcHttpBasicHeaderParser_t head_parser;
+		NyLPC_TcHttpBodyParser_t body_parser;
+	}pw;
+};
+
+
+void NyLPC_cHttpClient_initialize(NyLPC_TcHttpClient_t* i_inst,void* i_rx_buf,NyLPC_TUInt16 i_rx_size);
+
+void NyLPC_cHttpClient_finalize(NyLPC_TcHttpClient_t* i_inst);
+
+/**
+ * サーバとの接続を切断する。
+ * ステータスはCLOSEDになる。
+ */
+void NyLPC_cHttpClient_close(NyLPC_TcHttpClient_t* i_inst);
+
+
+/**
+ * サーバに接続する。
+ * 関数はステータスをIDLEへ遷移する。
+ * インスタンスのステータスは何でも構わない。
+ * @return
+ * TRUE - ステータスはIDLEへ遷移する。
+ * FALSE - ステータスはCLOSEDへ遷移する。
+ */
+NyLPC_TBool NyLPC_cHttpClient_connect(NyLPC_TcHttpClient_t* i_inst,struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_port);
+
+
+
+/**
+ * POSTリクエストを送信する。
+ * ステータスはIDLEである必要がある。
+ * @param i_content_length
+ * 送信bodyのサイズ。最大 0xfffffffe
+ * NyLPC_cHttpHeaderWriter_CONTENT_LENGTH_UNLIMITEDの場合はChunked転送になる。
+ * @return
+ * 引き続き処理が可能かを返す。
+ * TRUE - 成功。ステータスはSEND_REQ_BODYになる。write/getStatusを呼び出せる。
+ * FALSE - 失敗。ステータスはCLOSEDになる。
+ */
+NyLPC_TBool NyLPC_cHttpClient_sendMethod(
+	NyLPC_TcHttpClient_t* i_inst,
+	NyLPC_THttpMethodType i_method,
+	const NyLPC_TChar* i_path,
+	NyLPC_TUInt32 i_content_length,
+	const NyLPC_TChar* i_mime_type,
+	const NyLPC_TChar* i_additional_header);
+
+
+/**
+ * POSTリクエストのデータを送信する。
+ * ステータスはSEND_REQ_BODYである必要がある。
+ * @return
+ * TRUE - 成功。
+ * FALSE - 失敗。ステータスはCLOSEDになる。
+ */
+NyLPC_TBool NyLPC_cHttpClient_write(NyLPC_TcHttpClient_t* i_inst,void* i_buf,NyLPC_TUInt32 i_buf_size);
+
+/**
+ * 書式文字列としてPOSTリクエストのデータを送信する。
+ * ステータスはSEND_REQ_BODYである必要がある。
+ * @param i_fmt
+ * printfライクなフォーマット文字列
+ * @return
+ * TRUE - 成功。
+ * FALSE - 失敗。ステータスはCLOSEDになる。
+ */
+NyLPC_TBool NyLPC_cHttpClient_writeFormat(NyLPC_TcHttpClient_t* i_inst,const NyLPC_TChar* i_fmt,...);
+NyLPC_TBool NyLPC_cHttpClient_writeFormatV(NyLPC_TcHttpClient_t* i_inst,const NyLPC_TChar* i_fmt,va_list i_args);
+
+/**
+ * ステータスコードを返す。
+ * ステータスはSEND_REQ_BODYである必要がある。
+ * @return
+ * 0 - 失敗。ステータスはCLOSEDになる。
+ * その他 - ステータスコード。ステータスはRECV_RES_BODYになる。
+ */
+NyLPC_TUInt16 NyLPC_cHttpClient_getStatus(NyLPC_TcHttpClient_t* i_inst);
+
+
+/**
+ * GET/POSTリクエストで受信したデータを読み出す。
+ * ステータスはRECV_RES_BODYである必要がある。
+ * @param o_read_len
+ * 戻り値TRUEの場合のみ有効。データ終端に達した場合は0になる。
+ * @return
+ * TRUE:正常読み出し。o_read_lenの値で終端判定
+ * FALSE:失敗。コネクションはクローズされる。
+ */
+NyLPC_TBool NyLPC_cHttpClient_read(NyLPC_TcHttpClient_t* i_inst,void* i_buf,NyLPC_TUInt32 i_buf_size,NyLPC_TInt16* o_read_len);
+
+
+
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* NYLPC_CHTTPCLIENT_H_ */
+
--- a/core/net/httpd/NyLPC_cHttpdConnection.c	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/net/httpd/NyLPC_cHttpdConnection.c	Fri Sep 13 06:38:16 2013 +0000
@@ -81,7 +81,7 @@
     //continueにセットされていたらcloseをFALSEに
     NyLPC_cHttpHeaderWriter_setConnectionClose(h,(i_inst->_connection_message_mode!=NyLPC_TcHttpdConnection_CONNECTION_MODE_CONTINUE));
 
-    if(!NyLPC_cHttpHeaderWriter_writeHeader(h,i_response_code)){
+    if(!NyLPC_cHttpHeaderWriter_writeResponseHeader(h,i_response_code)){
         NyLPC_OnErrorGoto(ERROR_SEND);
     }
     if(!NyLPC_cHttpHeaderWriter_writeMessage(h,"Content-type",i_content_type)){
@@ -169,15 +169,13 @@
     if(NyLPC_cHttpHeaderWriter_initialize(h,&i_inst->_in_stream.super,NULL)){
         //ヘッダを送信
         NyLPC_cHttpHeaderWriter_setConnectionClose(h,NyLPC_TBool_TRUE);
-        NyLPC_cHttpHeaderWriter_writeHeader(h,i_status);
+        NyLPC_cHttpHeaderWriter_writeResponseHeader(h,i_status);
         NyLPC_cHttpHeaderWriter_close(h);
         NyLPC_cHttpHeaderWriter_finalize(h);
     }
 }
 /**
  * 関数を実行後、_res_statusはCLOSEDかHEADかERRORに遷移する。
- * @return
- * TRUE/FALSE TCPコネクションを切断するかどうかのフラグ
  */
 NyLPC_TBool NyLPC_cHttpdConnection_closeResponse(NyLPC_TcHttpdConnection_t* i_inst)
 {
--- a/core/net/httpd/NyLPC_cHttpdConnection_protected.h	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/net/httpd/NyLPC_cHttpdConnection_protected.h	Fri Sep 13 06:38:16 2013 +0000
@@ -42,9 +42,8 @@
 
 
 /**
- * 関数を実行後、_res_statusはCLOSEDかHEADかERRORに遷移する。
- * @return
- * TRUE/FALSE TCPコネクションを切断するかどうかのフラグ
+ * コネクションをHTTPレベルで閉じます。
+ * ResponseステータスはCLOSEDになります。Requestステータスは変化しません。
  */
 NyLPC_TBool NyLPC_cHttpdConnection_closeResponse(NyLPC_TcHttpdConnection_t* i_inst);
 
@@ -62,7 +61,8 @@
 NyLPC_TBool NyLPC_cHttpdConnection_acceptSocket(NyLPC_TcHttpdConnection_t* i_inst);
 
 /**
- * ソケットをLISTEN状態に戻します。
+ * コネクションのソケットを閉じます。
+ * ResponseステータスはCLOSEDになり、RequestステータスはLISTENになります。
  */
 void NyLPC_cHttpdConnection_closeSocket(NyLPC_TcHttpdConnection_t* i_inst);
 
--- a/core/net/httpd/mod/NyLPC_cModFileIoBaseClass.c	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/net/httpd/mod/NyLPC_cModFileIoBaseClass.c	Fri Sep 13 06:38:16 2013 +0000
@@ -30,8 +30,6 @@
 #include "../NyLPC_cHttpdUtils.h"
 #include "NyLPC_net.h"
 
-#define MVM_VERSION "ModFileIo/1.0;Json/1.0"
-
 #define FNAME_MAX   48
 #define STRBUF_MAX  48
 
--- a/core/net/httpd/mod/NyLPC_cModRomFiles.c	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/net/httpd/mod/NyLPC_cModRomFiles.c	Fri Sep 13 06:38:16 2013 +0000
@@ -115,7 +115,7 @@
         {
             NyLPC_cHttpdConnection_setConnectionMode(i_connection,NyLPC_TcHttpdConnection_CONNECTION_MODE_CLOSE);
         }
-        return NyLPC_cHttpdUtils_sendFixedContentBatch(i_connection,i_inst->_data[i].content_type,i_inst->_data[i].data,i_inst->_data[i].size>0?i_inst->_data[i].size:strlen(i_inst->_data[i].data));
+        return NyLPC_cHttpdUtils_sendFixedContentBatch(i_connection,i_inst->_data[i].content_type,i_inst->_data[i].data,(i_inst->_data[i].size>0)?i_inst->_data[i].size:strlen(i_inst->_data[i].data));
     }
     //404Error
     NyLPC_cHttpdUtils_sendErrorResponse(i_connection,404);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/net/httpd/mod/NyLPC_cModWebSocket.c	Fri Sep 13 06:38:16 2013 +0000
@@ -0,0 +1,600 @@
+/*********************************************************************************
+ * 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>
+ *
+ *********************************************************************************/
+#include "NyLPC_cModWebSocket.h"
+#include "NyLPC_utils.h"
+
+
+
+#define NyLPC_TcModWebSocket_FRAME_TYPE_BIN 0x01
+#define NyLPC_TcModWebSocket_FRAME_TYPE_TXT 0x02
+
+
+
+#define STRBUF_MAX 32
+struct TModWebSocketHeader
+{
+	struct NyLPC_THttpBasicHeader super;
+	NyLPC_TcStr_t _tstr;
+	NyLPC_TChar _tstr_buf[STRBUF_MAX];
+	NyLPC_TChar key[24+4];
+	NyLPC_TInt16 version;
+	NyLPC_TUInt8 sub_protocol_id;
+	NyLPC_TUInt8 message_id;
+	const NyLPC_TChar* _ref_sub_protocol;
+};
+
+
+
+#define MESSAGE_ID_UNKNOWN					0x00
+#define MESSAGE_ID_UPGRADE					0x01
+#define MESSAGE_ID_SEC_WEBSOCKET_KEY		0x02
+#define MESSAGE_ID_ORIGIN					0x03
+#define MESSAGE_ID_SEC_WEBSOCKET_PROTOCL	0x04
+#define MESSAGE_ID_SEC_WEBSOCKET_VERSION	0x05
+
+static const struct NyLPC_TTextIdTbl msg_tbl[]=
+{
+	{"Upgrade",MESSAGE_ID_UPGRADE},
+	{"Sec-WebSocket-Key",MESSAGE_ID_SEC_WEBSOCKET_KEY},
+	{"Origin",MESSAGE_ID_ORIGIN},
+	{"Sec-WebSocket-Protocol",MESSAGE_ID_SEC_WEBSOCKET_PROTOCL},
+	{"Sec-WebSocket-Version",MESSAGE_ID_SEC_WEBSOCKET_VERSION},
+	{NULL,MESSAGE_ID_UNKNOWN}
+};
+
+static NyLPC_TBool messageHandler(NyLPC_TcHttpBasicHeaderParser_t* i_inst,const NyLPC_TChar* i_name,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out)
+{
+	struct TModWebSocketHeader* out=(struct TModWebSocketHeader*)o_out;
+	if(i_name!=NULL){
+		out->message_id=NyLPC_TTextIdTbl_getMatchIdIgnoreCase(i_name,msg_tbl);
+		NyLPC_cStr_clear(&(out->_tstr));
+	}else{
+		switch(out->message_id)
+		{
+		case MESSAGE_ID_UPGRADE:
+			if(i_c!='\0'){
+				if(!NyLPC_cStr_put(&(out->_tstr),i_c)){
+					NyLPC_OnErrorGoto(ERROR);
+				}
+			}else{
+				//websocketかチェック
+				if(!NyLPC_cStr_isEqualIgnoreCase(&out->_tstr,"websocket")){
+					return NyLPC_TBool_FALSE;//不一致
+				}
+			}
+			break;
+		case MESSAGE_ID_SEC_WEBSOCKET_KEY:
+			if(i_c!='\0'){
+				if(!NyLPC_cStr_put(&(out->_tstr),i_c)){
+					NyLPC_OnErrorGoto(ERROR);
+				}
+			}else{
+				//HASH値をコピー
+				strcpy(out->key,NyLPC_cStr_str(&out->_tstr));
+			}
+			break;
+		case MESSAGE_ID_SEC_WEBSOCKET_PROTOCL:
+			if(i_c!='\0' && i_c!=','){
+				if(!NyLPC_cStr_put(&(out->_tstr),i_c)){
+					NyLPC_OnErrorGoto(ERROR);
+				}
+			}else{
+				//トークン終端
+				if(out->_ref_sub_protocol!=NULL){
+					//サブプロトコルが指定されている場合はチェック
+					if(NyLPC_stricmp(NyLPC_cStr_str(&out->_tstr),out->_ref_sub_protocol)==0){
+						out->sub_protocol_id=1;//SubProtocol一致
+					}
+				}
+				//','の時はリセット
+				if(i_c!=','){
+					NyLPC_cStr_clear(&(out->_tstr));
+				}
+			}
+			break;
+		case MESSAGE_ID_SEC_WEBSOCKET_VERSION:
+			if(i_c!='\0'){
+				if(!NyLPC_cStr_put(&(out->_tstr),i_c)){
+					NyLPC_OnErrorGoto(ERROR);
+				}
+			}else{
+				//VERSION
+				out->version=atoi(NyLPC_cStr_str(&out->_tstr));
+				if(out->version<0){
+					NyLPC_OnErrorGoto(ERROR);
+				}
+			}
+		}
+	}
+	return NyLPC_TBool_TRUE;
+	ERROR:
+	return NyLPC_TBool_FALSE;
+}
+
+
+
+
+/**
+ * デフォルトハンドラ
+ */
+static const struct NyLPC_TcHttpBasicHeaderParser_Handler handler=
+{
+	messageHandler,
+	NULL
+};
+#define NyLPC_TcModWebSocket_ST_START_PAYLOAD	0x01
+#define NyLPC_TcModWebSocket_ST_READ_PAYLOAD	0x02
+#define NyLPC_TcModWebSocket_ST_CLOSED			0x03
+
+
+/**
+ * コンストラクタ。
+ */
+void NyLPC_cModWebSocket_initialize(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_ref_root_path)
+{
+	NyLPC_cModRomFiles_initialize(&i_inst->super,i_ref_root_path,NULL,0);
+	i_inst->_frame_type=NyLPC_TcModWebSocket_FRAME_TYPE_TXT;
+	i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED;
+}
+void NyLPC_cModWebSocket_finalize(NyLPC_TcModWebSocket_t* i_inst)
+{
+	NyLPC_cModRomFiles_finalize(&i_inst->super);
+}
+/**
+ * モジュールがコネクションをハンドリングできるかを返します。
+ */
+NyLPC_TBool NyLPC_cModWebSocket_canHandle(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TcHttpdConnection_t* i_connection)
+{
+	return NyLPC_cModRomFiles_canHandle(&i_inst->super,i_connection);
+}
+
+static union{
+	struct TModWebSocketHeader header;
+}work;
+
+
+
+/**
+ * モジュールを実行します。
+ */
+NyLPC_TBool NyLPC_cModWebSocket_execute(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TcHttpdConnection_t* i_connection)
+{
+	union{
+		NyLPC_TcHttpBasicHeaderParser_t parser;
+		SHA1_CTX sh1;
+	}sh;
+
+	//リクエストParse済へ遷移(この関数の後はModが責任を持ってリクエストを返却)
+	NyLPC_cHttpdConnection_setReqStatusParsed(i_connection);
+
+
+
+	//排他ロック
+	NyLPC_cHttpdConnection_lock(i_connection);
+	{//parser
+
+		//初期化
+		work.header.version=0;
+		work.header.sub_protocol_id=0;
+		NyLPC_cStr_initialize(&work.header._tstr,work.header._tstr_buf,STRBUF_MAX);
+
+		NyLPC_cHttpBasicHeaderParser_initialize(&sh.parser,&handler);
+
+		//プリフェッチしたデータを流す
+		NyLPC_cHttpBasicHeaderParser_parseInit(&sh.parser,&(work.header.super));
+		NyLPC_cHttpdConnection_pushPrefetchInfo(i_connection,&sh.parser,&work.header.super);
+		//後続をストリームから取り込む
+		if(!NyLPC_cHttpBasicHeaderParser_parseStream(&sh.parser,NyLPC_cHttpdConnection_refStream(i_connection),&(work.header.super))){
+			NyLPC_cHttpdUtils_sendErrorResponse(i_connection,500);
+			NyLPC_OnErrorGoto(Error1);
+		}
+		if(!NyLPC_cHttpBasicHeaderParser_parseFinish(&sh.parser,&(work.header.super))){
+			NyLPC_cHttpdUtils_sendErrorResponse(i_connection,500);
+			NyLPC_OnErrorGoto(Error1);
+		}
+		//HeaderParserはここで破棄(URLEncode,cSTRも)
+		NyLPC_cHttpBasicHeaderParser_finalize(&sh.parser);
+
+		NyLPC_cStr_finalize(&single_header._tstr);
+
+
+		//HTTP/1.1であること。Connection:Upgradeはチェックしない。
+		if(work.header.super.startline.req.version!=NyLPC_THttpVersion_11)
+		{
+			NyLPC_cHttpdUtils_sendErrorResponse(i_connection,400);
+			NyLPC_OnErrorGoto(Error2);
+		}
+		if(NyLPC_cHttpdConnection_getMethod(i_connection)!=NyLPC_THttpMethodType_GET){
+			NyLPC_cHttpdUtils_sendErrorResponse(i_connection,400);
+			NyLPC_OnErrorGoto(Error2);
+		}
+		//WebSocket version 13であること
+		if(work.header.version!=13){
+			NyLPC_cHttpdUtils_sendErrorResponse(i_connection,400);
+			NyLPC_OnErrorGoto(Error2);
+		}
+
+		//レスポンスの生成(生データを直接ストリームへ書きこむ)
+		if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_connection),
+			"HTTP/1.1 101 Switching Protocols\r\n"	//32+2
+			"Upgrade: websocket\r\n" 				//18+2
+			"Connection: Upgrade\r\n"				//19+2
+			"Sec-WebSocket-Accept: "				//22
+			,32+2+18+2+19+2+22)){
+			NyLPC_OnErrorGoto(Error3);
+		}
+		//SH1キーの生成
+		SHA1Init(&sh.sh1);
+		SHA1Update(&sh.sh1,(const unsigned char*)work.header.key,strlen(work.header.key));
+		SHA1Update(&sh.sh1,(const unsigned char*)"258EAFA5-E914-47DA-95CA-C5AB0DC85B11",36);
+		//ワークメモリ32バイトはstrの使いまわし
+		SHA1Final((unsigned char*)(work.header._tstr_buf),&sh.sh1);
+		//BASE64化(single_header.keyへ出力)
+		NyLPC_cBase64_encode(work.header._tstr_buf,20,work.header.key);
+		if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_connection),work.header.key,28)){
+			NyLPC_OnErrorGoto(Error3);
+		}
+		//SubProtocolの認証が有る場合
+		if(work.header.sub_protocol_id!=0){
+			if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_connection)
+				,"\r\nSec-WebSocket-Protocol: "	//24
+				,24)){
+				NyLPC_OnErrorGoto(Error3);
+			}
+			if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_connection)
+				,work.header._ref_sub_protocol
+				,strlen(work.header._ref_sub_protocol)))
+			{
+				NyLPC_OnErrorGoto(Error3);
+			}
+		}
+		//Sec-WebSocket-Protocol
+		if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_connection),"\r\n\r\n",4)){
+			NyLPC_OnErrorGoto(Error3);
+		}
+		i_inst->_payload_st=NyLPC_TcModWebSocket_ST_START_PAYLOAD;
+	}
+//占有解除
+	NyLPC_cHttpdConnection_unlock(i_connection);
+	//参照コネクションの設定
+	i_inst->_ref_connection=i_connection;
+	NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection));
+	return NyLPC_TBool_TRUE;
+Error3:
+Error2:
+	//VM排他ロックの解除
+	NyLPC_cHttpdConnection_unlock(i_connection);
+	return NyLPC_TBool_FALSE;
+Error1:
+	NyLPC_cHttpBasicHeaderParser_finalize(&parser);
+	NyLPC_cStr_finalize(&single_header._tstr);
+	//VM排他ロックの解除
+	NyLPC_cHttpdConnection_unlock(i_connection);
+	return NyLPC_TBool_FALSE;
+}
+
+
+
+static void writeClosePacket(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TUInt16 i_code)
+{
+	char w[4];
+	w[0]=0x88;
+	w[1]=0x02;
+	*((NyLPC_TUInt16*)(&w[2]))=NyLPC_htons(i_code);	//REASON
+	//CloseFrame送信
+	NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),w,4);
+	NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection));
+}
+
+
+#define FLAGS_MASK_BIT 7
+/**
+ * @return
+ * n>0:データ受信
+ * 0  :タイムアウト。コネクションの状態は変化しない。
+ * -1 :エラー コネクションはNyLPC_TcModWebSocket_ST_CLOSEDへ遷移する。
+ */
+NyLPC_TInt16 NyLPC_cModWebSocket_read(NyLPC_TcModWebSocket_t* i_inst,void* i_buf,NyLPC_TInt16 i_buf_len)
+{
+	const NyLPC_TUInt8* rx;
+	NyLPC_TInt32 rs,i;
+	NyLPC_TUInt16 header_size;
+	NyLPC_TUInt8 w8[2];
+	if(i_inst->_payload_st==NyLPC_TcModWebSocket_ST_CLOSED){
+		return -1;
+	}
+START:
+	rs=NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx);
+	//Error?
+	if(rs<0){
+		NyLPC_OnErrorGoto(Error);
+	}
+	//Timeout?
+	if(rs==0){
+		goto Timeout;
+	}
+	switch(i_inst->_payload_st){
+	case NyLPC_TcModWebSocket_ST_START_PAYLOAD:
+		//ペイロード
+		//2バイト溜まるまで待つ
+		if(rs<2){
+			//Timeout?
+			goto Timeout;
+		}
+		//ペイロードサイズの分析
+		if((0x7f&rx[1])<=125){
+			header_size=2+(((rx[1]&0x80)==0x80)?4:0);
+			i_inst->payload_size=(0x7f&rx[1]);
+		}else if((0x7f&rx[1])==126){
+			if(rs<4){
+				//Timeout?
+				goto Timeout;
+			}
+			header_size=2+2+(((rx[1]&0x80)==0x80)?4:0);
+			i_inst->payload_size=(rx[2]<<8)|rx[3];
+		}else{
+			//CLOSEの送信
+			writeClosePacket(i_inst,1009);
+			NyLPC_OnErrorGoto(Error);
+		}
+		//十分なヘッダが集まったかチェック
+		if(rs<header_size){
+			goto Timeout;
+		}
+		i_inst->_frame_flags_bits=0;
+		//FINがセットされていること.断片化禁止!
+		if((rx[0]&0x80)!=0x80){
+			NyLPC_OnErrorGoto(Error);
+		}
+		//必要ならMaskをコピー
+		if((rx[1]&0x80)==0x80){
+			memcpy(i_inst->_frame_mask,(rx+header_size-4),4);
+			NyLPC_TUInt8_setBit(i_inst->_frame_flags_bits,FLAGS_MASK_BIT);
+		}
+		i_inst->payload_ptr=0;
+
+		//パケットサイズの確定(基本ヘッダ+マスク)
+		switch(rx[0]&0x0f){
+		case 0x00:
+			//継続パケットは扱わない
+			NyLPC_OnErrorGoto(Error);
+		case 0x01:
+			if(i_inst->_frame_type!=NyLPC_TcModWebSocket_FRAME_TYPE_TXT){
+				NyLPC_OnErrorGoto(Error);
+			}
+			break;
+		case 0x02:
+			if(i_inst->_frame_type==NyLPC_TcModWebSocket_FRAME_TYPE_BIN){
+				NyLPC_OnErrorGoto(Error);
+			}
+			break;
+		case 0x08://close(非断片)
+			//CloseFrame送信
+			writeClosePacket(i_inst,1009);
+			//Errorとして処理
+			NyLPC_OnErrorGoto(Error);
+		case 0x09://ping(非断片)
+			//PONGを送信
+			w8[0]=0x0a;
+			NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),w8,1);
+			NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),rx+1,header_size-1);
+			NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection));
+			NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),header_size);
+			while(i_inst->payload_size!=i_inst->payload_ptr){
+				rs=NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx);
+				if(rs<=0){
+					if(rs<0){
+						//Error
+						NyLPC_OnErrorGoto(Error);
+					}
+					//Timeout
+					goto Timeout;
+				}
+				//読み込みサイズを決定
+				rs=(rs<i_buf_len)?rs:i_buf_len;
+				NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),rx,rs);
+				NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),rs);
+				i_inst->payload_ptr+=rs;
+			}
+			//Timeout(パケットスタートに戻る?)
+			goto START;
+		case 0x0a://pong(非断片)
+			//パケットの読み捨て
+			NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),header_size);
+			while(i_inst->payload_size!=i_inst->payload_ptr){
+				rs=NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx);
+				if(rs<=0){
+					if(rs<0){
+						//Error
+						NyLPC_OnErrorGoto(Error);
+					}
+					//Timeout
+					goto Timeout;
+				}
+				//読み込みサイズを決定
+				rs=(rs<i_buf_len)?rs:i_buf_len;
+				NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),rs);
+				i_inst->payload_ptr+=rs;
+			}
+			//Timeout(パケットスタートに戻る?)
+			goto START;
+		default:
+			//知らないコードはエラー
+			NyLPC_OnErrorGoto(Error);
+		}
+		//読み出し位置のシーク(Header部)
+		NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),header_size);
+		//ペイロード読み出しへ
+		i_inst->_payload_st=NyLPC_TcModWebSocket_ST_READ_PAYLOAD;
+		//継続してペイロード受信処理
+	case NyLPC_TcModWebSocket_ST_READ_PAYLOAD:
+		rs=NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx);
+		if(rs<=0){
+			if(rs<0){
+				//Error
+				NyLPC_OnErrorGoto(Error);
+			}
+			//Timeout
+			goto Timeout;
+		}
+		//読み込みサイズを決定
+		rs=(rs<i_buf_len)?rs:i_buf_len;
+		//アンマスク
+		if(NyLPC_TUInt8_isBitOn(i_inst->_frame_flags_bits,FLAGS_MASK_BIT)){
+			for(i=0;i<rs;i++){
+				*(((NyLPC_TUInt8*)i_buf)+i)=rx[i]^i_inst->_frame_mask[(i_inst->payload_ptr+i)%4];
+			}
+		}else{
+			memcpy(i_buf,rx,rs);
+		}
+		//読取位置を移動
+		NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),rs);
+		i_inst->payload_ptr+=rs;
+		if(i_inst->payload_size==i_inst->payload_ptr){
+			i_inst->_payload_st=NyLPC_TcModWebSocket_ST_START_PAYLOAD;
+		}
+		return rs;
+	}
+	//処理されなければエラー
+Error:
+	NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection);
+	i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED;
+	return -1;
+Timeout:
+	return 0;
+}
+
+static NyLPC_TBool fmt_handler(void* i_inst,const void* i_buf,NyLPC_TUInt32 i_len)
+{
+	return NyLPC_iHttpPtrStream_write((NyLPC_TiHttpPtrStream_t*)i_inst,i_buf,i_len);
+}
+
+NyLPC_TBool NyLPC_cModWebSocket_writeFormat(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,...)
+{
+	va_list a;
+	NyLPC_TInt16 l;
+	NyLPC_TUInt16 s;
+	NyLPC_TChar w[4];
+	//データサイズで切り分け
+	if(i_inst->_payload_st==NyLPC_TcModWebSocket_ST_CLOSED){
+		return NyLPC_TBool_FALSE;
+	}
+	//書式文字列の長さを計算
+	va_start(a,i_fmt);
+	l=NyLPC_cFormatWriter_length(i_fmt,a);
+	va_end(a);
+	switch(i_inst->_frame_type)
+	{
+	case NyLPC_TcModWebSocket_FRAME_TYPE_TXT:
+		w[0]=0x80|0x01;
+		break;
+	case NyLPC_TcModWebSocket_FRAME_TYPE_BIN:
+		w[0]=0x80|0x02;
+		break;
+	default:
+		NyLPC_OnErrorGoto(Error);
+	}
+	if(l<126){
+		w[1]=(NyLPC_TUInt8)l;
+		s=2;
+	}else{
+		w[1]=126;
+		s=3;
+		*((NyLPC_TUInt16*)(&(w[2])))=NyLPC_htons(l);
+	}
+	if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),w,s)){
+		//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);
+		NyLPC_OnErrorGoto(Error);
+	}
+	va_end(a);
+	NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection));
+	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_write(NyLPC_TcModWebSocket_t* i_inst,void* i_buf,NyLPC_TInt16 i_len)
+{
+	NyLPC_TChar w[4];
+	NyLPC_TUInt16 s;
+	//データサイズで切り分け
+	if(i_inst->_payload_st==NyLPC_TcModWebSocket_ST_CLOSED){
+		return NyLPC_TBool_FALSE;
+	}
+	//OP CODE
+	switch(i_inst->_frame_type)
+	{
+	case NyLPC_TcModWebSocket_FRAME_TYPE_TXT:
+		w[0]=0x80|0x01;
+		break;
+	case NyLPC_TcModWebSocket_FRAME_TYPE_BIN:
+		w[0]=0x80|0x02;
+		break;
+	default:
+		NyLPC_OnErrorGoto(Error);
+	}
+	if(i_len<126){
+		w[1]=(NyLPC_TUInt8)i_len;
+		s=2;
+	}else{
+		w[1]=126;
+		s=3;
+		*((NyLPC_TUInt16*)(&(w[2])))=NyLPC_htons(i_len);
+	}
+	if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),w,s)){
+		//CLOSE
+		NyLPC_OnErrorGoto(Error);
+	}
+	if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),i_buf,i_len)){
+		//CLOSE
+		NyLPC_OnErrorGoto(Error);
+	}
+	NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection));
+	return NyLPC_TBool_TRUE;
+Error:
+	NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection);
+	i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED;
+	return NyLPC_TBool_FALSE;
+}
+
+void NyLPC_cModWebSocket_close(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TUInt16 i_code)
+{
+	if(i_inst->_payload_st==NyLPC_TcModWebSocket_ST_CLOSED){
+		return;
+	}
+	//CLOSE送信
+	writeClosePacket(i_inst,i_code);
+	i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED;
+	//切断
+	NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/net/httpd/mod/NyLPC_cModWebSocket.h	Fri Sep 13 06:38:16 2013 +0000
@@ -0,0 +1,122 @@
+#ifndef NYLPC_CMODWEBSOCKET_H_
+#define NYLPC_CMODWEBSOCKET_H_
+
+/*********************************************************************************
+ * 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>
+ *
+ *********************************************************************************/
+#include "NyLPC_stdlib.h"
+#include "NyLPC_http.h"
+#include "../NyLPC_cHttpdConnection_protected.h"
+#include "../NyLPC_cHttpdUtils.h"
+#include "NyLPC_net.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * ファイルアップロードの為の基本シーケンスを提供する抽象クラスです。
+ * 継承クラスで_abstruct_function以下の関数に実体を設定して使います。
+ */
+typedef struct NyLPC_TcModWebSocket NyLPC_TcModWebSocket_t;
+
+
+#define NyLPC_TcModWebSocket_FRAME_TYPE_BIN 0x01
+#define NyLPC_TcModWebSocket_FRAME_TYPE_TXT 0x02
+
+/**
+ * クラス構造体
+ */
+struct NyLPC_TcModWebSocket
+{
+	NyLPC_TcModRomFiles_t super;
+	/**
+	 * サブプロトコル。NULLの場合0
+	 */
+	const NyLPC_TChar* _ref_sub_protocol;
+	/**ペイロードの解析ステータス*/
+	NyLPC_TUInt8 _payload_st;
+	NyLPC_TUInt8 _frame_type;
+	/**
+	 * BIT0: MASK value
+	 */
+	NyLPC_TUInt8 _frame_flags_bits;
+	NyLPC_TUInt8 _frame_mask[4];
+	/** ペイロードサイズ*/
+	NyLPC_TUInt16 payload_size;
+	/** ペイロード位置*/
+	NyLPC_TUInt16 payload_ptr;
+	NyLPC_TcHttpdConnection_t* _ref_connection;
+};
+
+/**
+ * コンストラクタ。
+ */
+void NyLPC_cModWebSocket_initialize(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_ref_root_path);
+
+void NyLPC_cModWebSocket_finalize(NyLPC_TcModWebSocket_t* i_inst);
+
+/**
+ * モジュールがコネクションをハンドリングできるかを返します。
+ */
+NyLPC_TBool NyLPC_cModWebSocket_canHandle(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TcHttpdConnection_t* i_connection);
+
+/**
+ * モジュールを実行します。
+ */
+NyLPC_TBool NyLPC_cModWebSocket_execute(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TcHttpdConnection_t* i_connection);
+
+
+/**
+ * i_bufに最大i_buf_lenバイトのデータを受信します。
+ * @return
+ * n>0:受信成功。nバイトのデータを受信した。
+ * 0  :タイムアウト。コネクションの状態は変化しない。
+ * -1 :エラー。 コネクションはNyLPC_TcModWebSocket_ST_CLOSEDへ遷移する。
+ */
+NyLPC_TInt16 NyLPC_cModWebSocket_read(NyLPC_TcModWebSocket_t* i_inst,void* i_buf,NyLPC_TInt16 i_buf_len);
+/**
+ * i_bufからi_lenバイトのデータを送信します。データは1ペーロードとしてクライアントへ送信されます。
+ * @return
+ * true: 送信に成功した。
+ * false:送信に失敗した。 コネクションはNyLPC_TcModWebSocket_ST_CLOSEDへ遷移する。
+ */
+NyLPC_TBool NyLPC_cModWebSocket_write(NyLPC_TcModWebSocket_t* i_inst,void* i_buf,NyLPC_TInt16 i_len);
+/**
+ * 書式文字列を出力します。
+ */
+NyLPC_TBool NyLPC_cModWebSocket_writeFormat(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,...);
+
+/**
+ * CLOSEパケットを送信してコネクションを閉じます。
+ * i_codeにはWebsocketのコード
+ */
+void NyLPC_cModWebSocket_close(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TUInt16 i_code);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* NYLPC_CMODWEBSOCKET_H_ */
--- a/core/net/upnp/NyLPC_cSsdpSocket.c	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/net/upnp/NyLPC_cSsdpSocket.c	Fri Sep 13 06:38:16 2013 +0000
@@ -75,38 +75,7 @@
 // *であるかを確認 未実装
 	return NyLPC_TBool_TRUE;
 }
-static NyLPC_TInt16 printIpAddr(const struct NyLPC_TIPv4Addr* i_ip,NyLPC_TChar* i_buf)
-{
-	NyLPC_TUInt32 ip;
-	NyLPC_TUInt8 v;
-	NyLPC_TInt8 l;
-	NyLPC_TChar* p=i_buf;
-	//IPをホストオーダーにする。
-	ip=NyLPC_NTOHL(i_ip->v);
-	for(l=3;l>=0;l--){
-		v=(ip>>(8*l))&0xff;
-		if(v<10){
-			//1桁
-			*(p+0)=v+'0';
-			*(p+1)='.';
-			p+=2;
-		}else if(v<100){
-			//2桁
-			*(p+0)=(v/10)+'0';
-			*(p+1)=(v%10)+'0';
-			*(p+2)='.';
-			p+=3;
-		}else{
-			//3桁
-			*(p+0)=(v/100)+'0';
-			*(p+1)=((v/10)%10)+'0';
-			*(p+2)=(v%10)+'0';
-			*(p+3)='.';
-			p+=4;
-		}
-	}
-	return p-i_buf-1;
-}
+
 #define TIMEOUT_IN_MS 100
 
 /**
@@ -137,7 +106,7 @@
 {
 	NyLPC_TChar* obuf;
 	NyLPC_TUInt16 l;
-	NyLPC_TUInt16 len_usn=(NyLPC_TUInt16)(i_usn!=NULL?strlen(i_usn):0);
+	NyLPC_TUInt16 len_usn=(NyLPC_TUInt16)((i_usn!=NULL)?strlen(i_usn):0);
 	NyLPC_TUInt16 len_udn=(NyLPC_TUInt16)strlen(i_udn);
 	NyLPC_TUInt16 len_location=(NyLPC_TUInt16)strlen(i_inst->location_path);
 
@@ -171,7 +140,7 @@
 		"LOCATION: http://");
 	l+=strlen(obuf);
 	//IP addr:port\r\n
-	l+=printIpAddr(NyLPC_cUdpSocket_getSockIP(&i_inst->super),obuf+l);
+	l+=NyLPC_TIPv4Addr_toString(NyLPC_cUdpSocket_getSockIP(&i_inst->super),obuf+l);
 	*(obuf+l)=':';
 	l+=1+NyLPC_itoa(i_inst->location_port,obuf+l+1,10);
 	*(obuf+l)='/';l++;
@@ -220,7 +189,7 @@
 {
 	NyLPC_TChar* obuf;
 	NyLPC_TUInt16 l,l2;
-	NyLPC_TUInt16 len_usn=(NyLPC_TUInt16)(i_usn!=NULL?strlen(i_usn):0);
+	NyLPC_TUInt16 len_usn=(NyLPC_TUInt16)((i_usn!=NULL)?strlen(i_usn):0);
 	NyLPC_TUInt16 len_udn=(NyLPC_TUInt16)strlen(i_udn);
 	NyLPC_TUInt16 len_location=(NyLPC_TUInt16)strlen(i_inst->location_path);
 
@@ -233,7 +202,7 @@
 	//	"LOCATION: http://xxx.xxx.xxx.xxx:nnnnn/%s/d.xml\r\n"//44+2=46
 	//	"USN: %s%s\r\n"									//5+2=7
 	//	"NT: %s\r\n\r\n"								//4+4=8
-	l2=204+len_location+len_usn+len_udn+(len_usn>0?len_usn:len_udn);
+	l2=204+len_location+len_usn+len_udn+((len_usn>0)?len_usn:len_udn);
 	obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->super),l2,&l,TIMEOUT_IN_MS);
 	if(obuf==NULL){
 		return NULL;
@@ -255,7 +224,7 @@
 		"LOCATION: http://");
 	l+=strlen(obuf);
 	//IP addr:port\r\n
-	l+=printIpAddr(NyLPC_cUdpSocket_getSockIP(&i_inst->super),obuf+l);
+	l+=NyLPC_TIPv4Addr_toString(NyLPC_cUdpSocket_getSockIP(&i_inst->super),obuf+l);
 	*(obuf+l)=':';
 	l+=1+NyLPC_itoa(i_inst->location_port,obuf+l+1,10);
 	*(obuf+l)='/';l++;
--- a/core/uip/NyLPC_cBaseSocket.c	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/uip/NyLPC_cBaseSocket.c	Fri Sep 13 06:38:16 2013 +0000
@@ -0,0 +1,9 @@
+#include "NyLPC_cBaseSocket.h"
+#include "NyLPC_cUipService_protected.h"
+
+void NyLPC_cBaseSocket_initialize(NyLPC_TcBaseSocket_t* i_inst,NyLPC_TUInt8 i_typeid)
+{
+    NyLPC_TcUipService_t* srv=_NyLPC_TcUipService_inst;
+    i_inst->_typeid=i_typeid;
+    i_inst->_parent_ipv4=&(srv->_tcpv4);
+}
--- a/core/uip/NyLPC_cBaseSocket.h	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/uip/NyLPC_cBaseSocket.h	Fri Sep 13 06:38:16 2013 +0000
@@ -30,6 +30,7 @@
 #endif /* __cplusplus */
 
 #include "NyLPC_stdlib.h"
+#include "NyLPC_cIPv4_typedef.h"
 
 /**
  * Base socket class
@@ -44,9 +45,13 @@
 struct NyLPC_TcBaseSocket
 {
     /**タイプID 継承クラスのinitializerで設定。 */
-    NyLPC_TUInt32 _typeid;
+    NyLPC_TUInt8 _typeid;
+    NyLPC_TUInt8 _padding8;
+    NyLPC_TUInt16 _padding16;
+    /** 所属してるIPv4コンローラ*/
+    NyLPC_TcIPv4_t* _parent_ipv4;
 };
-#define NyLPC_cBaseSocket_initialize(i_inst,i_typeid) ((i_inst)->_typeid=i_typeid)
+void NyLPC_cBaseSocket_initialize(NyLPC_TcBaseSocket_t* i_inst,NyLPC_TUInt8 i_typeid);
 #define NyLPC_cBaseSocket_finalize(i_inst)
 
 
--- a/core/uip/NyLPC_cIPv4.c	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/uip/NyLPC_cIPv4.c	Fri Sep 13 06:38:16 2013 +0000
@@ -170,7 +170,40 @@
     }
     return NULL;
 }
-
+/**
+ * 指定番号のTCPポートが未使用かを返す。
+ * @return
+ * i_lport番のポートが未使用であればTRUE
+ */
+static NyLPC_TBool cSocketTbl_isClosedTcpPort(
+    NyLPC_TcPtrTbl_t* i_inst,
+    NyLPC_TUInt16 i_lport)
+{
+    NyLPC_TcBaseSocket_t** p=(NyLPC_TcBaseSocket_t**)(i_inst->buf);
+    NyLPC_TcTcpSocket_t* tp;
+    int i;
+    //一致するポートを検索
+    for(i=i_inst->size-1;i>=0;i--){
+        if(p[i]==NULL){
+            continue;
+        }
+        if(p[i]->_typeid!=NyLPC_TcBaseSocket_TYPEID_TCP_SOCK){
+            tp=((NyLPC_TcTcpSocket_t*)p[i]);
+            //TCPソケット && !クローズ  && ポート一致なら使用中
+            if((tp->tcpstateflags!=UIP_CLOSED) && tp->uip_connr.lport==i_lport){
+                return NyLPC_TBool_FALSE;
+            }
+        }
+        if(p[i]->_typeid!=NyLPC_TcBaseSocket_TYPEID_TCP_LISTENER){
+            //Listenerソケット  && ポート一致なら使用中
+            if(((NyLPC_TcTcpListener_t*)p[i])->_port==i_lport){
+                return NyLPC_TBool_FALSE;
+            }
+        }
+    }
+    //未使用
+    return NyLPC_TBool_TRUE;
+}
 /**
  * テーブルにある有効なソケットのperiodicをすべて呼び出します。
  */
@@ -273,6 +306,7 @@
     //instanceの初期化
     NyLPC_cMutex_initialize(&(i_inst->_sock_mutex));
     NyLPC_cMutex_initialize(&(i_inst->_listener_mutex));
+    i_inst->tcp_port_counter=0;
     i_inst->_ref_config=NULL;
     return;
 }
@@ -399,10 +433,24 @@
     return NyLPC_TBool_FALSE;
 }
 
+NyLPC_TUInt16 NyLPC_cIPv4_getNewPortNumber(NyLPC_TcIPv4_t* i_inst)
+{
+    NyLPC_TUInt16 i,n;
+    for(i=0;i<0x0fff;i--){
+        i_inst->tcp_port_counter=(i_inst->tcp_port_counter+1)%0x0fff;
+        n=i_inst->tcp_port_counter+49152;
+        if(cSocketTbl_isClosedTcpPort(&i_inst->_socket_tbl,n))
+        {
+            return n;
+        }
+    }
+    return 0;
+}
+
 
 /**********************************************************************
  *
- * public function
+ * packet handler
  *
  **********************************************************************/
 
--- a/core/uip/NyLPC_cIPv4.h	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/uip/NyLPC_cIPv4.h	Fri Sep 13 06:38:16 2013 +0000
@@ -71,24 +71,14 @@
 #endif /* __cplusplus */
 
 
-/**
- * クラス型を定義します。
- * NyLPC_cIPv4クラスは、NyLPC_cUipServiceクラスの一部として働きます。
- * 通常ユーザが操作することはありません。
- * IPv4における、ソケットクラス(NyLPC_cTcpSocketとNyLPC_cTcpListener)の管理を担当します。
- * クラスのインスタンスは、NyLPC_cUipServiceのインスタンスにより生成されます。
- * インスタンスは2つのポインタリストをもち、ここにこれらのインスタンスを登録します。
- * インスタンスは、NyLPC_cUipServiceから送られてきた受信パケットを、登録されているソケットクラスに
- * ディスパッチする機能を持ちます。
- */
-typedef struct NyLPC_TcIPv4 NyLPC_TcIPv4_t;
+
 
 /**********************************************************************
  *
  * class NyLPC_TcIPv4
  *
  **********************************************************************/
-
+#include "NyLPC_cIPv4_typedef.h"
 
 ///**
 // * 環境定数です。NyLPC_TcTcpListenerインスタンスリストの数を設定します。
@@ -119,6 +109,8 @@
     NyLPC_TcPtrTbl_t _socket_tbl;
     /** _socket_tblが使用するメモリ領域です。*/
     NyLPC_TcBaseSocket_t* _socket_array_buf[NyLPC_cIPv4_MAX_SOCKET];
+    /** 0-0xfffまでを巡回するカウンタ*/
+    NyLPC_TUInt16 tcp_port_counter;
 };
 
 /**
@@ -225,6 +217,15 @@
  */
 #define NyLPC_cIPv4_getListenerMutex(i_inst) (&((i_inst)->_listener_mutex))
 
+/**
+ * ポート0で使用するポート番号を返します。
+ * @return
+ * 49152 - (49152+0x0ffff)番までのポートのうち、使用中でないポート番号を返します。
+ * エラー時は0です。
+ */
+NyLPC_TUInt16 NyLPC_cIPv4_getNewPortNumber(NyLPC_TcIPv4_t* i_inst);
+
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
--- a/core/uip/NyLPC_cIPv4Config.h	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/uip/NyLPC_cIPv4Config.h	Fri Sep 13 06:38:16 2013 +0000
@@ -57,15 +57,15 @@
  */
 struct NyLPC_TcIPv4Config
 {
-    /** イーサネットアドレスを格納します。*/
+    /** イーサネットアドレスを格納します。 */
     struct NyLPC_TEthAddr eth_mac;
-    /** IPアドレスを格納します。Network orderです。*/
+    /** IPアドレスを格納します。Network orderです。 */
     struct NyLPC_TIPv4Addr ip_addr;
-    /** ネットマスクを格納します。Network orderです。*/
+    /** ネットマスクを格納します。Network orderです。 */
     struct NyLPC_TIPv4Addr netmask;
-    /** デフォルトゲートウェイアドレスを格納します。Network orderです。*/
+    /** デフォルトゲートウェイアドレスを格納します。Network orderです。 */
     struct NyLPC_TIPv4Addr dr_addr;
-    /** デフォルトMMSサイズです。送信パケットのMSS値、受信パケットのデフォルトMSS値として使います。*/
+    /** デフォルトMMSサイズです。送信パケットのMSS値、受信パケットのデフォルトMSS値として使います。 */
     NyLPC_TUInt16 default_mss;
 };
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/uip/NyLPC_cIPv4_typedef.h	Fri Sep 13 06:38:16 2013 +0000
@@ -0,0 +1,17 @@
+#ifndef NYLPC_CIPV4_TYPEDEF_H_
+#define NYLPC_CIPV4_TYPEDEF_H_
+
+/**
+ * クラス型を定義します。
+ * NyLPC_cIPv4クラスは、NyLPC_cUipServiceクラスの一部として働きます。
+ * 通常ユーザが操作することはありません。
+ * IPv4における、ソケットクラス(NyLPC_cTcpSocketとNyLPC_cTcpListener)の管理を担当します。
+ * クラスのインスタンスは、NyLPC_cUipServiceのインスタンスにより生成されます。
+ * インスタンスは2つのポインタリストをもち、ここにこれらのインスタンスを登録します。
+ * インスタンスは、NyLPC_cUipServiceから送られてきた受信パケットを、登録されているソケットクラスに
+ * ディスパッチする機能を持ちます。
+ */
+typedef struct NyLPC_TcIPv4 NyLPC_TcIPv4_t;
+
+#endif /* NYLPC_CIPV4_PUBLIC_H_ */
+
--- a/core/uip/NyLPC_cTcpListener.c	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/uip/NyLPC_cTcpListener.c	Fri Sep 13 06:38:16 2013 +0000
@@ -98,9 +98,10 @@
 
 
 
-
-#define lockResource(i_inst) NyLPC_cMutex_lock(((i_inst)->_mutex))
-#define unlockResource(i_inst) NyLPC_cMutex_unlock(((i_inst)->_mutex))
+//#define lockResource(i_inst) NyLPC_cMutex_lock(((i_inst)->_mutex))
+//#define unlockResource(i_inst) NyLPC_cMutex_unlock(((i_inst)->_mutex))
+#define lockResource(i_inst) NyLPC_cMutex_lock(NyLPC_cIPv4_getListenerMutex(((i_inst)->_super._parent_ipv4)))
+#define unlockResource(i_inst) NyLPC_cMutex_unlock(NyLPC_cIPv4_getListenerMutex(((i_inst)->_super._parent_ipv4)))
 
 
 /**
@@ -114,8 +115,8 @@
     //uipサービスは初期化済であること。
     NyLPC_Assert(NyLPC_TcUipService_isInitService());
     //初期化
-    //  NyLPC_cMutex_initialize(&(i_inst->_mutex));
-    i_inst->_mutex=NyLPC_cIPv4_getListenerMutex(&srv->_tcpv4);//    NyLPC_cMutex_initialize(&(i_inst->_mutex));
+//  //  NyLPC_cMutex_initialize(&(i_inst->_mutex));
+//  i_inst->_mutex=NyLPC_cIPv4_getListenerMutex(&srv->_tcpv4);//    NyLPC_cMutex_initialize(&(i_inst->_mutex));
     i_inst->_port=NyLPC_htons(i_port);
     //管理リストへ登録。
     return NyLPC_cIPv4_addSocket(&(srv->_tcpv4),&(i_inst->_super));
--- a/core/uip/NyLPC_cTcpListener.h	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/uip/NyLPC_cTcpListener.h	Fri Sep 13 06:38:16 2013 +0000
@@ -65,11 +65,11 @@
 {
     NyLPC_TcBaseSocket_t _super;
     NyLPC_TUInt16 _port;                /**<ネットワークオーダーのポート番号*/
-    /**
-     * タスク間の調停用Mutex
-     * Listener用の共通Mutexポインタ
-     */
-    NyLPC_TcMutex_t* _mutex;
+//  /**
+//   * タスク間の調停用Mutex
+//   * Listener用の共通Mutexポインタ
+//   */
+//  NyLPC_TcMutex_t* _mutex;
     /**
      * SYNパケットのキュー
      */
--- a/core/uip/NyLPC_cTcpSocket.c	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/uip/NyLPC_cTcpSocket.c	Fri Sep 13 06:38:16 2013 +0000
@@ -31,6 +31,29 @@
 static NyLPC_TUInt32 iss32=3939;
 #define SIZE_OF_IPv4_TCPIP_HEADER 40
 
+/**
+ * TCPのRTOの最大値。
+ * ms単位である。
+ * defaultは64SEC
+ */
+#define UIP_IP_RTO_MAX_RTO 64000
+/**
+ * TCPのRTOの初期値。
+ * ms単位である。
+ * 伝送路の特性に合わせて調整すること。
+ */
+#define UIP_TCP_RTO_INITIAL 3000
+
+/**
+ * CONNECTION時のRTO
+ */
+#define UIP_TCP_RTO_CONNECTION_INITIAL 200
+
+/**
+ * 下限値
+ */
+#define UIP_TCP_RTO_MINIMUM 100
+
 
 /**
  * for Debug
@@ -44,11 +67,10 @@
     #define DEBUG_RTO_LOG(i_inst)
 #endif
 
-
 //#define lockResource(i_inst) NyLPC_cMutex_lock(&((i_inst)->_smutex))
 //#define unlockResource(i_inst) NyLPC_cMutex_unlock(&((i_inst)->_smutex))
-#define lockResource(i_inst) NyLPC_cMutex_lock(((i_inst)->_smutex))
-#define unlockResource(i_inst) NyLPC_cMutex_unlock(((i_inst)->_smutex))
+#define lockResource(i_inst) NyLPC_cMutex_lock(NyLPC_cIPv4_getSockMutex(((i_inst)->_super._parent_ipv4)))
+#define unlockResource(i_inst) NyLPC_cMutex_unlock(NyLPC_cIPv4_getSockMutex(((i_inst)->_super._parent_ipv4)))
 
 static void sendRst(NyLPC_TcTcpSocket_t* i_inst);
 
@@ -225,8 +247,8 @@
         break;
     }
     NyLPC_cStopwatch_finalize(&sw);
-    if(new_rto<UIP_IP_RTO_MINIMUM){
-        new_rto=UIP_IP_RTO_MINIMUM;
+    if(new_rto<UIP_TCP_RTO_MINIMUM){
+        new_rto=UIP_TCP_RTO_MINIMUM;
     }
     i_inst->uip_connr.current_rto32=new_rto;
 }
@@ -312,7 +334,7 @@
 
     NyLPC_cFifoBuffer_initialize(&(i_inst->rxbuf),i_rbuf,i_rbuf_len);
     //  NyLPC_AbortIfNot(NyLPC_cMutex_initialize(&(i_inst->_smutex)));//個別Mutex
-    i_inst->_smutex=NyLPC_cIPv4_getSockMutex(&(srv->_tcpv4));//共有Mutex
+//  i_inst->_smutex=NyLPC_cIPv4_getSockMutex(&(srv->_tcpv4));//共有Mutex
     i_inst->tcpstateflags=UIP_CLOSED;
     i_inst->txbuf.rp=i_inst->txbuf.wp=0;
     for(i=0;i<NyLPC_TcTcpSocket_NUMBER_OF_TXQ;i++){
@@ -356,7 +378,7 @@
     {
         //localipとdefault_mmsは別枠で設定
         /* Fill in the necessary fields for the new connection. */
-        i_inst->uip_connr.current_rto32 = UIP_IP_RTOP_INITIAL;
+        i_inst->uip_connr.current_rto32 = UIP_TCP_RTO_INITIAL;
         i_inst->uip_connr.lport = i_lport;
         i_inst->uip_connr.rport = i_lq->rport;
         i_inst->uip_connr.ripaddr=i_lq->srcaddr;
@@ -364,20 +386,17 @@
         /* rcv_nxt should be the seqno from the incoming packet + 1. */
         i_inst->uip_connr.rcv_nxt32= i_lq->rcv_nxt32;
         //MSSの設定
-        i_inst->uip_connr.peer_mss=i_inst->uip_connr.default_mss;
-        if(i_lq->mss!=0){
-            i_inst->uip_connr.peer_mss=i_lq->mss;
-        }
+        i_inst->uip_connr.peer_mss=(i_lq->mss!=0)?i_lq->mss:i_inst->uip_connr.default_mss;
         i_inst->uip_connr.peer_win=0;
         NyLPC_cFifoBuffer_clear(&(i_inst->rxbuf));
+        //ここでステータスがかわる。
+        i_inst->tcpstateflags = UIP_SYN_RCVD;
         //前回のデータが残っていた場合の保険
         if(i_inst->txbuf.rp!=i_inst->txbuf.wp){
             resetTxQWithUnlock(i_inst);
         }else{
             unlockResource(i_inst);
         }
-        //ここでステータスがかわる。
-        i_inst->tcpstateflags = UIP_SYN_RCVD;
         return NyLPC_TBool_TRUE;
     }
     unlockResource(i_inst);
@@ -496,7 +515,7 @@
         s=i_len;
     }
     //ACK番号の計算
-    next_ack=i_inst->uip_connr.snd_nxt32+s+((i_tcpf&(TCP_FIN|TCP_SYN))!=0x00?1:0);
+    next_ack=i_inst->uip_connr.snd_nxt32+s+(((i_tcpf&(TCP_FIN|TCP_SYN))!=0x00)?1:0);
     txq->rto32=i_inst->uip_connr.current_rto32;
     txq->tick_of_sent=NyLPC_cStopwatch_now();
 
@@ -561,6 +580,7 @@
         //エラー:ドロップする。
         return NyLPC_TBool_FALSE;
     }
+
     return NyLPC_TBool_TRUE;
 }
 
@@ -571,6 +591,77 @@
  * Public function
  */
 
+NyLPC_TBool NyLPC_cTcpSocket_connect(NyLPC_TcTcpSocket_t* i_inst,struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_peer_port,NyLPC_TUInt32 i_wait_in_msec)
+{
+    volatile NyLPC_TUInt8 f;
+    NyLPC_TUInt32 sq;
+    NyLPC_TcStopwatch_t sw;
+    NyLPC_TUInt16 lport;
+    lockResource(i_inst);
+    //ソケットが無効であること。
+    if(i_inst->tcpstateflags!=UIP_CLOSED)
+    {
+        NyLPC_OnErrorGoto(Error);
+    }
+    //ポート番号の取得(lockResourceが他のソケットと共有なので、重複ポートの割当は起こりえない。でもちょっと注意して)
+    lport=NyLPC_htons(NyLPC_cIPv4_getNewPortNumber(i_inst->_super._parent_ipv4));
+    if(lport==0){
+        NyLPC_OnErrorGoto(Error);
+    }
+    //connectの為の準備
+
+    //localipとdefault_mmsは別枠で設定
+    /* Fill in the necessary fields for the new connection. */
+    i_inst->uip_connr.current_rto32 = UIP_TCP_RTO_CONNECTION_INITIAL;//RTOを短くしてARP発行時の再接続短縮を期待する。
+    i_inst->uip_connr.lport = lport;
+    i_inst->uip_connr.rport = NyLPC_htons(i_peer_port);
+    i_inst->uip_connr.ripaddr=*i_addr;
+    i_inst->uip_connr.snd_nxt32=iss32;//should be random
+    /* rcv_nxt should be the seqno from the incoming packet + 1. */
+    i_inst->uip_connr.rcv_nxt32=0;
+    //MSSの設定
+    i_inst->uip_connr.peer_mss=i_inst->uip_connr.default_mss;
+    i_inst->uip_connr.peer_win=1;//periodicの再送信を期待するために相手のWindowサイズは1と仮定する。
+    NyLPC_cFifoBuffer_clear(&(i_inst->rxbuf));
+    //ここでステータスがかわる。
+    i_inst->tcpstateflags = UIP_SYN_SENT;
+    //前回のデータが残っていた場合の保険
+    if(i_inst->txbuf.rp!=i_inst->txbuf.wp){
+        resetTxQWithUnlock(i_inst);
+    }else{
+        unlockResource(i_inst);
+    }
+
+    NyLPC_cStopwatch_initialize(&sw);
+
+    NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec);
+    if(sendWithRetransmit(i_inst,TCP_SYN,NULL,0,&sw,&sq)==0){
+        //ちょっと待つ。
+        NyLPC_cThread_yield();
+        //キューにあるTXが消えるのを待つ。
+        if(waitForTxRemove(i_inst,sq,&sw)){
+            //ACK受信に成功して、TXが消失
+            NyLPC_cStopwatch_finalize(&sw);
+            return NyLPC_TBool_TRUE;
+        }
+    }
+    //ロックして、強制的なステータス遷移
+    lockResource(i_inst);
+    f=i_inst->tcpstateflags;
+    if(f!=UIP_CLOSED){
+        //もし、強制CLOSE遷移であれば、RSTも送信。
+        i_inst->tcpstateflags=UIP_CLOSED;
+        unlockResource(i_inst);
+        sendRst(i_inst);
+    }else{
+        unlockResource(i_inst);
+    }
+    return NyLPC_TBool_FALSE;
+Error:
+    unlockResource(i_inst);
+    return NyLPC_TBool_FALSE;
+}
+
 /**
  * この関数は、UIP_SYN_RCVDステータスのソケットを、ESTABLISHEDへ遷移させます。
  * cTcpListener_listen関数を通過したインスタンスに実行してください。
@@ -612,12 +703,12 @@
     lockResource(i_inst);
     f=i_inst->tcpstateflags;
     if(f!=UIP_CLOSED){
+        //もし、強制CLOSE遷移であれば、RSTも送信。
         i_inst->tcpstateflags=UIP_CLOSED;
-    }
-    unlockResource(i_inst);
-    //もし、強制CLOSE遷移であれば、RSTも送信。
-    if(f!=UIP_CLOSED){
+        unlockResource(i_inst);
         sendRst(i_inst);
+    }else{
+        unlockResource(i_inst);
     }
     return NyLPC_TBool_FALSE;
 }
@@ -861,7 +952,7 @@
     if(i_len<1){
         return 0;
     }
-    hint=(i_len>32767)?32767:0;
+    hint=(i_len>32767)?32767:i_len;
     buf=NyLPC_cTcpSocket_allocSendBuf(i_inst,hint,&s,i_wait_in_msec);
     if(buf==NULL){
         return -1;
@@ -967,12 +1058,12 @@
     lockResource(i_inst);
     f=i_inst->tcpstateflags;
     if(f!=UIP_CLOSED){
+        //もし、強制CLOSE遷移であれば、RSTも送信。
         i_inst->tcpstateflags=UIP_CLOSED;
-    }
-    unlockResource(i_inst);
-    //もし、強制CLOSE遷移であれば、RSTも送信。
-    if(f!=UIP_CLOSED){
+        unlockResource(i_inst);
         sendRst(i_inst);
+    }else{
+        unlockResource(i_inst);
     }
     NyLPC_cStopwatch_finalize(&sw);
     return;
@@ -1149,8 +1240,8 @@
                 }
             }
         }
-        //MSSとWNDの更新
-        i_inst->uip_connr.peer_mss = i_inst->uip_connr.default_mss;
+//      //MSSとWNDの更新
+//      i_inst->uip_connr.peer_mss = i_inst->uip_connr.default_mss;//@bug じゃないのこれ。peer_mss勝手に上書きしたらダメだろ
         //どちらにしろ、ACK送信
         if(is_new_packet && (in_tcpflag & TCP_FIN)){
             //FINがあるときは、ステータスをCLOSE_WAITへセットして、ACKを返す。
@@ -1200,10 +1291,21 @@
         break;
     case UIP_CLOSED:
         //何もできない。何もしない。
-        break;//goto DROP;
+        break;
     case UIP_TIME_WAIT:
         //最終ACKを送り続ける。
         break;
+    case UIP_SYN_SENT:
+        //connect関数実行中しか起動しないステータス
+        if(num_of_noack==0){
+            i_inst->tcpstateflags=UIP_ESTABLISHED;
+            i_inst->uip_connr.rcv_nxt32=NyLPC_ntohl(o_ipp->payload.tcp->seqno32)+1;
+        }else{
+            //それ以外のパケットはドロップする。
+            break;//goto DROP;
+        }
+        //ACKを送る。
+        break;
     default:
         goto DROP;
     }
--- a/core/uip/NyLPC_cTcpSocket.h	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/uip/NyLPC_cTcpSocket.h	Fri Sep 13 06:38:16 2013 +0000
@@ -139,10 +139,12 @@
         struct NyLPC_TcTcpSocket_TxQItem txq[NyLPC_TcTcpSocket_NUMBER_OF_TXQ];
     }txbuf;
     volatile NyLPC_TUInt8 tcpstateflags; /**< TCP state and flags. */
-    /** 共通MUTEXへのポインタ(うまくいtったらこのままで)*/
-    NyLPC_TcMutex_t* _smutex;
 };
 
+
+#define NyLPC_cTcpSocket_getPeerAddr(i_inst) (&((i_inst)->uip_connr.ripaddr))
+#define NyLPC_cTcpSocket_getPeerPort(i_inst) (((i_inst)->uip_connr.rport))
+
 /**
  * 初期化関数です。
  * uipserviceは初期化済である必要があります。
@@ -159,6 +161,12 @@
 void NyLPC_cTcpSocket_finalize(NyLPC_TcTcpSocket_t* i_inst);
 
 NyLPC_TBool NyLPC_cTcpSocket_accept(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_wait_in_msec);
+/**
+ * @return
+ *  1 - 以上:受信に成功した。
+ *  0 - タイムアウト
+ * -1 - ソケットがクローズしている
+ */
 NyLPC_TInt32 NyLPC_cTcpSocket_precv(NyLPC_TcTcpSocket_t* i_inst,const void** o_buf_ptr,NyLPC_TUInt32 i_wait_msec);
 void NyLPC_cTcpSocket_pseek(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt16 i_seek);
 /**
@@ -205,6 +213,11 @@
  */
 NyLPC_TBool NyLPC_cTcpSocket_psend(NyLPC_TcTcpSocket_t* i_inst,void* i_buf_ptr,int i_len,NyLPC_TUInt32 i_wait_in_msec);
 
+/**
+ * TCPソケットをクライアントとしてサーバへ接続します。
+ */
+NyLPC_TBool NyLPC_cTcpSocket_connect(NyLPC_TcTcpSocket_t* i_inst,struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_peer_port,NyLPC_TUInt32 i_wait_in_msec);
+
 
 #ifdef __cplusplus
 }
--- a/core/uip/NyLPC_cUipService.c	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/uip/NyLPC_cUipService.c	Fri Sep 13 06:38:16 2013 +0000
@@ -95,7 +95,7 @@
         struct NyLPC_TArpHeader arp;
         struct NyLPC_TIPv4Header ipv4;
     }data;
-};
+}PACK_STRUCT_END;
 
 
 
@@ -122,7 +122,7 @@
 
 static NyLPC_TBool sendIPv4Tx(struct NyLPC_TTxBufferHeader* i_eth_buf);
 static void copyAndSendIPv4Tx(const struct TEthPacket* i_buf);
-static void sendArpReqest(const struct TEthPacket* i_eth_packet);
+//static void sendArpReqest(const struct TEthPacket* i_eth_packet);
 static void sendRawEthFrame(void* i_buf,NyLPC_TUInt16 i_len);
 static void emacIsrHandler(unsigned long i_status);
 
@@ -136,7 +136,6 @@
 
 NyLPC_TcThread_t th;
 
-void led(int i);
 NyLPC_TBool NyLPC_cUipService_initialize(void)
 {
     NyLPC_TcUipService_t* inst=&_service_instance;
@@ -396,31 +395,10 @@
 }
 
 
-
-
 /**
- * allocTxBufで取得したメモリを"IPパケットとして"送信します。
- * @param i_eth_payload
- * [NyLPC_TTxBufferHeader][NyLPC_TEthernetIIHeader][payload]メモリの、[payload]のアドレスを指定します。
- * 通常は、NyLPC_cUipService_allocTxBufの返却したメモリを指定します。
+ * IPv4パケットのpeerIPを問い合わせるARPパケットを送信します。
  */
-
-void NyLPC_cUipService_sendIPv4Tx(void* i_eth_payload)
-{
-    NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
-    NyLPC_cMutex_lock(&(inst->_mutex));
-    //IPパケットの送信を試行
-    if(!sendIPv4Tx(((struct NyLPC_TTxBufferHeader*)(((struct NyLPC_TEthernetIIHeader*)i_eth_payload)-1))-1)){
-        //ARPリクエストを代わりに送信
-        sendArpReqest(((struct TEthPacket*)i_eth_payload)-1);
-    }
-    NyLPC_cMutex_unlock(&(inst->_mutex));
-    return;
-}
-/**
- * 指定したIPアドレスに対してARPRequestを送信します。
- */
-void NyLPC_cUipService_sendArpRequest(const struct NyLPC_TIPv4Addr* i_addr)
+static void sendArpReqest(const struct NyLPC_TIPv4Addr* i_addr)
 {
     NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
     NyLPC_TUInt16 tx_len;
@@ -431,10 +409,48 @@
     }
     //ARPパケットを作る。
     ethbuf=(struct TEthPacket*)(inst->stx.buf);
-    NyLPC_TArpHeader_setArpRequest(&(ethbuf->data.arp),inst->_ref_config->ip_addr,&(inst->_ref_config->eth_mac),*i_addr);
+    NyLPC_TArpHeader_setArpRequest(&(ethbuf->data.arp),inst->_ref_config->ip_addr,&(inst->_ref_config->eth_mac),i_addr);
     tx_len=NyLPC_TEthernetIIHeader_setArpTx(&(ethbuf->header),&(inst->_ref_config->eth_mac));
     //送信
     inst->_ethif->sendTxEthFrame(&(inst->stx.h),tx_len);
+}
+
+
+
+
+/**
+ * allocTxBufで取得したペイロードメモリを"IPパケットとして"送信します。
+ * @param i_eth_payload
+ * [NyLPC_TTxBufferHeader][NyLPC_TEthernetIIHeader][payload]メモリの、[payload]のアドレスを指定します。
+ * 通常は、NyLPC_cUipService_allocTxBufの返却したメモリを指定します。
+ */
+
+void NyLPC_cUipService_sendIPv4Tx(void* i_eth_payload)
+{
+    NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
+    struct NyLPC_TTxBufferHeader* p=((struct NyLPC_TTxBufferHeader*)(((struct NyLPC_TEthernetIIHeader*)i_eth_payload)-1))-1;
+    NyLPC_cMutex_lock(&(inst->_mutex));
+
+    //IPパケットの送信を試行
+    if(!sendIPv4Tx(p)){
+        //ARPリクエストを代わりに送信
+        sendArpReqest(&((struct NyLPC_TIPv4Header*)i_eth_payload)->destipaddr);
+    }
+    NyLPC_cMutex_unlock(&(inst->_mutex));
+    return;
+}
+
+
+
+/**
+ * 指定したIPアドレスに対してARPRequestを送信します。
+ */
+void NyLPC_cUipService_sendArpRequest(const struct NyLPC_TIPv4Addr* i_addr)
+{
+    NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
+    NyLPC_cMutex_lock(&(inst->_mutex));
+    sendArpReqest(i_addr);
+    NyLPC_cMutex_unlock(&(inst->_mutex));
     return;
 }
 
@@ -448,6 +464,8 @@
 }
 
 
+
+
 /**
  * 送信ペイロードメモリを返します。
  * この関数は、リエントラントを許容します。
@@ -501,7 +519,7 @@
  */
 
 /**
- * 新たにメモリを確保して、"IPv4パケットを格納した"イーサフレームを送信します。
+ * "IPv4パケットを格納した"イーサフレームを送信します。
  * コール前に、必ずロックしてから呼び出してください。
  */
 static void copyAndSendIPv4Tx(const struct TEthPacket* i_buf)
@@ -517,29 +535,13 @@
     memcpy(inst->stx.buf,i_buf,s);
     if(!sendIPv4Tx(&(inst->stx.h))){
         //失敗した場合はARPリクエストに変換して再送
-        sendArpReqest(i_buf);
+//@todo unchecked PASS!
+        sendArpReqest(&i_buf->data.ipv4.destipaddr);
     }
     return;
 }
-/**
- * IPv4パケットのpeerIPを問い合わせるARPパケットを送信します。
- */
-static void sendArpReqest(const struct TEthPacket* i_eth_packet)
-{
-    NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
-    NyLPC_TUInt16 tx_len;
-    struct TEthPacket* ethbuf;
-    //ACK送信用の自己バッファが空くまで待つ
-    while(inst->stx.h.is_lock){
-        inst->_ethif->processTx();
-    }
-    //ARPパケットを作る。
-    ethbuf=(struct TEthPacket*)(inst->stx.buf);
-    NyLPC_TArpHeader_setArpRequest(&(ethbuf->data.arp),inst->_ref_config->ip_addr,&(inst->_ref_config->eth_mac),i_eth_packet->data.ipv4.destipaddr);
-    tx_len=NyLPC_TEthernetIIHeader_setArpTx(&(ethbuf->header),&(inst->_ref_config->eth_mac));
-    //送信
-    inst->_ethif->sendTxEthFrame(&(inst->stx.h),tx_len);
-}
+
+
 
 /**
  * uipタスクが所有するTXバッファを使用してデータを送信します。
@@ -623,36 +625,4 @@
 
 
 
-//static void startEther()
-//{
-//  NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
-//
-//  //Ethernetの起動待ち
-//  while(lEMACInit(_NyLPC_TcUipService_inst->_emac_semapho,&(inst->_ref_config->eth_mac))!= pdPASS )
-//    {
-//        vTaskDelay( 100 / portTICK_RATE_MS );
-//    }
-//  //Ethernetの割込み開始設定
-//  portENTER_CRITICAL();
-//  {
-//      LPC_EMAC->IntEnable = ( INT_RX_DONE | INT_TX_DONE );
-//      /* Set the interrupt priority to the max permissible to cause some
-//      interrupt nesting. */
-//      NVIC_SetPriority( ENET_IRQn, configEMAC_INTERRUPT_PRIORITY );
-//
-//      /* Enable the interrupt. */
-//      NVIC_EnableIRQ( ENET_IRQn );
-//  }
-//  portEXIT_CRITICAL();
-//}
-//
-//static void stopEther()
-//{
-//  portENTER_CRITICAL();
-//  {
-//      LPC_EMAC->IntEnable = (~(INT_RX_DONE|INT_TX_DONE))&LPC_EMAC->IntEnable;
-//      NVIC_DisableIRQ( ENET_IRQn );
-//  }
-//  portEXIT_CRITICAL();
-//}
 
--- a/core/uip/NyLPC_uip.c	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/uip/NyLPC_uip.c	Fri Sep 13 06:38:16 2013 +0000
@@ -63,6 +63,34 @@
 const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_MULTICAST_MASK = NyLPC_TIPv4Addr_pack(224,0,0,0);
 const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_APIPA_MASK = NyLPC_TIPv4Addr_pack(255,255,0,0);
 
+NyLPC_TInt16 NyLPC_TIPv4Addr_toString(const struct NyLPC_TIPv4Addr* i_ip,NyLPC_TChar* i_buf)
+{
+    NyLPC_TUInt32 ip;
+    NyLPC_TChar* p=i_buf;
+    NyLPC_TUInt8 v;
+    NyLPC_TInt8 l;
+    //IPをホストオーダーにする。
+    ip=NyLPC_NTOHL(i_ip->v);
+    for(l=3;l>=0;l--){
+        v=(ip>>(8*l))&0xff;
+        if(v>100){
+            *p=(v/100)+'0';
+            v=v%100;
+            p++;
+        }
+        if(v>10){
+            *p=(v/10)+'0';
+            v=v%10;
+            p++;
+        }
+        *p=v+'0';
+        *(p+1)='.';
+        p+=2;
+    }
+    *(p-1)='\0';
+    return p-i_buf-1;
+}
+
 
 NyLPC_TUInt16 NyLPC_uip_chksum(NyLPC_TUInt16 sum, const NyLPC_TUInt8 *data, NyLPC_TUInt16 len)
 {
@@ -356,17 +384,17 @@
  *
  *------------------------------------------------------------------------------*/
 /**
- * 指定したIPアドレスに対する、ARP REQUESTをセットする。
+ * i_req_addrを問い合わせるARP_REQUESTを生成します。
  */
 void NyLPC_TArpHeader_setArpRequest(
     struct NyLPC_TArpHeader* i_struct,
     const struct NyLPC_TIPv4Addr i_saddr,
     const struct NyLPC_TEthAddr* i_srceth,
-    const struct NyLPC_TIPv4Addr i_daddr)
+    const struct NyLPC_TIPv4Addr* i_req_addr)
 {
     memset(i_struct->dhwaddr.addr, 0x00, 6);
     memcpy(i_struct->shwaddr.addr, i_srceth, 6);
-    i_struct->dipaddr=i_daddr;
+    i_struct->dipaddr=*i_req_addr;
     i_struct->sipaddr=i_saddr;
     i_struct->opcode = NyLPC_HTONS(ARP_REQUEST); /* ARP request. */
     i_struct->hwtype = NyLPC_HTONS(ARP_HWTYPE_ETH);
--- a/core/uip/NyLPC_uip.h	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/uip/NyLPC_uip.h	Fri Sep 13 06:38:16 2013 +0000
@@ -119,6 +119,12 @@
 #define NyLPC_TIPv4Addr_set(s,a0,a1,a2,a3) (s)->v=NyLPC_htonl((0xff000000&(((NyLPC_TUInt32)(a0))<<24))|(0x00ff0000&(((NyLPC_TUInt32)(a1))<<16))|(0x0000ff00&(((NyLPC_TUInt32)(a2))<<8))|(0x000000ff&((NyLPC_TUInt32)(a3))))
 #define NyLPC_TIPv4Addr_pack(a0,a1,a2,a3) {NyLPC_HTONL((0xff000000&(((NyLPC_TUInt32)(a0))<<24))|(0x00ff0000&(((NyLPC_TUInt32)(a1))<<16))|(0x0000ff00&(((NyLPC_TUInt32)(a2))<<8))|(0x000000ff&((NyLPC_TUInt32)(a3))))}
 
+/**
+ * IPアドレスを文字列に変換して返します。
+ */
+NyLPC_TInt16 NyLPC_TIPv4Addr_toString(const struct NyLPC_TIPv4Addr* i_ip,NyLPC_TChar* i_buf);
+
+
 
 
 
@@ -139,19 +145,6 @@
  */
 #define UIP_DEFAULT_IP_TTL 64
 
-/**
- * RTOの最大値。ms単位である。
- * 64sが標準値である。
- */
-#define UIP_IP_RTO_MAX_RTO 64000
-
-/**
- * RTOの初期値。ms単位である。
- * 伝送路の特性に合わせて調整すること。
- */
-#define UIP_IP_RTOP_INITIAL 3000
-
-#define UIP_IP_RTO_MINIMUM 100
 
 
 /**
@@ -188,7 +181,7 @@
 #       define NyLPC_ntohl(n) (n)
 #       define NyLPC_HTONS(n) (n)
 #       define NyLPC_NTOHS(n) (n)
-#   else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
+#   else
 #       define NyLPC_htonl(n) NyLPC_TUInt32_bswap(n)
 #       define NyLPC_ntohl(n) NyLPC_TUInt32_bswap(n)
 #       define NyLPC_htons(n) NyLPC_TUInt16_bswap(n)
@@ -429,11 +422,14 @@
 } PACK_STRUCT_END;
 
 
+/**
+ * i_req_addrを問い合わせるARP_REQUESTを生成します。
+ */
 void NyLPC_TArpHeader_setArpRequest(
     struct NyLPC_TArpHeader* i_struct,
     const struct NyLPC_TIPv4Addr i_saddr,
     const struct NyLPC_TEthAddr* i_srceth,
-    const struct NyLPC_TIPv4Addr i_daddr);
+    const struct NyLPC_TIPv4Addr* i_req_addr);
 
 
 typedef struct NyLPC_TcEthernetIIPayload NyLPC_TcEthernetIIPayload_t;
--- a/core/utils/NyLPC_cFormatWriter.c	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/utils/NyLPC_cFormatWriter.c	Fri Sep 13 06:38:16 2013 +0000
@@ -1,8 +1,8 @@
 #include "NyLPC_cFormatWriter.h"
 
 
-#define FTYPE_LENGTH 0x00000001
-#define FTYPE_NOTHING 0x00000000
+#define FTYPE_LENGTH 0x01
+#define FTYPE_NOTHING 0x00
 
 #define NUM_OF_WORK 16
 NyLPC_TBool NyLPC_cFormatWriter_print(NyLPC_cFormatWriter_printHandler i_handler,void* i_inst,const NyLPC_TChar* i_fmt,va_list args)
@@ -10,9 +10,9 @@
     const char* rp=i_fmt;
     const char* sp;
     char wk[NUM_OF_WORK];
-    NyLPC_TUInt32 ftype;
+    NyLPC_TUInt8 ftype;
     NyLPC_TUInt32 ut;
-    int ol=0;
+    NyLPC_TInt16 ol=0;
     while(*rp!='\0'){
         if(*rp=='%'){
             ftype=FTYPE_NOTHING;
@@ -132,3 +132,132 @@
     //どこかでエラーが起こってればFALSE返す。
     return i_handler(i_inst,wk,ol);
 }
+
+NyLPC_TInt16 NyLPC_cFormatWriter_length(const NyLPC_TChar* i_fmt,va_list args)
+{
+    const char* rp=i_fmt;
+    const char* sp;
+    char wk[NUM_OF_WORK];
+    NyLPC_TUInt32 ut;
+    NyLPC_TUInt8 ftype;
+    NyLPC_TInt16 len=0;
+    NyLPC_TInt16 ol=0;
+    while(*rp!='\0'){
+        if(*rp=='%'){
+            ftype=FTYPE_NOTHING;
+            rp++;
+        FMT_NEXT:
+            switch (*rp){
+            case '.':
+                //%.*(s)
+                if(*(rp+1)=='*'){
+                    //%.*
+                    ftype=FTYPE_LENGTH;
+                    rp+=2;
+                    goto FMT_NEXT;
+                }
+                //その他
+                wk[ol]=*rp;
+                ol++;
+                rp++;
+                break;
+            case 's':
+                switch(ftype){
+                case FTYPE_LENGTH:
+                    //%.*sの場合
+                    ut=va_arg(args,NyLPC_TUInt32);
+                    break;
+                default:
+                    ut=0x7FFFFFFF;
+                }
+                sp=va_arg(args,const char*);
+                while(*sp!=0 && ut>0){
+                    wk[ol]=*sp;
+                    ol++;
+                    sp++;
+                    //バッファフルなら書込み。
+                    if(ol>=NUM_OF_WORK){
+                        len+=NUM_OF_WORK;
+                        ol=0;
+                    }
+                    ut--;
+                }
+                rp++;
+                continue;
+            case 'c':
+                wk[ol]=(char)va_arg(args,int);
+                rp++;
+                ol++;
+                break;
+            case 'd':
+                //ワークを空にする。
+                if(ol>0){
+                    len+=ol;
+                    ol=0;
+                }
+                NyLPC_itoa((va_arg(args,int)),wk,10);
+                //強制コミット
+                len+=(NyLPC_TInt16)strlen(wk);
+                rp++;
+                continue;
+            case 'u':
+                //ワークを空にする。
+                if(ol>0){
+                    len+=ol;
+                }
+                ut=va_arg(args,NyLPC_TUInt32);
+                ol=15;
+                wk[ol--]='\0';
+                do{
+                    wk[ol--]='0'+(ut%10);
+                    ut/=10;
+                }while(ut>0);
+                len+=14-ol;
+                ol=0;
+                rp++;
+                continue;
+            case 'x':
+                //ワークを空にする。
+                if(ol>0){
+                    len+=ol;
+                    ol=0;
+                }
+                NyLPC_uitoa((va_arg(args,unsigned int)),wk,16);
+                //強制コミット
+                len+=(NyLPC_TInt16)strlen(wk);
+                rp++;
+                continue;
+//          case 'X':
+            case '%':
+                wk[ol]='%';
+                ol++;
+                rp++;
+                break;
+            case '\0':
+                //オワタ(ループ抜けるためにrpはそのまま。)
+                break;
+            default:
+                wk[ol]=*rp;
+                ol++;
+            }
+            //バッファフルなら書込み。
+            if(ol>=NUM_OF_WORK){
+                len+=NUM_OF_WORK;
+                ol=0;
+            }
+        }else if(*rp==0){
+            //オワタ
+            break;
+        }else{
+            wk[ol]=*rp;
+            ol++;
+            rp++;
+            if(ol>=NUM_OF_WORK){
+                len+=NUM_OF_WORK;
+                ol=0;
+            }
+        }
+    }
+    //どこかでエラーが起こってればFALSE返す。
+    return len+ol;
+}
--- a/core/utils/NyLPC_cFormatWriter.h	Sat Aug 10 02:52:22 2013 +0000
+++ b/core/utils/NyLPC_cFormatWriter.h	Fri Sep 13 06:38:16 2013 +0000
@@ -21,6 +21,11 @@
  */
 NyLPC_TBool NyLPC_cFormatWriter_print(NyLPC_cFormatWriter_printHandler i_handler,void* i_inst,const NyLPC_TChar* i_fmt,va_list args);
 
+/**
+ * 書式文字列を出力した時のバイト長さを求めます。
+ */
+NyLPC_TInt16 NyLPC_cFormatWriter_length(const NyLPC_TChar* i_fmt,va_list args);
+
 
 #ifdef __cplusplus
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/utils/sha1/sha1.c	Fri Sep 13 06:38:16 2013 +0000
@@ -0,0 +1,229 @@
+/*
+SHA-1 in C
+By Steve Reid <steve@edmweb.com>
+100% Public Domain
+
+Test Vectors (from FIPS PUB 180-1)
+"abc"
+  A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+A million repetitions of "a"
+  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+*/
+/**
+ * modified by nyatla
+ * Still public domain.
+ */
+
+/* #define LITTLE_ENDIAN * This should be #define'd if true. */
+/* #define SHA1HANDSOFF * Copies data before messing with it. */
+
+#include <stdio.h>
+#include <string.h>
+#include "sha1.h"
+#include "NyLPC_config.h"
+
+
+#   if UIP_BYTE_ORDER == NyLPC_ENDIAN_BIG
+#   else
+#	define LITTLE_ENDIAN 1
+#endif
+
+
+
+
+/*
+void SHA1Transform(unsigned long state[5], unsigned char buffer[64]);
+void SHA1Init(SHA1_CTX* context);
+void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len);
+void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
+*/
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/* blk0() and blk() perform the initial expand. */
+/* I got the idea of expanding during the round function from SSLeay */
+#ifdef LITTLE_ENDIAN
+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
+    |(rol(block->l[i],8)&0x00FF00FF))
+#else
+#define blk0(i) block->l[i]
+#endif
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+    ^block->l[(i+2)&15]^block->l[i&15],1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+#define SHA1HANDSOFF 1
+void SHA1Transform(unsigned long state[5],const unsigned char buffer[64])
+{
+unsigned long a, b, c, d, e;
+typedef union {
+    unsigned char c[64];
+    unsigned long l[16];
+} CHAR64LONG16;
+CHAR64LONG16* block;
+#ifdef SHA1HANDSOFF
+static unsigned char workspace[64];
+    block = (CHAR64LONG16*)workspace;
+    memcpy(block, buffer, 64);
+#else
+    block = (CHAR64LONG16*)buffer;
+#endif
+    /* Copy context->state[] to working vars */
+    a = state[0];
+    b = state[1];
+    c = state[2];
+    d = state[3];
+    e = state[4];
+    /* 4 rounds of 20 operations each. Loop unrolled. */
+    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+    R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+    R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+    R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+    R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+    R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+    R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+    R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+    R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+    R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+    R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+    R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+    R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+    R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+    /* Add the working vars back into context.state[] */
+    state[0] += a;
+    state[1] += b;
+    state[2] += c;
+    state[3] += d;
+    state[4] += e;
+    /* Wipe variables */
+    a = b = c = d = e = 0;
+}
+
+
+/* SHA1Init - Initialize new context */
+
+void SHA1Init(SHA1_CTX* context)
+{
+    /* SHA1 initialization constants */
+    context->state[0] = 0x67452301;
+    context->state[1] = 0xEFCDAB89;
+    context->state[2] = 0x98BADCFE;
+    context->state[3] = 0x10325476;
+    context->state[4] = 0xC3D2E1F0;
+    context->count[0] = context->count[1] = 0;
+}
+
+
+/* Run your data through this. */
+
+void SHA1Update(SHA1_CTX* context,const void* data, unsigned int len)
+{
+unsigned int i, j;
+
+    j = (context->count[0] >> 3) & 63;
+    if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
+    context->count[1] += (len >> 29);
+    if ((j + len) > 63) {
+        memcpy(&context->buffer[j], data, (i = 64-j));
+        SHA1Transform(context->state, context->buffer);
+        for ( ; i + 63 < len; i += 64) {
+            SHA1Transform(context->state, ((const unsigned char*)data)+i);
+        }
+        j = 0;
+    }
+    else i = 0;
+    memcpy(&context->buffer[j], ((const unsigned char*)data)+i, len - i);
+}
+
+
+/* Add padding and return the message digest. */
+
+void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
+{
+	unsigned long i, j;
+	unsigned char finalcount[8];
+
+    for (i = 0; i < 8; i++) {
+        finalcount[i] = (unsigned char)((context->count[((i >= 4) ? 0 : 1)]
+         >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
+    }
+    SHA1Update(context, (unsigned char *)"\200", 1);
+    while ((context->count[0] & 504) != 448) {
+        SHA1Update(context, (unsigned char *)"\0", 1);
+    }
+    SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */
+    for (i = 0; i < 20; i++) {
+        digest[i] = (unsigned char)
+         ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
+    }
+    /* Wipe variables */
+    i = j = 0;
+    memset(context->buffer, 0, 64);
+    memset(context->state, 0, 20);
+    memset(context->count, 0, 8);
+    memset(&finalcount, 0, 8);
+#ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite it's own static vars */
+    SHA1Transform(context->state, context->buffer);
+#endif
+}
+
+
+/*************************************************************/
+//#define TEST_SHA1
+#ifdef TEST_SHA1
+
+int main(int argc, char** argv)
+{
+int i, j;
+SHA1_CTX context;
+unsigned char digest[20], buffer[16384];
+FILE* file;
+
+    if (argc > 2) {
+        puts("Public domain SHA-1 implementation - by Steve Reid <steve@edmweb.com>");
+        puts("Produces the SHA-1 hash of a file, or stdin if no file is specified.");
+        exit(0);
+    }
+    if (argc < 2) {
+        file = stdin;
+    }
+    else {
+        if (!(file = fopen(argv[1], "rb"))) {
+            fputs("Unable to open file.", stderr);
+            exit(-1);
+        }
+    }
+    SHA1Init(&context);
+    while (!feof(file)) {  /* note: what if ferror(file) */
+        i = fread(buffer, 1, 16384, file);
+        SHA1Update(&context, buffer, i);
+    }
+    SHA1Final(digest, &context);
+    fclose(file);
+    for (i = 0; i < 5; i++) {
+        for (j = 0; j < 4; j++) {
+            printf("%02X", digest[i*4+j]);
+        }
+        putchar(' ');
+    }
+    putchar('\n');
+    exit(0);
+}
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/utils/sha1/sha1.h	Fri Sep 13 06:38:16 2013 +0000
@@ -0,0 +1,40 @@
+/* sha1.h */
+#include "NyLPC_stdlib.h"
+/* If OpenSSL is in use, then use that version of SHA-1 */
+#ifdef OPENSSL
+#include <t_sha.h>
+#define __SHA1_INCLUDE_
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifndef __SHA1_INCLUDE_
+
+#ifndef SHA1_SIGNATURE_SIZE
+#ifdef SHA_DIGESTSIZE
+#define SHA1_SIGNATURE_SIZE SHA_DIGESTSIZE
+#else
+#define SHA1_SIGNATURE_SIZE 20
+#endif
+#endif
+
+
+typedef struct {
+    NyLPC_TUInt32 state[5];
+    NyLPC_TUInt32 count[2];
+    unsigned char buffer[64];
+}SHA1_CTX;
+
+void SHA1Init(SHA1_CTX* context);
+void SHA1Update(SHA1_CTX* context,const void* data, unsigned int len);
+void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#define __SHA1_INCLUDE_
+#endif /* __SHA1_INCLUDE_ */
+