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

Fork of libMiMic by Ryo Iizuka

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_ */
+