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

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

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

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

構成

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

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

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

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

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

対応機種

  • mbed(mbed LPC1768)
  • LPCXpresso1769

プログラム

Import programMiMicRemoteMCU-for-Mbed

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

Import programMbedFileServer

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

サンプル

Import programMiMicSimpleHttpd

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

Import programUPnPBasicDevice

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

Import programWebSocketSample

MiMicSDK Websocket module sample program.

Import programHttpClientSamlpe

A http client sample program.

Import programTcpSocketClientSamlpe

MiMicSDK Tcp client socket sample program.

Import programUdpSocketSamlpe

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

チュートリアル

English

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

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

Structure

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

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

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

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

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

Supported target

  • mbed(mbed LPC1768)
  • LPCXpresso1769

Application

Import programMiMicRemoteMCU-for-Mbed

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

Import programMbedFileServer

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

Sample

Import programMiMicSimpleHttpd

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

Import programUPnPBasicDevice

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

Import programWebSocketSample

MiMicSDK Websocket module sample program.

Import programHttpClientSamlpe

A http client sample program.

Import programTcpSocketClientSamlpe

MiMicSDK Tcp client socket sample program.

Import programUdpSocketSamlpe

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

Tutorial

Files at this revision

API Documentation at this revision

Comitter:
nyatla
Date:
Wed Jun 19 09:33:01 2013 +0000
Parent:
36:f02596009a02
Child:
38:b0604fee76b0
Commit message:
update; MiMic Core r263; add mDNS service,DHCP client,APIPA client

Changed in this revision

core/NyLPC_cMiMicEnv.h Show annotated file Show diff for this revision Revisions of this file
core/driver/uip/EthDev_LPC17xx.c Show annotated file Show diff for this revision Revisions of this file
core/driver/uip/EtherDev_DP83848C.c Show annotated file Show diff for this revision Revisions of this file
core/driver/uip/EtherDev_LAN8720.c Show annotated file Show diff for this revision Revisions of this file
core/driver/uip/IEthernetDevice.h Show annotated file Show diff for this revision Revisions of this file
core/flash/NyLPC_cMiMicConfiglation.c Show annotated file Show diff for this revision Revisions of this file
core/flash/NyLPC_cMiMicConfiglation.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_cUrlEncode.c Show annotated file Show diff for this revision Revisions of this file
core/http/NyLPC_cUrlEncode.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_uipService.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/NyLPC_cNet.c Show annotated file Show diff for this revision Revisions of this file
core/net/NyLPC_cNet.h Show annotated file Show diff for this revision Revisions of this file
core/net/NyLPC_cNetConfig.c Show annotated file Show diff for this revision Revisions of this file
core/net/NyLPC_cNetConfig.h Show annotated file Show diff for this revision Revisions of this file
core/net/apipa/NyLPC_cApipa.c Show annotated file Show diff for this revision Revisions of this file
core/net/apipa/NyLPC_cApipa.h Show annotated file Show diff for this revision Revisions of this file
core/net/dhcp/NyLPC_cDhcpClient.c Show annotated file Show diff for this revision Revisions of this file
core/net/dhcp/NyLPC_cDhcpClient.h Show annotated file Show diff for this revision Revisions of this file
core/net/httpd/NyLPC_cHttpd.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_cHttpdThread.h Show annotated file Show diff for this revision Revisions of this file
core/net/httpd/mod/NyLPC_cMocMiMicSetting.c Show annotated file Show diff for this revision Revisions of this file
core/net/httpd/mod/NyLPC_cModMiMicSetting.h Show annotated file Show diff for this revision Revisions of this file
core/net/mdns/NyLPC_cMDnsServer.c Show annotated file Show diff for this revision Revisions of this file
core/net/mdns/NyLPC_cMDnsServer.h Show annotated file Show diff for this revision Revisions of this file
core/os/NyLPC_cMutex.h 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_cIPv4Arp.c Show annotated file Show diff for this revision Revisions of this file
core/uip/NyLPC_cIPv4Config.c 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_cIPv4Payload.c Show annotated file Show diff for this revision Revisions of this file
core/uip/NyLPC_cIPv4Payload.h Show annotated file Show diff for this revision Revisions of this file
core/uip/NyLPC_cIPv4Payload_protected.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_cTcpListener_protected.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_cTcpSocket_protected.h Show annotated file Show diff for this revision Revisions of this file
core/uip/NyLPC_cUdpSocket.c Show annotated file Show diff for this revision Revisions of this file
core/uip/NyLPC_cUdpSocket.h Show annotated file Show diff for this revision Revisions of this file
core/uip/NyLPC_cUdpSocket_protected.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_cUipService.h Show annotated file Show diff for this revision Revisions of this file
core/uip/NyLPC_cUipService_protected.h 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_cFormatTextReader.c Show annotated file Show diff for this revision Revisions of this file
core/utils/NyLPC_cFormatTextReader.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
mbed/Net.cpp Show annotated file Show diff for this revision Revisions of this file
mbed/Net.h Show annotated file Show diff for this revision Revisions of this file
mbed/NetConfig.cpp Show annotated file Show diff for this revision Revisions of this file
mbed/NetConfig.h Show annotated file Show diff for this revision Revisions of this file
--- a/core/NyLPC_cMiMicEnv.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/NyLPC_cMiMicEnv.h	Wed Jun 19 09:33:01 2013 +0000
@@ -13,7 +13,7 @@
 #endif /* __cplusplus */
 
 
-#define NyLPC_cMiMicEnv_VERSION "MiMic/1.4.5"
+#define NyLPC_cMiMicEnv_VERSION "MiMic/1.4.8"
 
 
 #ifdef __cplusplus
--- a/core/driver/uip/EthDev_LPC17xx.c	Thu May 16 16:06:46 2013 +0000
+++ b/core/driver/uip/EthDev_LPC17xx.c	Wed Jun 19 09:33:01 2013 +0000
@@ -123,8 +123,6 @@
     LPC_EMAC->TxStatus = TX_STAT_BASE;
     LPC_EMAC->TxDescriptorNumber = NUM_TX_FRAG - 1;
 
-    /* Tx Descriptors Point to 0 */
-    LPC_EMAC->TxProduceIndex = 0;
 
 }
 
@@ -308,8 +306,6 @@
     LPC_EMAC->RxStatus = RX_STAT_BASE;
     LPC_EMAC->RxDescriptorNumber = NUM_RX_FRAG - 1;
 
-    /* Rx Descriptors Point to 0 */
-    LPC_EMAC->RxConsumeIndex = 0;
 }
 
 
--- a/core/driver/uip/EtherDev_DP83848C.c	Thu May 16 16:06:46 2013 +0000
+++ b/core/driver/uip/EtherDev_DP83848C.c	Wed Jun 19 09:33:01 2013 +0000
@@ -1,6 +1,6 @@
 /*
     FreeRTOS V7.0.0 - Copyright (C) 2011 Real Time Engineers Ltd.
-    
+
 
     ***************************************************************************
      *                                                                       *
@@ -183,6 +183,8 @@
         return NyLPC_TBool_FALSE;
     }
     *o_dev=&_interface;
+    LPC_EMAC->TxProduceIndex = 0;
+    LPC_EMAC->RxConsumeIndex = 0;
     return NyLPC_TBool_TRUE;
 }
 
@@ -244,6 +246,8 @@
         NVIC_DisableIRQ( ENET_IRQn );
     }
     NyLPC_cIsr_exitCritical();
+    LPC_EMAC->Command &= ~( CR_RX_EN | CR_TX_EN );
+    LPC_EMAC->MAC1 &= ~MAC1_REC_EN;
     return;
 }
 
--- a/core/driver/uip/EtherDev_LAN8720.c	Thu May 16 16:06:46 2013 +0000
+++ b/core/driver/uip/EtherDev_LAN8720.c	Wed Jun 19 09:33:01 2013 +0000
@@ -172,6 +172,8 @@
         return NyLPC_TBool_FALSE;
     }
     *o_dev=&_interface;
+    LPC_EMAC->TxProduceIndex = 0;
+    LPC_EMAC->RxConsumeIndex = 0;
     return NyLPC_TBool_TRUE;
 }
 
@@ -237,6 +239,9 @@
         NVIC_DisableIRQ( ENET_IRQn );
     }
     NyLPC_cIsr_exitCritical();
+    LPC_EMAC->Command &= ~( CR_RX_EN | CR_TX_EN );
+    LPC_EMAC->MAC1 &= ~MAC1_REC_EN;
+
 }
 
 
--- a/core/driver/uip/IEthernetDevice.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/driver/uip/IEthernetDevice.h	Wed Jun 19 09:33:01 2013 +0000
@@ -8,6 +8,7 @@
 #define IEthernetDevice_h
 #include "../../uip/NyLPC_uip.h"
 #include "NyLPC_stdlib.h"
+//#include "../../uip/NyLPC_uip_ethernet.h"
 
 
 #ifdef __cplusplus
@@ -74,6 +75,8 @@
  * allocTxBufで得たメモリか、初期化したNyLPC_TTxBufferHeaderメモリブロックを指定する。
  * 送信が終わるまでの間、メモリを開放してはならない。
  * #外部で確保したメモリについては、利用不能なケースがあるかもしれない。現在のMiMicでは、使用できることを前提としている。
+ * @oaram i_size
+ * i_bufの後ろに連結されているデータメモリの長さ
  */
 typedef void (*NyLPC_TiEthernetDevice_sendTxEthFrame)(struct NyLPC_TTxBufferHeader* i_buf,unsigned short i_size);
 /**
--- a/core/flash/NyLPC_cMiMicConfiglation.c	Thu May 16 16:06:46 2013 +0000
+++ b/core/flash/NyLPC_cMiMicConfiglation.c	Wed Jun 19 09:33:01 2013 +0000
@@ -1,7 +1,7 @@
 #include "NyLPC_flash.h"
 #include "NyLPC_http.h"
 #include "NyLPC_cMiMicConfiglation.h"
-
+#include "NyLPC_net.h"
 /**
  * Onchip flashを使ったコンフィギュレーション保存システムです。
  */
@@ -19,15 +19,21 @@
 /**
  * コンフィギュレーション値はホストオーダーで保存する。
  */
-const struct NyLPC_TMimicConfigulation factory_default=
+const struct NyLPC_TMiMicConfigulation factory_default=
 {
-    0xffffffff,
-    0x02010203,0x0405ffff,
+    0xffffffff,             //fastboot
+    "MiMic020102030405",
+    0x02010203,0x0405ffff,  //Mac addr
+    //IPv4
+    NyLPC_TcNetConfig_IPV4_FLAG_MODE_MANUAL,    //flags
     IP2Int(192,168,0,39),
     IP2Int(255,255,255,0),
     IP2Int(192,168,0,254),
-    80,
-    0x0000FFFF
+    //ServerFlags
+    NyLPC_TcNetConfig_SERVICE_FLAG_MDNS,
+    //HTTP
+    80, //HTTP-Port
+    0   //padding
 };
 
 
@@ -37,7 +43,7 @@
  * ユーザコンフィギュレーションを更新する。
  * この関数をコールするときは、割込/FreeRTOSを一時停止すること。
  */
-NyLPC_TBool NyLPC_cMiMicConfiglation_updateConfigulation(const struct NyLPC_TMimicConfigulation* i_congfiglation)
+NyLPC_TBool NyLPC_cMiMicConfiglation_updateConfigulation(const struct NyLPC_TMiMicConfigulation* i_congfiglation)
 {
     const NyLPC_TUInt32* volatile fast_boot=&(factory_default.fast_boot);
     //イレース
@@ -45,7 +51,7 @@
         NyLPC_OnErrorGoto(Error);
     }
     //コンフィギュレーションを書き込む。
-    if(!NyLPC_cOnchipFlashWriter_writeSector(MIMIC_CONFIGLATION_FLASH_SECTOR,0x00000000,i_congfiglation,sizeof(struct NyLPC_TMimicConfigulation))){
+    if(!NyLPC_cOnchipFlashWriter_writeSector(MIMIC_CONFIGLATION_FLASH_SECTOR,0x00000000,i_congfiglation,sizeof(struct NyLPC_TMiMicConfigulation))){
         NyLPC_OnErrorGoto(Error);
     }
     //プログラム済フラッシュの一部を書き換えてユーザコンフィギュレーションをONにする。
@@ -65,17 +71,17 @@
 /**
  * コンフィギュレーション値を返す。
  */
-const struct NyLPC_TMimicConfigulation* NyLPC_cMiMicConfiglation_loadFromFlash(void)
+const struct NyLPC_TMiMicConfigulation* NyLPC_cMiMicConfiglation_loadFromFlash(void)
 {
     if(NyLPC_cMiMicConfiglation_hasUserConfigulation()){
         //userコンフィギュレーション読むよ
-        return (const struct NyLPC_TMimicConfigulation*)(MIMIC_CONFIGLATION_FLASH_SECTOR_ADDR);
+        return (const struct NyLPC_TMiMicConfigulation*)(MIMIC_CONFIGLATION_FLASH_SECTOR_ADDR);
     }else{
         //Userコンフィギュレーションない
         return &factory_default;
     }
 }
-const struct NyLPC_TMimicConfigulation* NyLPC_cMiMicConfiglation_loadFactoryDefault(void)
+const struct NyLPC_TMiMicConfigulation* NyLPC_cMiMicConfiglation_loadFactoryDefault(void)
 {
     return &factory_default;
 }
--- a/core/flash/NyLPC_cMiMicConfiglation.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/flash/NyLPC_cMiMicConfiglation.h	Wed Jun 19 09:33:01 2013 +0000
@@ -6,6 +6,7 @@
  */
 
 #include "NyLPC_stdlib.h"
+#include "NyLPC_net.h"
 #ifndef NYLPC_CCONFIGLATIONSTORAGE_H_
 #define NYLPC_CCONFIGLATIONSTORAGE_H_
 
@@ -13,22 +14,47 @@
 extern "C" {
 #endif /* __cplusplus */
 
+
 /**
  * IPアドレスはネットワークオーダーで格納する。
  * 構造体は4バイトアライメントであること。
  */
-struct NyLPC_TMimicConfigulation{
-    /**
-     * ROM焼検出用。0xFFFFFFFFを書く
+struct NyLPC_TMiMicConfigulation{
+    /** ROM焼検出用。0xFFFFFFFFを書く */
+    NyLPC_TUInt32   fast_boot;
+    /** ホスト名*/
+    NyLPC_TChar     hostname[NyLPC_TcNetConfig_HOSTNAME_LEN];
+    /** MACアドレスの下位4bit*/
+    NyLPC_TUInt32   mac_00_01_02_03;
+    /** MACアドレスの上位2bit*/
+    NyLPC_TUInt32   mac_04_05_xx_xx;
+    /*
+     * IPv4設定
      */
-    NyLPC_TUInt32   fast_boot;
-    NyLPC_TUInt32   mac_00_01_02_03;
-    NyLPC_TUInt32   mac_04_05_xx_xx;
+
+    /**
+     * 0-1bit 起動モード
+     *  0:default,1:DHCP,2:AUTOIP,3:APIPA
+     */
+    NyLPC_TUInt32   ipv4_flags;
+    /** IPV4アドレス*/
     NyLPC_TUInt32   ipv4_addr_net;
     NyLPC_TUInt32   ipv4_mask_net;
     NyLPC_TUInt32   ipv4_drut_net;
-    NyLPC_TUInt32   ipv4_port;
-    NyLPC_TUInt32   accessmode;
+
+    /*
+     * Service setting
+     */
+
+    /**
+     * Service flags
+     * 0:mdns ON/OFF
+     */
+    NyLPC_TUInt32   srv_flags;
+    /** HTTPポート番号*/
+    NyLPC_TUInt16   http_port;
+    NyLPC_TUInt16   padding;
+
 };
 
 /**
@@ -42,13 +68,13 @@
  * この関数は、RTOSが停止中に実行すること。
  * この関数は384バイト程度のスタックが必要です。
  */
-NyLPC_TBool NyLPC_cMiMicConfiglation_updateConfigulation(const struct NyLPC_TMimicConfigulation* i_congfiglation);
+NyLPC_TBool NyLPC_cMiMicConfiglation_updateConfigulation(const struct NyLPC_TMiMicConfigulation* i_congfiglation);
 /**
  * コンフィギュレーション値を返す。
  * この関数は、RTOSが停止中に実行すること。
  */
-const struct NyLPC_TMimicConfigulation* NyLPC_cMiMicConfiglation_loadFromFlash(void);
-const struct NyLPC_TMimicConfigulation* NyLPC_cMiMicConfiglation_loadFactoryDefault(void);
+const struct NyLPC_TMiMicConfigulation* NyLPC_cMiMicConfiglation_loadFromFlash(void);
+const struct NyLPC_TMiMicConfigulation* NyLPC_cMiMicConfiglation_loadFactoryDefault(void);
 
 #ifdef __cplusplus
 }
--- a/core/http/NyLPC_cHttpBodyWriter.c	Thu May 16 16:06:46 2013 +0000
+++ b/core/http/NyLPC_cHttpBodyWriter.c	Wed Jun 19 09:33:01 2013 +0000
@@ -26,6 +26,7 @@
 
 
 #include <stdlib.h>
+#include "NyLPC_utils.h"
 #include "NyLPC_cHttpBodyWriter.h"
 
 
@@ -33,7 +34,23 @@
 
 
 
-static NyLPC_TBool print(void* i_inst,const char* i_fmt,va_list args);
+/**
+ * PrintHandler
+ */
+static NyLPC_TBool printHandler(void* i_inst,const void* i_buf,NyLPC_TUInt32 i_len)
+{
+    //エラー状態ならFALSE
+    if(((NyLPC_TcHttpBodyWriter_t*)i_inst)->_is_error){
+        return NyLPC_TBool_FALSE;
+    }
+    ((NyLPC_TcHttpBodyWriter_t*)i_inst)->_size_of_sent+=i_len;
+    if(!NyLPC_iHttpPtrStream_write(((NyLPC_TcHttpBodyWriter_t*)i_inst)->_ref_stream,i_buf,i_len)){
+        ((NyLPC_TcHttpBodyWriter_t*)i_inst)->_is_error=NyLPC_TUInt8_TRUE;
+        return NyLPC_TBool_FALSE;
+    }
+    return NyLPC_TBool_TRUE;
+}
+
 
 
 void NyLPC_cHttpBodyWriter_initialize(NyLPC_TcHttpBodyWriter_t* i_inst,NyLPC_TcHttpStream_t* i_stream)
@@ -66,17 +83,9 @@
  */
 NyLPC_TBool NyLPC_cHttpBodyWriter_write(NyLPC_TcHttpBodyWriter_t* i_inst,const void* i_buf,NyLPC_TUInt32 i_len)
 {
-    //エラー状態ならFALSE
-    if(i_inst->_is_error){
-        return NyLPC_TBool_FALSE;
-    }
-    i_inst->_size_of_sent+=i_len;
-    if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,i_buf,i_len)){
-        i_inst->_is_error=NyLPC_TUInt8_TRUE;
-        return NyLPC_TBool_FALSE;
-    }
-    return NyLPC_TBool_TRUE;
+    return printHandler(i_inst,i_buf,i_len);
 }
+
 /**
  * HttpBodyの書き込みを完了します。
  * @return
@@ -117,7 +126,7 @@
         return NyLPC_TBool_FALSE;
     }
     va_start(a,i_fmt);
-    ret=print(i_inst,i_fmt,a);
+    ret=   NyLPC_cFormatWriter_print(printHandler,i_inst,i_fmt,a);
     va_end(a);
     return ret;
 }
@@ -129,117 +138,10 @@
     if(i_inst->_is_error){
         return NyLPC_TBool_FALSE;
     }
-    ret=print(i_inst,i_fmt,i_args);
+    ret=NyLPC_cFormatWriter_print(printHandler,i_inst,i_fmt,i_args);
     return ret;
 }
 
-#define NUM_OF_WORK 16
-
-static NyLPC_TBool print(void* i_inst,const char* i_fmt,va_list args)
-{
-    const char* rp=i_fmt;
-    const char* sp;
-    char wk[NUM_OF_WORK];
-    NyLPC_TUInt32 ut;
-    int ol=0;
-    while(*rp!='\0'){
-        if(*rp=='%'){
-            rp++;
-            switch (*rp){
-            case 's':
-                sp=va_arg(args,const char*);
-                while(*sp!=0){
-                    wk[ol]=*sp;
-                    ol++;
-                    sp++;
-                    //バッファフルなら書込み。
-                    if(ol>=NUM_OF_WORK){
-                        NyLPC_cHttpBodyWriter_write((NyLPC_TcHttpBodyWriter_t*)i_inst,wk,NUM_OF_WORK);
-                        ol=0;
-                    }
-                }
-                rp++;
-                continue;
-            case 'c':
-                wk[ol]=(char)va_arg(args,int);
-                rp++;
-                ol++;
-                break;
-            case 'd':
-                //ワークを空にする。
-                if(ol>0){
-                    NyLPC_cHttpBodyWriter_write((NyLPC_TcHttpBodyWriter_t*)i_inst,wk,ol);
-                    ol=0;
-                }
-                NyLPC_itoa((va_arg(args,int)),wk,10);
-                //強制コミット
-                NyLPC_cHttpBodyWriter_write((NyLPC_TcHttpBodyWriter_t*)i_inst,wk,strlen(wk));
-                rp++;
-                continue;
-            case 'u':
-                //ワークを空にする。
-                if(ol>0){
-                    NyLPC_cHttpBodyWriter_write((NyLPC_TcHttpBodyWriter_t*)i_inst,wk,ol);
-                }
-                ut=va_arg(args,NyLPC_TUInt32);
-                ol=15;
-                wk[ol--]='\0';
-                do{
-                    wk[ol--]='0'+(ut%10);
-                    ut/=10;
-                }while(ut>0);
-                NyLPC_cHttpBodyWriter_write((NyLPC_TcHttpBodyWriter_t*)i_inst,(wk+ol+1),14-ol);
-                ol=0;
-                rp++;
-                continue;
-            case 'x':
-                //ワークを空にする。
-                if(ol>0){
-                    NyLPC_cHttpBodyWriter_write((NyLPC_TcHttpBodyWriter_t*)i_inst,wk,ol);
-                    ol=0;
-                }
-                NyLPC_uitoa((va_arg(args,int)),wk,16);
-                //強制コミット
-                NyLPC_cHttpBodyWriter_write((NyLPC_TcHttpBodyWriter_t*)i_inst,wk,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){
-                NyLPC_cHttpBodyWriter_write((NyLPC_TcHttpBodyWriter_t*)i_inst,wk,NUM_OF_WORK);
-                ol=0;
-            }
-        }else if(*rp==0){
-            //オワタ
-            break;
-        }else{
-            wk[ol]=*rp;
-            ol++;
-            rp++;
-            if(ol>=NUM_OF_WORK){
-                NyLPC_cHttpBodyWriter_write((NyLPC_TcHttpBodyWriter_t*)i_inst,wk,NUM_OF_WORK);
-                ol=0;
-            }
-        }
-    }
-    //どこかでエラーが起こってればFALSE返す。
-    return NyLPC_cHttpBodyWriter_write((NyLPC_TcHttpBodyWriter_t*)i_inst,wk,ol);
-}
-
-
-
 /**
  * テスト用のコード。
  */
@@ -323,4 +225,4 @@
     //TCPのクローズ
     return;
 }
-#endif
\ No newline at end of file
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/http/NyLPC_cUrlEncode.c	Wed Jun 19 09:33:01 2013 +0000
@@ -0,0 +1,51 @@
+#include "NyLPC_cUrlEncode.h"
+#include <stdarg.h>
+#include <ctype.h>
+
+
+NyLPC_TBool NyLPC_cUrlEncode_initialize(NyLPC_TcUrlEncode_t* i_inst)
+{
+    i_inst->_len=0;
+    return NyLPC_TBool_TRUE;
+}
+
+NyLPC_TcUrlEncode_ST NyLPC_cUrlEncode_decode(NyLPC_TcUrlEncode_t* i_inst,NyLPC_TChar c,NyLPC_TChar* out)
+{
+    int t;
+    if(c=='%'){
+        if(i_inst->_len!=0){
+            NyLPC_OnErrorGoto(Error);
+        }
+        i_inst->_len=1;
+        return NyLPC_TcUrlEncode_ST_NEXT;
+    }else{
+        switch(i_inst->_len){
+        case 0:
+            *out=c;
+            return NyLPC_TcUrlEncode_ST_DONE;
+        case 1:
+            if(!isxdigit(c)){
+                NyLPC_OnErrorGoto(Error);
+            }
+            t=NyLPC_ctox(c);
+            i_inst->v=(NyLPC_TChar)t;//16進文字→HEX
+            i_inst->_len++;
+            return NyLPC_TcUrlEncode_ST_NEXT;
+        case 2:
+            if(!isxdigit(c)){
+                NyLPC_OnErrorGoto(Error);
+            }
+            t=NyLPC_ctox(c);
+            *out=(NyLPC_TChar)((i_inst->v<<4) | t);
+            i_inst->v=0;
+            i_inst->_len=0;
+            return NyLPC_TcUrlEncode_ST_DONE;
+        default:
+            NyLPC_OnErrorGoto(Error);
+        }
+    }
+Error:
+    i_inst->v=0;
+    i_inst->_len=0;
+    return NyLPC_TcUrlEncode_ST_ERROR;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/http/NyLPC_cUrlEncode.h	Wed Jun 19 09:33:01 2013 +0000
@@ -0,0 +1,39 @@
+/*
+ * NyLPC_cUrlEncode.h
+ *
+ *  Created on: 2013/06/11
+ *      Author: nyatla
+ */
+
+#ifndef NYLPC_CURLENCODE_H_
+#define NYLPC_CURLENCODE_H_
+
+#include "NyLPC_stdlib.h"
+#include <stdarg.h>
+#include <ctype.h>
+
+typedef struct NyLPC_TcUrlEncode NyLPC_TcUrlEncode_t;
+
+typedef NyLPC_TUInt32 NyLPC_TcUrlEncode_ST;
+#define NyLPC_TcUrlEncode_ST_NEXT   2
+#define NyLPC_TcUrlEncode_ST_DONE   1
+#define NyLPC_TcUrlEncode_ST_ERROR  0
+
+struct NyLPC_TcUrlEncode
+{
+    /**一時バッファ */
+    NyLPC_TChar v;
+    /** バッファに蓄積してる長さ*/
+    NyLPC_TInt8 _len;
+};
+
+NyLPC_TBool NyLPC_cUrlEncode_initialize(NyLPC_TcUrlEncode_t* i_inst);
+
+#define NyLPC_cUrlEncode_finalize(i_inst)
+
+
+
+NyLPC_TcUrlEncode_ST NyLPC_cUrlEncode_decode(NyLPC_TcUrlEncode_t* i_inst,NyLPC_TChar c,NyLPC_TChar* out);
+
+
+#endif /* NYLPC_CURLENCODE_H_ */
--- a/core/include/NyLPC_net.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/include/NyLPC_net.h	Wed Jun 19 09:33:01 2013 +0000
@@ -31,6 +31,9 @@
 #define NYLPC_NET_H_
 #include "../net/NyLPC_cNet.h"
 
+#include "../net/mdns/NyLPC_cMDnsServer.h"
+#include "../net/apipa/NyLPC_cApipa.h"
+
 #include "../net/httpd/NyLPC_cHttpdConnection.h"
 #include "../net/httpd/NyLPC_cHttpd.h"
 #include "../net/httpd/NyLPC_cHttpdUtils.h"
--- a/core/include/NyLPC_stdlib.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/include/NyLPC_stdlib.h	Wed Jun 19 09:33:01 2013 +0000
@@ -217,7 +217,7 @@
  * @bf
  * 操作対象の変数です。
  * @b
- * 操作するビット番号です。
+ * 操作するビットパターンです。
  */
 #define NyLPC_TUInt8_setBit(bf,b) NyLPC_TUInt32_setBit(bf,b)
 /**
@@ -225,7 +225,7 @@
  * @bf
  * 操作対象の変数です。
  * @b
- * 操作するビット番号です。
+ * 操作するビットパターンです。
  */
 #define NyLPC_TUInt8_unsetBit(bf,b) NyLPC_TUInt32_unsetBit(bf,b)
 /**
@@ -233,9 +233,9 @@
  * @bf
  * 判定する変数です。
  * @b
- * 判定するビット番号です。
+ * 判定するビットパターンです。
  * @return
- * ビットが1なら真を返します。
+ * ビットが一致するなら真を返します。
  */
 #define NyLPC_TUInt8_isBitOn(bf,b) NyLPC_TUInt32_isBitOn(bf,b)
 
@@ -283,7 +283,7 @@
  * @bf
  * 操作対象の変数です。
  * @b
- * 操作するビット番号です。
+ * 操作するビットパターンです。
  */
 #define NyLPC_TUInt16_unsetBit(bf,b) NyLPC_TUInt32_unsetBit(bf,b)
 /**
@@ -291,9 +291,9 @@
  * @bf
  * 判定する変数です。
  * @b
- * 判定するビット番号です。
+ * 判定するビットパターンです。
  * @return
- * ビットが1なら真を返します。
+ * ビットが一致するなら真を返します。
  */
 #define NyLPC_TUInt16_isBitOn(bf,b) NyLPC_TUInt32_isBitOn(bf,b)
 
@@ -364,7 +364,7 @@
  * @b
  * 判定するビットパターンです。
  * @return
- * ビットが1なら真を返します。
+ * ビットが一致するなら真を返します。
  */
 #define NyLPC_TUInt32_isBitOn(bf,b) ((bf&b)==(b))
 
--- a/core/include/NyLPC_uipService.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/include/NyLPC_uipService.h	Wed Jun 19 09:33:01 2013 +0000
@@ -33,6 +33,7 @@
 #include "NyLPC_stdlib.h"
 #include "../uip/NyLPC_cTcpListener.h"
 #include "../uip/NyLPC_cTcpSocket.h"
+#include "../uip/NyLPC_cUdpSocket.h"
 #include "../uip/NyLPC_cUipService.h"
 
 #ifdef __cplusplus
--- a/core/include/NyLPC_utils.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/include/NyLPC_utils.h	Wed Jun 19 09:33:01 2013 +0000
@@ -32,7 +32,7 @@
 
 #include "../utils/NyLPC_cRomFileSet.h"
 #include "../utils/NyLPC_cFormatTextReader.h"
-
+#include "../utils/NyLPC_cFormatWriter.h"
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
--- a/core/net/NyLPC_cNet.c	Thu May 16 16:06:46 2013 +0000
+++ b/core/net/NyLPC_cNet.c	Wed Jun 19 09:33:01 2013 +0000
@@ -1,4 +1,31 @@
+/*********************************************************************************
+ * 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_cNet.h"
+#include "dhcp/NyLPC_cDhcpClient.h"
+
 
 const char* NyLPC_cNet_PlatformName;
 
@@ -13,7 +40,7 @@
 
 void NyLPC_cNet_start(NyLPC_TcNet_t* i_inst,const NyLPC_TcNetConfig_t* i_ref_config)
 {
-    NyLPC_cUipService_start(&(i_ref_config->interface_setting.ethernet));
+    NyLPC_cUipService_start(&(i_ref_config->super));
     //プラットフォーム名を推測(デバイス名の初めの1文字だけ見る。)
     switch(*(NyLPC_cUipService_refDeviceName())){
     case 'L':
@@ -26,4 +53,50 @@
         break;
     }
     return;
-}
\ No newline at end of file
+}
+
+void NyLPC_cNet_stop(NyLPC_TcNet_t* i_inst)
+{
+    NyLPC_cUipService_stop();
+}
+
+/**
+ * NyLPC_TcIPv4Config_tをDHCPで更新します。
+ * この関数をコールする時は、サービスは停止中でなければなりません。
+ * @param i_cfg
+ * 更新するi_cfg構造体。
+ * emac,default_mssは設定済である必要があります。他のフィールド値は不定で構いません。
+ * 更新されるフィールドは、ip,netmast,default_rootの3つです。
+ * @return
+ * 更新に成功した場合TRUE
+ */
+NyLPC_TBool NyLPC_cNet_requestAddrDhcp(NyLPC_TcNet_t* i_net,NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat)
+{
+    NyLPC_TBool ret;
+    NyLPC_TcDhcpClient_t sock;
+    //netを開始
+    NyLPC_cDhcpClient_initialize(&sock);
+    ret=NyLPC_cDhcpClient_requestAddr(&sock,i_cfg,i_repeat);
+    NyLPC_cDhcpClient_finalize(&sock);
+    return ret;
+}
+/**
+ * NyLPC_TcIPv4Config_tをAPIPAで更新します。
+ * この関数をコールする時は、サービスは停止中でなければなりません。
+ * @param i_cfg
+ * 更新するi_cfg構造体。
+ * emac,default_mssは設定済である必要があります。他のフィールド値は不定で構いません。
+ * 更新されるフィールドは、ip,netmast,default_rootの3つです。
+ * @return
+ * 更新に成功した場合TRUE
+ */
+NyLPC_TBool NyLPC_cNet_requestAddrApipa(NyLPC_TcNet_t* i_net,NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat)
+{
+    NyLPC_TBool ret;
+    NyLPC_TcApipa_t sock;
+    //netを開始
+    NyLPC_cApipa_initialize(&sock);
+    ret=NyLPC_cApipa_requestAddr(&sock,i_cfg,i_repeat);
+    NyLPC_cApipa_finalize(&sock);
+    return ret;
+}
--- a/core/net/NyLPC_cNet.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/net/NyLPC_cNet.h	Wed Jun 19 09:33:01 2013 +0000
@@ -1,3 +1,28 @@
+/*********************************************************************************
+ * PROJECT: MiMic
+ * --------------------------------------------------------------------------------
+ *
+ * This file is part of MiMic
+ * Copyright (C)2011 Ryo Iizuka
+ *
+ * MiMic is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * For further information please contact.
+ *  http://nyatla.jp/
+ *  <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
+ *
+ *********************************************************************************/
 #ifndef NYLPC_CNET_H_
 #define NYLPC_CNET_H_
 
@@ -30,11 +55,32 @@
 
 #define NyLPC_cNet_finalize(inst)
 /**
+ * ネットワークサービスを開始します。
+ * サービスは停止中でなければなりません。
  * 関数は、ネットワークアダプタの値を元にNyLPC_cMiMicEnv_PlatformName変数の値を更新します。
  * @param i_ref_config
  * Networkコンフィギュレーション変数。このオブジェクトはcNetをstopするまで維持すること。
  */
 void NyLPC_cNet_start(NyLPC_TcNet_t* i_inst,const NyLPC_TcNetConfig_t* i_ref_config);
+/**
+ * ネットワークスタックを停止します。
+ * サービスは開始中でなければなりません。
+ * start関数で開始済である必要があります。
+ * この関数をコールする前に、全てのTCPソケットを閉じ、非同期なソケット操作を停止してください。
+ */
+void NyLPC_cNet_stop(NyLPC_TcNet_t* i_inst);
+
+/**
+ * NyLPC_TcIPv4Config_tをDHCPで更新します。
+ * この関数をコールする時は、サービスは停止中でなければなりません。
+ * @param i_cfg
+ * 更新するi_cfg構造体。
+ * emac,default_mssは設定済である必要があります。他のフィールド値は不定で構いません。
+ * 更新されるフィールドは、ip,netmast,default_rootの3つです。
+ * @return
+ * 更新に成功した場合TRUE
+ */
+NyLPC_TBool NyLPC_cNet_requestAddrDhcp(NyLPC_TcNet_t* i_net,NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat);
 
 #ifdef __cplusplus
 }
--- a/core/net/NyLPC_cNetConfig.c	Thu May 16 16:06:46 2013 +0000
+++ b/core/net/NyLPC_cNetConfig.c	Wed Jun 19 09:33:01 2013 +0000
@@ -1,30 +1,33 @@
+/*********************************************************************************
+ * 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_cNetConfig.h"
 #include "../flash/NyLPC_cMiMicConfiglation.h"
-/**
- * IPアドレスはネットワークオーダーで格納する。
- * 構造体は4バイトアライメントであること。
- */
-struct TNetConfigMemMap
-{
-    /**
-     * ROM焼検出用。0xFFFFFFFFを書く
-     */
-    NyLPC_TUInt32   fast_boot;
-    NyLPC_TUInt16   version;
-    NyLPC_TUInt16   interface_type;
-    NyLPC_TUInt32   mac_00_01_02_03;
-    NyLPC_TUInt32   mac_04_05_xx_xx;
-    /** network order ip address*/
-    NyLPC_TUInt32   ipv4_addr_net;
-    /** network order mask value*/
-    NyLPC_TUInt32   ipv4_mask_net;
-    /** network order route*/
-    NyLPC_TUInt32   ipv4_drut_net;
-//  NyLPC_TUInt32   ipv4_port;
-//  NyLPC_TUInt32   accessmode;
-};
+
 
-static void update(NyLPC_TcNetConfig_t* i_inst,const struct NyLPC_TMimicConfigulation* pdata);
+static void update(NyLPC_TcNetConfig_t* i_inst,const struct NyLPC_TMiMicConfigulation* pdata);
 
 
 void NyLPC_cNetConfig_initialize(NyLPC_TcNetConfig_t* i_inst,NyLPC_TBool i_is_factory_default)
@@ -87,7 +90,7 @@
  */
 //#define ETHERNET_FRAME_LEN 1480
 #define ETHERNET_FRAME_LEN 1400
-static void update(NyLPC_TcNetConfig_t* i_inst,const struct NyLPC_TMimicConfigulation* pdata)
+static void update(NyLPC_TcNetConfig_t* i_inst,const struct NyLPC_TMiMicConfigulation* pdata)
 {
     struct NyLPC_TEthAddr ea;
     struct NyLPC_TIPv4Addr ip,mask,drt;
@@ -101,11 +104,13 @@
     ip.v=NyLPC_htonl(pdata->ipv4_addr_net);
     mask.v=NyLPC_htonl(pdata->ipv4_mask_net);
     drt.v=NyLPC_htonl(pdata->ipv4_drut_net);
-    i_inst->version=1;
-    i_inst->interface_type=NyLPC_cNetConfig_INTERFACE_TYPE_ETHERNET;
-    NyLPC_cIPv4Config_initialzeForEthernet(&i_inst->interface_setting.ethernet,&ea,ETHERNET_FRAME_LEN);
-    NyLPC_cIPv4Config_setDefaultRoute(&i_inst->interface_setting.ethernet,&drt);
-    NyLPC_cIPv4Config_setIp(&i_inst->interface_setting.ethernet,&ip,&mask);
+    strcpy(i_inst->hostname,pdata->hostname);
+    NyLPC_cIPv4Config_initialzeForEthernet(&i_inst->super,&ea,ETHERNET_FRAME_LEN);
+    NyLPC_cIPv4Config_setDefaultRoute(&i_inst->super,&drt);
+    NyLPC_cIPv4Config_setIp(&i_inst->super,&ip,&mask);
+    i_inst->services.flags=pdata->srv_flags;
+    i_inst->services.http_port=pdata->http_port;
+    i_inst->tcp_mode=pdata->ipv4_flags;
     return;
 }
 
--- a/core/net/NyLPC_cNetConfig.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/net/NyLPC_cNetConfig.h	Wed Jun 19 09:33:01 2013 +0000
@@ -1,3 +1,28 @@
+/*********************************************************************************
+ * PROJECT: MiMic
+ * --------------------------------------------------------------------------------
+ *
+ * This file is part of MiMic
+ * Copyright (C)2011 Ryo Iizuka
+ *
+ * MiMic is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * For further information please contact.
+ *  http://nyatla.jp/
+ *  <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
+ *
+ *********************************************************************************/
 #ifndef NYLPC_CNETCONFIG_H_
 #define NYLPC_CNETCONFIG_H_
 
@@ -6,8 +31,8 @@
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
-#define NyLPC_cNetConfig_INTERFACE_TYPE_ETHERNET 1
 
+#define NyLPC_TcNetConfig_HOSTNAME_LEN 32
 /**
  * クラス型を定義します。
  * NyLPC_cNetConfigクラスは、NyLPC_NetConfigの初期化データを保持します。
@@ -17,27 +42,47 @@
 
 
 /**
- * NyLPC_TcFifoBufferクラスの構造体です。
+ * NyLPC_TcIPv4Configクラスの継承クラスです。
+ * IPv4設定にネットワーク設定項目を加えます。
+ * 加えられる項目は全て[RECOMMEND]パラメータです。
  */
 struct NyLPC_TcNetConfig
 {
-    /** Must be 1*/
-    NyLPC_TUInt16 version;
-    /** インタフェイスタイプ*/
-    NyLPC_TUInt16 interface_type;
+    NyLPC_TcIPv4Config_t super;
+    /**
+     * ホスト名
+     */
+    NyLPC_TChar hostname[NyLPC_TcNetConfig_HOSTNAME_LEN];
+    /**
+     * tcp初期設定モードのフラグ値
+     * NyLPC_TcNetConfig_IPV4_FLAG_Xの組み合わせ
+     * bit 01:IP初期設定のモード. 0:Manual指定,1:DHCP指定,2:AutoIP指定,3:APIPA指定
+     */
+    NyLPC_TUInt32 tcp_mode;
+    struct{
+        /**
+         * サービスのフラグセット。
+         * NyLPC_TcNetConfig_SERVICE_FLAG_xの組み合わせ
+         */
+        NyLPC_TUInt32 flags;
+        NyLPC_TUInt16 http_port;
+        NyLPC_TUInt16 padding;
+    }services;
+
     /** インタフェイス層の設定*/
-    union{
-        /** Ethernet mac address */
-        NyLPC_TcIPv4Config_t ethernet;
-//
-//      struct{
-//          struct NyLPC_TEthAddr mac_addr;
-//      }ethernet2;
-    }interface_setting;
 };
+#define NyLPC_TcNetConfig_IPV4_FLAG_MODE_MASK 3
+#define NyLPC_TcNetConfig_IPV4_FLAG_MODE_MANUAL 0
+#define NyLPC_TcNetConfig_IPV4_FLAG_MODE_DHCP 1
+#define NyLPC_TcNetConfig_IPV4_FLAG_MODE_AUTOIP 2
+#define NyLPC_TcNetConfig_IPV4_FLAG_MODE_APIPA (NyLPC_TcNetConfig_IPV4_FLAG_MODE_DHCP|NyLPC_TcNetConfig_IPV4_FLAG_MODE_AUTOIP)
+
+#define NyLPC_TcNetConfig_SERVICE_FLAG_MDNS 1
 
 /**
- * インスタンスを初期化します。
+ * フラッシュメモリから設定値を読み出して、インスタンスを初期化します。
+ * @param i_is_factory_default
+ * 出荷時設定を読み出すかを設定します。
  */
 void NyLPC_cNetConfig_initialize(NyLPC_TcNetConfig_t* i_inst,NyLPC_TBool i_is_factory_default);
 
@@ -47,17 +92,17 @@
  */
 #define NyLPC_cNetConfig_finalize(i_inst);
 
-#define NyLPC_cNetConfig_setIpAddr(i_inst,ip1,ip2,ip3,ip4) NyLPC_TIPv4Addr_set(&((i_inst)->interface_setting.ethernet.ip_addr),(ip1),(ip2),(ip3),(ip4));
+#define NyLPC_cNetConfig_setIpAddr(i_inst,ip1,ip2,ip3,ip4) NyLPC_TIPv4Addr_set(&((i_inst)->super.ip_addr),(ip1),(ip2),(ip3),(ip4));
 
 /**
  * Set IPv4 network mask value to instance.
  */
-#define NyLPC_cNetConfig_setNetMask(i_inst,ip1,ip2,ip3,ip4) NyLPC_TIPv4Addr_set(&((i_inst)->interface_setting.ethernet.netmask),(ip1),(ip2),(ip3),(ip4));
+#define NyLPC_cNetConfig_setNetMask(i_inst,ip1,ip2,ip3,ip4) NyLPC_TIPv4Addr_set(&((i_inst)->super.netmask),(ip1),(ip2),(ip3),(ip4));
 
 /**
  * Set IPv4 default gateway address to instance.
  */
-#define NyLPC_cNetConfig_setGateway(i_inst,ip1,ip2,ip3,ip4) NyLPC_TIPv4Addr_set(&((i_inst)->interface_setting.ethernet.dr_addr),(ip1),(ip2),(ip3),(ip4));
+#define NyLPC_cNetConfig_setGateway(i_inst,ip1,ip2,ip3,ip4) NyLPC_TIPv4Addr_set(&((i_inst)->super.dr_addr),(ip1),(ip2),(ip3),(ip4));
 
 /**
  * Set ethernet mac address to instance.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/net/apipa/NyLPC_cApipa.c	Wed Jun 19 09:33:01 2013 +0000
@@ -0,0 +1,92 @@
+#include "NyLPC_cApipa.h"
+#include "NyLPC_uipService.h"
+#include "../uip/NyLPC_cUipService_protected.h"
+#include <stdio.h>
+#include <string.h>
+
+
+/**
+ * ARPテーブルに指定IPが現れるまで待ちます。
+ */
+static NyLPC_TBool waitForArpResponse(const struct NyLPC_TIPv4Addr* i_ip,NyLPC_TUInt32 i_wait_in_ms)
+{
+    NyLPC_TcStopwatch_t sw;
+    NyLPC_cStopwatch_initialize(&sw);
+    NyLPC_cStopwatch_startExpire(&sw,i_wait_in_ms);
+    while(!NyLPC_cStopwatch_isExpired(&sw)){
+        NyLPC_cThread_yield();
+        if(NyLPC_cUipService_hasArpInfo(i_ip)){
+            return NyLPC_TBool_TRUE;
+        }
+    }
+    NyLPC_cStopwatch_finalize(&sw);
+    return NyLPC_TBool_FALSE;
+}
+static void makeIP(NyLPC_TcApipa_t* i_inst,struct NyLPC_TIPv4Addr* i_ip)
+{
+//  NyLPC_TIPv4Addr_set(i_ip,192,168,128,206);//for conflict test!
+    NyLPC_TIPv4Addr_set(i_ip,169,254,(i_inst->_seed>>8)&0xff,i_inst->_seed & 0xff);
+}
+static void updateSeed(NyLPC_TcApipa_t* i_inst)
+{
+    do{
+        i_inst->_seed=(391*i_inst->_seed+392);
+    }while(((i_inst->_seed & 0xff)==0) || ((i_inst->_seed & 0xff00)==0));
+}
+
+
+
+void NyLPC_cApipa_initialize(NyLPC_TcApipa_t* i_inst)
+{
+    i_inst->_seed=0;
+}
+
+
+/**
+ * この関数はuipを操作します。
+ * cNetは停止中である必要があります。
+ */
+NyLPC_TBool NyLPC_cApipa_requestAddr(NyLPC_TcApipa_t* i_inst,NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat)
+{
+    int i;
+    NyLPC_TcIPv4Config_t cfg;
+    struct NyLPC_TIPv4Addr caip;
+
+    //ゼロコンフィギュレーション用のIPを設定
+    NyLPC_cIPv4Config_initialzeCopy(&cfg,i_cfg);
+    //seedを更新
+    for(i=0;i<6;i++)
+    {
+        i_inst->_seed+=i_cfg->eth_mac.addr[i];
+    }
+    NyLPC_cIPv4Config_setDefaultRoute(&cfg,&NyLPC_TIPv4Addr_ZERO);
+    for(i=i_repeat-1;i>=0;i--){
+        NyLPC_cIPv4Config_setIp(&cfg,&NyLPC_TIPv4Addr_ZERO,&NyLPC_TIPv4Addr_ZERO);
+        updateSeed(i_inst);
+        makeIP(i_inst,&caip);
+        //startInterface
+        NyLPC_cUipService_start(&cfg);
+        NyLPC_cUipService_sendArpRequest(&caip);
+        //テーブル更新待ち
+        if(waitForArpResponse(&caip,512+(i_inst->_seed % 256))){
+            NyLPC_cUipService_stop();
+            continue;
+        }
+        NyLPC_cUipService_stop();
+        //IPのコンフリクトテスト
+        NyLPC_cIPv4Config_setIp(&cfg,&caip,&NyLPC_TIPv4Addr_APIPA_MASK);
+        NyLPC_cUipService_start(&cfg);
+        //!ARP送信
+        NyLPC_cUipService_sendArpRequest(&caip);
+        if(waitForArpResponse(&caip,512+(256-(i_inst->_seed % 256)))){
+            //応答があったらエラー
+            NyLPC_cUipService_stop();
+            continue;
+        }
+        //OK
+        NyLPC_cUipService_stop();
+        NyLPC_cIPv4Config_setIp(i_cfg,&cfg.ip_addr,&cfg.netmask);
+        return NyLPC_TBool_TRUE;
+    }
+    return NyLPC_TBool_FALSE;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/net/apipa/NyLPC_cApipa.h	Wed Jun 19 09:33:01 2013 +0000
@@ -0,0 +1,56 @@
+/*********************************************************************************
+ * PROJECT: MiMic
+ * --------------------------------------------------------------------------------
+ *
+ * This file is part of MiMic
+ * Copyright (C)2011-2013 Ryo Iizuka
+ *
+ * MiMic is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * For further information please contact.
+ *  http://nyatla.jp/
+ *  <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
+ *
+ *********************************************************************************/
+#ifndef NYLPC_CAPIPA_H_
+#define NYLPC_CAPIPA_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "NyLPC_stdlib.h"
+#include "NyLPC_net.h"
+
+typedef struct NyLPC_cApipa NyLPC_TcApipa_t;
+
+struct NyLPC_cApipa
+{
+    NyLPC_TUInt32 _seed;
+};
+void NyLPC_cApipa_initialize(NyLPC_TcApipa_t* i_inst);
+
+#define NyLPC_cApipa_finalize(i_inst)
+
+
+/**
+ * i_cfgにAutoIPのアドレスを取得します。
+ * この関数はuipを操作します。uipServiceは停止中である必要があります。
+ */
+NyLPC_TBool NyLPC_cApipa_requestAddr(NyLPC_TcApipa_t* i_inst,NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* NYLPC_CAPIPA_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/net/dhcp/NyLPC_cDhcpClient.c	Wed Jun 19 09:33:01 2013 +0000
@@ -0,0 +1,344 @@
+/*********************************************************************************
+ * PROJECT: MiMic
+ * --------------------------------------------------------------------------------
+ *
+ * This file is part of MiMic
+ * Copyright (C)2011-2013 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_cDhcpClient.h"
+#include <stdio.h>
+#include <string.h>
+
+struct NyLPC_TDhcpHeader
+{
+    NyLPC_TUInt8 op;
+    NyLPC_TUInt8 htype;
+    NyLPC_TUInt8 hlen;
+    NyLPC_TUInt8 hops;
+    NyLPC_TUInt32 xid;
+    NyLPC_TUInt16 secs;
+    NyLPC_TUInt16 flags;
+    NyLPC_TUInt32 ciaddr;
+    NyLPC_TUInt32 yiaddr;
+    NyLPC_TUInt32 siaddr;
+    NyLPC_TUInt32 giaddr;
+    struct{
+        struct NyLPC_TEthAddr emac;
+        NyLPC_TChar padding[10];
+    }chaddr;
+    NyLPC_TChar sname[64];
+    NyLPC_TChar file[128];
+}PACK_STRUCT_END;
+
+#define NyLPC_TDhcpHeader_BOOTREQUEST 1
+#define NyLPC_TDhcpHeader_BOOTREPLY   2
+
+#define DHCP_OPT_ID_ROUTER 3
+#define DHCP_OPT_ID_SERVER_ID 54
+#define DHCP_OPT_ID_NETMASK 1
+#define DHCP_OPT_ID_MESSAGETYPE 53
+
+
+
+/**
+ * DHCPパケットから32bit値を読み出す。
+ * @return
+ * ネットワークオーダー
+ */
+static NyLPC_TBool getUInt32Option(const NyLPC_TUInt8* i_buf,NyLPC_TUInt16 len,NyLPC_TUInt8 i_id,NyLPC_TUInt32* o_v)
+{
+    const NyLPC_TUInt8* p=i_buf+sizeof(struct NyLPC_TDhcpHeader)+4;
+    while(*p!=0x00 && p<(i_buf+len-5)){
+        if(*p==i_id){
+            if(*(p+1)==4){
+                *o_v=*((NyLPC_TUInt32*)(p+2));
+                return NyLPC_TBool_TRUE;
+            }
+        }else{
+            p+=(*(p+1))+2;
+        }
+    }
+    return NyLPC_TBool_FALSE;
+}
+static NyLPC_TBool getUInt8Option(const NyLPC_TUInt8* i_buf,NyLPC_TUInt16 len,NyLPC_TUInt8 i_id,NyLPC_TUInt8* o_v)
+{
+    const NyLPC_TUInt8* p=i_buf+sizeof(struct NyLPC_TDhcpHeader)+4;
+    while(*p!=0x00 && p<(i_buf+len-5)){
+        if(*p==i_id){
+            if(*(p+1)==1){
+                *o_v=*(p+2);
+                return NyLPC_TBool_TRUE;
+            }
+        }else{
+            p+=(*(p+1))+2;
+        }
+    }
+    return NyLPC_TBool_FALSE;
+}
+static NyLPC_TBool NyLPC_TDhcpHeader_parseDHCPOFFER(const NyLPC_TUInt8* i_buf,NyLPC_TUInt16 i_len,NyLPC_TUInt32 i_xid,NyLPC_TcIPv4Config_t* result)
+{
+    struct NyLPC_TDhcpHeader* p=(struct NyLPC_TDhcpHeader*)i_buf;
+    //XIDのチェック
+    if(p->xid!=NyLPC_HTONL(i_xid)){
+        return NyLPC_TBool_FALSE;
+    }
+    //サーバ情報をIPへ保存
+    if(!getUInt32Option(i_buf,i_len,DHCP_OPT_ID_SERVER_ID,&result->ip_addr.v)){
+        return NyLPC_TBool_FALSE;
+    }
+    return NyLPC_TBool_TRUE;
+}
+
+static NyLPC_TBool NyLPC_TDhcpHeader_parseDHCPACK(const NyLPC_TUInt8* i_buf,NyLPC_TUInt16 i_len,NyLPC_TUInt32 i_xid,NyLPC_TcIPv4Config_t* result)
+{
+    struct NyLPC_TDhcpHeader* p=(struct NyLPC_TDhcpHeader*)i_buf;
+    //XIDのチェック
+    if(p->xid!=NyLPC_HTONL(i_xid)){
+        return NyLPC_TBool_FALSE;
+    }
+    if(!getUInt32Option(i_buf,i_len,DHCP_OPT_ID_ROUTER,&result->dr_addr.v)){
+        result->dr_addr=NyLPC_TIPv4Addr_ZERO;
+    }
+    if(!getUInt32Option(i_buf,i_len,DHCP_OPT_ID_NETMASK,&result->netmask.v)){
+        result->netmask=NyLPC_TIPv4Addr_ZERO;
+    }
+    result->ip_addr.v=p->yiaddr;
+    return NyLPC_TBool_TRUE;
+}
+
+static void NyLPC_TDhcpHeader_setDHCPDISCOVER(char* i_buf,NyLPC_TUInt32 i_xid,const struct NyLPC_TEthAddr* emac,NyLPC_TUInt16* o_len)
+{
+    struct NyLPC_TDhcpHeader* p=(struct NyLPC_TDhcpHeader*)i_buf;
+    memset(i_buf,0,sizeof(struct NyLPC_TDhcpHeader));
+    p->op=NyLPC_TDhcpHeader_BOOTREQUEST;
+    p->htype=1;
+    p->hlen=6;
+    p->xid=NyLPC_HTONL(i_xid);
+    p->chaddr.emac=*emac;
+    memcpy(i_buf+sizeof(struct NyLPC_TDhcpHeader),
+        "\x63\x82\x53\x63"      //4
+        "\x35\x01\x01"          //3 MESSAGE TYPE
+        "\x37\x03\x01\x03\x06"  //5 REQUEST LIST(1,3,6)
+        "\x3d\x07\x00\x00\x00\x00\x00\x00\x10" //9 CLIENT INDIFIRE
+        "\xff",4+3+5+9+1);
+    //emacの上書き
+    memcpy((i_buf+sizeof(struct NyLPC_TDhcpHeader)+4+3+5+2),emac->addr,6);
+    //送信するパケットの長さ
+    *o_len=sizeof(struct NyLPC_TDhcpHeader)+4+3+5+9+1;
+    return;
+}
+static void NyLPC_TDhcpHeader_setDHCPREQUEST(char* i_buf,NyLPC_TUInt32 i_xid,const struct NyLPC_TIPv4Addr* i_sid,const struct NyLPC_TEthAddr* emac,NyLPC_TUInt16* o_len)
+{
+    struct NyLPC_TDhcpHeader* p=(struct NyLPC_TDhcpHeader*)i_buf;
+    memset(i_buf,0,sizeof(struct NyLPC_TDhcpHeader));
+    p->op=NyLPC_TDhcpHeader_BOOTREQUEST;
+    p->htype=1;
+    p->hlen=6;
+    p->xid=NyLPC_HTONL(i_xid);
+    p->chaddr.emac=*emac;
+    memcpy(i_buf+sizeof(struct NyLPC_TDhcpHeader),
+        "\x63\x82\x53\x63"      //4
+        "\x35\x01\x03"          //3 MESSAGE TYPE
+        "\x37\x03\x01\x03\x06"  //5 REQUEST LIST(1,3,6)
+        "\x3d\x07\x00\x00\x00\x00\x00\x00\x10" //9 CLIENT INDIFIRE
+        "\x36\x04\x00\x00\x00\x00" // 6 SERVER ID
+        "\xff",4+3+5+9+6+1);
+    //emacの上書き
+    memcpy((i_buf+sizeof(struct NyLPC_TDhcpHeader)+4+3+5+2),emac->addr,6);
+    //sidの上書き
+    memcpy((i_buf+sizeof(struct NyLPC_TDhcpHeader)+4+3+5+9+2),i_sid,4);
+    //送信するパケットの長さ
+    *o_len=sizeof(struct NyLPC_TDhcpHeader)+4+3+5+9+6+1;
+    return;
+}
+
+
+
+#define TcDhcpSock_ST_WAIT_OFFER    1
+#define TcDhcpSock_ST_WAIT_OFFER_OK 2
+#define TcDhcpSock_ST_WAIT_ACK 3
+#define TcDhcpSock_ST_WAIT_ACK_OK 4
+#define TcDhcpSock_ST_DONE_NG 3
+#define TcDhcpSock_ST_DONE_OK 4
+
+
+
+
+#define DHCP_OPT_ID_MESSAGETYPE_ACK   5
+#define DHCP_OPT_ID_MESSAGETYPE_OFFER 2
+
+static NyLPC_TBool onPacket(NyLPC_TcUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info);
+
+/**
+ * DHCPソケットを作成します。
+ */
+NyLPC_TBool NyLPC_cDhcpClient_initialize(NyLPC_TcDhcpClient_t* i_inst)
+{
+    if(!NyLPC_cUdpSocket_initialize(&(i_inst->super),68,NULL,0)){
+        return NyLPC_TBool_FALSE;
+    }
+    NyLPC_cUdpSocket_setBroadcast(&(i_inst->super));
+    NyLPC_cUdpSocket_setOnRxHandler(&(i_inst->super),onPacket);
+    return NyLPC_TBool_TRUE;
+}
+void NyLPC_cDhcpClient_finalize(NyLPC_TcDhcpClient_t* i_inst)
+{
+    NyLPC_cUdpSocket_finalize(&(i_inst->super));
+}
+#define TIMEOUT_SOCKAPI_MS 1000
+#define TIMEOUT_RECVMSG_MS 3000
+
+/**
+ * ネットワークを更新します。
+ * emac/default_mssを設定したネットワークが必要です。
+ */
+static NyLPC_TBool NyLPC_cDhcpClient_dhcpRequest(NyLPC_TcDhcpClient_t* i_sock,NyLPC_TcIPv4Config_t* i_result)
+{
+    char* buf;
+    NyLPC_TcStopwatch_t sw;
+    NyLPC_TUInt16 s;
+    NyLPC_TInt16 hint=sizeof(struct NyLPC_TDhcpHeader)+128;
+    i_sock->txid+=(*(NyLPC_TUInt16*)(&(i_result->eth_mac.addr[2])))+(*(NyLPC_TUInt16*)(&(i_result->eth_mac.addr[4])));
+    i_sock->_result=i_result;
+    buf=NyLPC_cUdpSocket_allocSendBuf(&i_sock->super,hint,&s,TIMEOUT_SOCKAPI_MS);
+    if(buf==NULL || s<hint){
+        return NyLPC_TBool_FALSE;
+    }
+    NyLPC_TDhcpHeader_setDHCPDISCOVER(buf,i_sock->txid,&i_sock->_result->eth_mac,&s);
+    i_sock->_status=TcDhcpSock_ST_WAIT_OFFER;
+    if(!NyLPC_cUdpSocket_psend(&i_sock->super,&NyLPC_TIPv4Addr_BROADCAST,67,buf,s)){
+        NyLPC_cUdpSocket_releaseSendBuf(&i_sock->super,buf);
+        return NyLPC_TBool_FALSE;
+    }
+    NyLPC_cStopwatch_initialize(&sw);
+    NyLPC_cStopwatch_startExpire(&sw,TIMEOUT_RECVMSG_MS);
+    while(i_sock->_status==TcDhcpSock_ST_WAIT_OFFER){
+        if(NyLPC_cStopwatch_isExpired(&sw)){
+            return NyLPC_TBool_FALSE;
+        }
+    }
+    //レスポンスのチェック
+    if(i_sock->_status!=TcDhcpSock_ST_WAIT_OFFER_OK)
+    {
+        return NyLPC_TBool_FALSE;
+    }
+    buf=NyLPC_cUdpSocket_allocSendBuf(&i_sock->super,hint,&s,TIMEOUT_SOCKAPI_MS);
+    if(buf==NULL || s<hint){
+        return NyLPC_TBool_FALSE;
+    }
+    NyLPC_TDhcpHeader_setDHCPREQUEST(buf,i_sock->txid,&(i_sock->_result->ip_addr),&i_sock->_result->eth_mac,&s);
+    i_sock->_status=TcDhcpSock_ST_WAIT_ACK;
+    if(!NyLPC_cUdpSocket_psend(&i_sock->super,&NyLPC_TIPv4Addr_BROADCAST,67,buf,s)){
+        NyLPC_cUdpSocket_releaseSendBuf(&i_sock->super,buf);
+        return NyLPC_TBool_FALSE;
+    }
+    NyLPC_cStopwatch_startExpire(&sw,TIMEOUT_RECVMSG_MS);
+    while(i_sock->_status==TcDhcpSock_ST_WAIT_ACK){
+        if(NyLPC_cStopwatch_isExpired(&sw)){
+            return NyLPC_TBool_FALSE;
+        }
+    }
+    //レスポンスのチェック
+    if(i_sock->_status!=TcDhcpSock_ST_WAIT_ACK_OK)
+    {
+        return NyLPC_TBool_FALSE;
+    }
+    return NyLPC_TBool_TRUE;
+}
+
+/**
+ * NyLPC_TcIPv4Config_tをDHCPで更新します。
+ * この関数をコールする時は、サービスは停止中でなければなりません。
+ * @param i_cfg
+ * 更新するi_cfg構造体。
+ * emac,default_mssは設定済である必要があります。他のフィールド値は不定で構いません。
+ * 更新されるフィールドは、ip,netmast,default_rootの3つです。
+ * @return
+ * 更新に成功した場合TRUE
+ */
+NyLPC_TBool NyLPC_cDhcpClient_requestAddr(NyLPC_TcDhcpClient_t* i_inst,NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat)
+{
+    NyLPC_TInt16 i;
+    NyLPC_TBool ret=NyLPC_TBool_FALSE;
+    NyLPC_TcIPv4Config_t c2;
+    //工場出荷時設定でリセットしてIPを0に
+    NyLPC_cIPv4Config_initialzeCopy(&c2,i_cfg);
+    NyLPC_cIPv4Config_setIp(&c2,&NyLPC_TIPv4Addr_ZERO,&NyLPC_TIPv4Addr_ZERO);
+    NyLPC_cIPv4Config_setDefaultRoute(&c2,&NyLPC_TIPv4Addr_ZERO);
+    //netを開始
+    NyLPC_cUipService_start(&c2);
+    for(i=i_repeat-1;i>=0;i--){
+        ret=NyLPC_cDhcpClient_dhcpRequest(i_inst,i_cfg);
+        if(ret){
+            break;
+        }
+    }
+    NyLPC_cUipService_stop();
+    NyLPC_cIPv4Config_finalize(&c2);
+    return ret;
+}
+
+
+
+static NyLPC_TBool onPacket(NyLPC_TcUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info)
+{
+    NyLPC_TUInt8 mt;//message type
+    NyLPC_TcDhcpClient_t* inst=(NyLPC_TcDhcpClient_t*)i_inst;
+    struct NyLPC_TDhcpHeader* dnsh=(struct NyLPC_TDhcpHeader*)i_buf;
+    if(i_info->size<sizeof(struct NyLPC_TDhcpHeader)+1){
+        return NyLPC_TBool_FALSE;//DROP
+    }
+    switch(inst->_status)
+    {
+    case TcDhcpSock_ST_WAIT_ACK:
+        if(dnsh->op!=NyLPC_TDhcpHeader_BOOTREPLY){
+            return NyLPC_TBool_FALSE;
+            }
+        if(!getUInt8Option(i_buf,i_info->size,DHCP_OPT_ID_MESSAGETYPE,&mt)){
+            return NyLPC_TBool_FALSE;
+        }
+        if(mt!=DHCP_OPT_ID_MESSAGETYPE_ACK){
+            return NyLPC_TBool_FALSE;
+        }
+        if(!NyLPC_TDhcpHeader_parseDHCPACK(i_buf,i_info->size,inst->txid,inst->_result)){
+            return NyLPC_TBool_FALSE;
+        }
+        inst->_status=TcDhcpSock_ST_WAIT_ACK_OK;
+        break;
+    case TcDhcpSock_ST_WAIT_OFFER:
+        if(dnsh->op!=NyLPC_TDhcpHeader_BOOTREPLY){
+            return NyLPC_TBool_FALSE;
+            }
+        if(!getUInt8Option(i_buf,i_info->size,DHCP_OPT_ID_MESSAGETYPE,&mt)){
+            return NyLPC_TBool_FALSE;
+        }
+        if(mt!=DHCP_OPT_ID_MESSAGETYPE_OFFER){
+            return NyLPC_TBool_FALSE;
+        }
+        if(!NyLPC_TDhcpHeader_parseDHCPOFFER(i_buf,i_info->size,inst->txid,inst->_result)){
+            return NyLPC_TBool_FALSE;
+        }
+        inst->_status=TcDhcpSock_ST_WAIT_OFFER_OK;
+        break;
+    }
+    return NyLPC_TBool_FALSE;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/net/dhcp/NyLPC_cDhcpClient.h	Wed Jun 19 09:33:01 2013 +0000
@@ -0,0 +1,71 @@
+/*********************************************************************************
+ * PROJECT: MiMic
+ * --------------------------------------------------------------------------------
+ *
+ * This file is part of MiMic
+ * Copyright (C)2011-2013 Ryo Iizuka
+ *
+ * MiMic is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * For further information please contact.
+ *  http://nyatla.jp/
+ *  <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
+ *
+ *********************************************************************************/
+#ifndef NYLPC_CDHCPCLIENT_H_
+#define NYLPC_CDHCPCLIENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "NyLPC_net.h"
+
+typedef struct NyLPC_TcDhcpClient NyLPC_TcDhcpClient_t;
+
+struct NyLPC_TcDhcpClient{
+    NyLPC_TcUdpSocket_t super;
+    NyLPC_TcIPv4Config_t* _result;
+    NyLPC_TUInt32 txid;
+    volatile NyLPC_TUInt16 _status;
+};
+
+
+/**
+ * DHCPソケットを作成します。
+ */
+NyLPC_TBool NyLPC_cDhcpClient_initialize(NyLPC_TcDhcpClient_t* i_inst);
+
+void NyLPC_cDhcpClient_finalize(NyLPC_TcDhcpClient_t* i_inst);
+
+/**
+ * NyLPC_TcIPv4Config_tをDHCPで更新します。
+ * この関数をコールする時は、サービスは停止中でなければなりません。
+ * @param i_cfg
+ * 更新するi_cfg構造体。
+ * emac,default_mssは設定済である必要があります。他のフィールド値は不定で構いません。
+ * 更新されるフィールドは、ip,netmast,default_rootの3つです。
+ * @return
+ * 更新に成功した場合TRUE
+ */
+NyLPC_TBool NyLPC_cDhcpClient_requestAddr(NyLPC_TcDhcpClient_t* i_inst,NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
--- a/core/net/httpd/NyLPC_cHttpd.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/net/httpd/NyLPC_cHttpd.h	Wed Jun 19 09:33:01 2013 +0000
@@ -4,7 +4,6 @@
 
 #include "NyLPC_stdlib.h"
 #include "../NyLPC_cNetConfig.h"
-#include "NyLPC_cHttpd.h"
 #include "NyLPC_cHttpdThread.h"
 
 #ifdef __cplusplus
@@ -18,7 +17,7 @@
 
 
 
-#define NyLPC_cNet_NUMBER_OF_THREAD 4
+#define NyLPC_cNet_NUMBER_OF_THREAD 2
 typedef void (*NyLPC_TcHttpd_onRequest)(NyLPC_TcHttpdConnection_t* i_inst);
 
 /**
--- a/core/net/httpd/NyLPC_cHttpdConnection.c	Thu May 16 16:06:46 2013 +0000
+++ b/core/net/httpd/NyLPC_cHttpdConnection.c	Wed Jun 19 09:33:01 2013 +0000
@@ -235,13 +235,13 @@
     return NyLPC_TBool_TRUE;
 }
 
+
 /**
  * コネクションのソケットをacceptします。
  */
 NyLPC_TBool NyLPC_cHttpdConnection_acceptSocket(NyLPC_TcHttpdConnection_t* i_inst)
 {
     NyLPC_Assert(i_inst->_req_status==NyLPC_cHttpdConnection_ReqStatus_ACCEPT);
-
     if(!NyLPC_cTcpSocket_accept(&(i_inst->_socket),NyLPC_cHttpdConnection_TIMEOUT_ACCEPT)){
         NyLPC_OnErrorGoto(Error);
     }
--- a/core/net/httpd/NyLPC_cHttpdThread.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/net/httpd/NyLPC_cHttpdThread.h	Wed Jun 19 09:33:01 2013 +0000
@@ -21,7 +21,7 @@
 #endif
 
 /** Httpdセッションスレッドのスタックサイズ*/
-#define NyLPC_TcHttpdThread_SIZE_OF_THREAD_STACK 2048
+#define NyLPC_TcHttpdThread_SIZE_OF_THREAD_STACK 1024
 
 typedef struct NyLPC_TcHttpdThread NyLPC_TcHttpdThread_t;
 /**
--- a/core/net/httpd/mod/NyLPC_cMocMiMicSetting.c	Thu May 16 16:06:46 2013 +0000
+++ b/core/net/httpd/mod/NyLPC_cMocMiMicSetting.c	Wed Jun 19 09:33:01 2013 +0000
@@ -31,9 +31,10 @@
 #include "NyLPC_flash.h"
 #include "../NyLPC_cHttpdConnection_protected.h"
 #include "../../NyLPC_cNet.h"
+#include <ctype.h>
 
-#define MOD_VERSION "ModMiMicSetting/1.2"
-#define SIZE_OF_SETUP_PARAM 7
+#define MOD_VERSION "ModMiMicSetting/1.3"
+#define SIZE_OF_SETUP_PARAM 8
 struct TModMiMicSettingRequest
 {
     struct NyLPC_THttpBasicHeader super;
@@ -47,19 +48,30 @@
     /** 文字列のパーサ*/
     NyLPC_TcMiMicDbCompiler_t _binparser;
     union{
-        struct{
-            /**pパラメータ。最大長さは16。長さ6であること。
-             * [0]:MACAddrの、[0][1][2][3]
-             * [1]:MACAddrの、[4][5][X][X]
-             * [2]:IPAddr(Networkorder)
-             * [3]:Subnetmask(Networkorder)
-             * [4]:Defaultgateway
-             * [5]:[0:port0][1:port1][X][X]
-             * [6]:accessmode [0:AC1][1:AC2][X][X]
+        /**
+         * スタックサイズ削減のための構造体。tmpは受信処理に使用。
+         * memimgはFlashへ書き込むときに使用。
+         */
+        union{
+            /**
+             * 受信用構造体。host_name,param_buf[6]までのデータは、memimgのfast_boot以降のデータ構造と位置をあわせてください。
+             * param_buf[7]以降については値変換必須
+             * tmpにデータを作成後にmemimgへ整形して書きこむかんじ。
              */
-            NyLPC_TUInt32 param_buf[SIZE_OF_SETUP_PARAM];
-            NyLPC_TUInt16 param_len;
-            NyLPC_TUInt32 cval;//コマンド値
+            struct{
+                NyLPC_TUInt16 param_len;
+                NyLPC_TUInt16 host_len;
+                NyLPC_TChar host_name[NyLPC_TcNetConfig_HOSTNAME_LEN];
+                /**pパラメータ。最大長さは16。
+                 * 詳細はNyLPC_TcModMiMicSetting_tを参照
+                 */
+                NyLPC_TUInt32 param_buf[SIZE_OF_SETUP_PARAM];
+                NyLPC_TUInt32 cval;//コマンド値
+            }tmp;
+            /**
+             * 書き込み用構造体
+             */
+            struct NyLPC_TMiMicConfigulation memimg;
         }setup;
         struct{
             /**
@@ -84,6 +96,7 @@
 #define ST_PARSE_QUERY_VALUE 3      //Query読み出し中
 #define ST_PARSE_QUERY_VALUE_P 4
 #define ST_PARSE_QUERY_VALUE_C 5
+#define ST_PARSE_QUERY_VALUE_HOST 6
 /**
  * コンテンツID定義(コンテンツ名に対応)
  */
@@ -96,6 +109,7 @@
 
 #define QNAME_ID_P  4
 #define QNAME_ID_C  5
+#define QNAME_ID_HOST   6
 #define QNAME_ID_UNKNOWN 0
 
 #define QVAL_C_GET 1
@@ -113,6 +127,7 @@
 {
     {"p",QNAME_ID_P},
     {"c",QNAME_ID_C},
+    {"host",QNAME_ID_HOST},
     {NULL,QNAME_ID_UNKNOWN}
 };
 
@@ -139,8 +154,9 @@
         switch(out->_content_id)
         {
         case CONTENT_ID_SETUP:
-            out->content.setup.param_len=0;
-            out->content.setup.cval=QVAL_C_UNKNOWN;
+            out->content.setup.tmp.param_len=0;//クエリが無い場合の初期値
+            out->content.setup.tmp.host_len =0;//クエリが無い場合の初期値
+            out->content.setup.tmp.cval=QVAL_C_UNKNOWN;
             break;
         default:
             break;
@@ -167,11 +183,15 @@
             switch(out->_qery_name_id){
             case QNAME_ID_P:
                 out->_astate=ST_PARSE_QUERY_VALUE_P;//MIMICBCのDBパラメータパーサを借用。
-                out->content.setup.param_len=0;
+                out->content.setup.tmp.param_len=0;
                 break;
             case QNAME_ID_C:
                 out->_astate=ST_PARSE_QUERY_VALUE_C;
                 break;
+            case QNAME_ID_HOST:
+                out->_astate=ST_PARSE_QUERY_VALUE_HOST;//_host_nameに蓄積
+                out->content.setup.tmp.host_len=0;
+                break;
             default:
                 out->_astate=ST_PARSE_QUERY_VALUE;
                 break;
@@ -185,6 +205,24 @@
             //クエリ値解析完了
             out->_astate=ST_PARSE_QUERY_NAME;
             return NyLPC_TBool_TRUE;
+        case ST_PARSE_QUERY_VALUE_HOST:
+            //未知のクエリは無視
+            if(i_c!='\0' && i_c!='&'){
+                //許可する文字列は、[:AlNum:]||'_'
+                if(!isalnum(i_c) && i_c!='_'){
+                    NyLPC_OnErrorGoto(ERROR);
+                }
+                out->content.setup.tmp.host_name[out->content.setup.tmp.host_len++]=i_c;
+                if(out->content.setup.tmp.host_len>=NyLPC_TcNetConfig_HOSTNAME_LEN){
+                    //長すぎ
+                    NyLPC_OnErrorGoto(ERROR);
+                }
+                return NyLPC_TBool_TRUE;
+            }
+            //クエリ値解析完了
+            out->content.setup.tmp.host_name[out->content.setup.tmp.host_len]='\0';
+            out->_astate=ST_PARSE_QUERY_NAME;
+            return NyLPC_TBool_TRUE;
         case ST_PARSE_QUERY_VALUE_C:
             if(i_c!='\0' && i_c!='&'){
                 if(!NyLPC_cStr_put(&(out->_tstr),i_c)){
@@ -193,9 +231,9 @@
                 return NyLPC_TBool_TRUE;
             }
             if(NyLPC_cStr_isEqual(&out->_tstr,"get")){
-                out->content.setup.cval=QVAL_C_GET;
+                out->content.setup.tmp.cval=QVAL_C_GET;
             }else if(NyLPC_cStr_isEqual(&out->_tstr,"update")){
-                out->content.setup.cval=QVAL_C_UPDATE;
+                out->content.setup.tmp.cval=QVAL_C_UPDATE;
             }else{
                 NyLPC_OnErrorGoto(ERROR);
             }
@@ -204,16 +242,16 @@
             return NyLPC_TBool_TRUE;
         case ST_PARSE_QUERY_VALUE_P:
             if(i_c!='\0' && i_c!='&'){
-                if(out->content.setup.param_len>=SIZE_OF_SETUP_PARAM)
+                if(out->content.setup.tmp.param_len>=SIZE_OF_SETUP_PARAM)
                 {
                     NyLPC_OnErrorGoto(ERROR);
                 }
-                switch(NyLPC_cMiMicDbCompiler_compileFragment2(&(out->_binparser),i_c,out->content.setup.param_buf+out->content.setup.param_len))
+                switch(NyLPC_cMiMicDbCompiler_compileFragment2(&(out->_binparser),i_c,out->content.setup.tmp.param_buf+out->content.setup.tmp.param_len))
                 {
                 case NyLPC_TcMiMicDbCompiler_RET_CONTINUE:
                     break;
                 case NyLPC_TcMiMicDbCompiler_RET_OK:
-                    out->content.setup.param_len++;
+                    out->content.setup.tmp.param_len++;
                     break;
                 case NyLPC_TcMiMicDbCompiler_RET_ERROR:
                 default:
@@ -345,59 +383,83 @@
 static void setup_proc(NyLPC_TcHttpdConnection_t* i_connection,struct TModMiMicSettingRequest* i_req)
 {
     NyLPC_TBool ret;
-    const struct NyLPC_TMimicConfigulation* config;
-    struct NyLPC_TMimicConfigulation cfg_image;
-    const NyLPC_TcIPv4Config_t* currebt_cfg;
+    const struct NyLPC_TMiMicConfigulation* config;
+    const NyLPC_TcNetConfig_t* currebt_cfg;
     NyLPC_Assert(
         (NyLPC_cHttpdConnection_getMethod(i_connection)==NyLPC_THttpMethodType_GET)||
         (NyLPC_cHttpdConnection_getMethod(i_connection)==NyLPC_THttpMethodType_HEAD));
 
-    switch(i_req->content.setup.cval){
+    switch(i_req->content.setup.tmp.cval){
     case QVAL_C_GET:
         if(!NyLPC_cHttpdUtils_sendJsonHeader(i_connection)){
             NyLPC_OnErrorGoto(Error);
         }
         if(NyLPC_cHttpdConnection_getMethod(i_connection)==NyLPC_THttpMethodType_GET){
             config=NyLPC_cMiMicConfiglation_loadFromFlash();
-            //JSONを書く。
+            //Flashの内容から
             if(!NyLPC_cHttpdConnection_sendResponseBodyF(i_connection,
                 "{"
                 "\"application\":\""MOD_VERSION";"NyLPC_cMiMicEnv_VERSION";%s\","
+                "\"landev\":\"%s\",",
+                NyLPC_cNet_PlatformName,
+                NyLPC_cUipService_refDeviceName()
+                ))
+            {
+                NyLPC_OnErrorGoto(Error);
+            }
+            if(!NyLPC_cHttpdConnection_sendResponseBodyF(i_connection,
+                "\"cfg\":{"
                 "\"mac00010203\":%u,"
                 "\"mac0405xxxx\":%u,"
-                "\"ip\":%u,"
-                "\"mask\":%u,"
-                "\"droute\":%u,"
-                "\"port\":%u,"
-                "\"access\":%u,",
-                NyLPC_cNet_PlatformName,
+                "\"host\":\"%s\","
+                "\"ipv4\":{"
+                    "\"flags\":%u,"
+                    "\"ip\":%u,"
+                    "\"mask\":%u,"
+                    "\"droute\":%u,"
+                "},"
+                "\"services\":{"
+                    "\"flags\":%u,"
+                    "\"http_port\":%u"
+                "}},",
                 config->mac_00_01_02_03,
                 config->mac_04_05_xx_xx,
+                config->hostname,
+                config->ipv4_flags,
                 config->ipv4_addr_net,
                 config->ipv4_mask_net,
                 config->ipv4_drut_net,
-                config->ipv4_port,
-                config->accessmode
+                config->srv_flags,
+                config->http_port
                 )){
                 NyLPC_OnErrorGoto(Error);
             }
             //write current status
-            currebt_cfg=NyLPC_cUipService_refCurrentConfig();
+            currebt_cfg=(const NyLPC_TcNetConfig_t*)NyLPC_cUipService_refCurrentConfig();
             if(!NyLPC_cHttpdConnection_sendResponseBodyF(i_connection,
-                "\"info\":{"
-                    "\"landev\":\"%s\","
-                    "\"mac00010203\":%u,"
-                    "\"mac0405xxxx\":%u,"
+                "\"cur\":{"
+                "\"mac00010203\":%u,"
+                "\"mac0405xxxx\":%u,"
+                "\"host\":\"%s\","
+                "\"ipv4\":{"
+                    "\"flags\":%u,"
                     "\"ip\":%u,"
                     "\"mask\":%u,"
-                    "\"droute\":%u"
-                "}}",
-                NyLPC_cUipService_refDeviceName(),
-                (currebt_cfg->eth_mac.addr[0]<<24)|(currebt_cfg->eth_mac.addr[1]<<16)|(currebt_cfg->eth_mac.addr[2]<<8)|currebt_cfg->eth_mac.addr[3],
-                (currebt_cfg->eth_mac.addr[4]<<24)|(currebt_cfg->eth_mac.addr[5]<<16),
-                NyLPC_ntohl(currebt_cfg->ip_addr.v),
-                NyLPC_ntohl(currebt_cfg->netmask.v),
-                NyLPC_ntohl(currebt_cfg->dr_addr.v)
+                    "\"droute\":%u,"
+                "},"
+                "\"services\":{"
+                    "\"flags\":%u,"
+                    "\"http_port\":%u"
+                "}}}",
+                (currebt_cfg->super.eth_mac.addr[0]<<24)|(currebt_cfg->super.eth_mac.addr[1]<<16)|(currebt_cfg->super.eth_mac.addr[2]<<8)|currebt_cfg->super.eth_mac.addr[3],
+                (currebt_cfg->super.eth_mac.addr[4]<<24)|(currebt_cfg->super.eth_mac.addr[5]<<16),
+                currebt_cfg->hostname,
+                currebt_cfg->tcp_mode,
+                NyLPC_ntohl(currebt_cfg->super.ip_addr.v),
+                NyLPC_ntohl(currebt_cfg->super.netmask.v),
+                NyLPC_ntohl(currebt_cfg->super.dr_addr.v),
+                currebt_cfg->services.flags,
+                currebt_cfg->services.http_port
                 )){
                 NyLPC_OnErrorGoto(Error);
             }
@@ -405,27 +467,31 @@
         break;
     case QVAL_C_UPDATE:
         //check parameter length
-        if(i_req->content.setup.param_len!=SIZE_OF_SETUP_PARAM)
+        if(i_req->content.setup.tmp.param_len!=SIZE_OF_SETUP_PARAM || i_req->content.setup.tmp.host_len<1)
         {
             NyLPC_cHttpdUtils_sendErrorResponse(i_connection,500);
         }else{
             //パラメータ→ROMイメージ変換
-            cfg_image.fast_boot=0xffffffff;
-            cfg_image.mac_00_01_02_03=(i_req->content.setup.param_buf[0]);
-            cfg_image.mac_04_05_xx_xx=(i_req->content.setup.param_buf[1]&0xffff0000);
-            cfg_image.ipv4_addr_net  =i_req->content.setup.param_buf[2];
-            cfg_image.ipv4_mask_net  =i_req->content.setup.param_buf[3];
-            cfg_image.ipv4_drut_net  =i_req->content.setup.param_buf[4];
-            cfg_image.ipv4_port =(NyLPC_TUInt16)(i_req->content.setup.param_buf[5]>>16);
-            cfg_image.accessmode=(i_req->content.setup.param_buf[6]);
+            i_req->content.setup.memimg.fast_boot=0xffffffff;
+//          ここの部分は受信時にデータ位置を合わせてあるのでコピー不要。
+//          cfg_image.mac_00_01_02_03=(i_req->content.setup.param_buf[0]);
+//          cfg_image.mac_04_05_xx_xx=(i_req->content.setup.param_buf[1]&0xffff0000);
+//          cfg_image.ipv4_flags     =i_req->content.setup.param_buf[2];
+//          cfg_image.ipv4_addr_net  =i_req->content.setup.param_buf[3];
+//          cfg_image.ipv4_mask_net  =i_req->content.setup.param_buf[4];
+//          cfg_image.ipv4_drut_net  =i_req->content.setup.param_buf[5];
+//          cfg_image.srv_flags =i_req->content.setup.param_buf[6];
+//          strcpy(cfg_image.hostname,i_req->content.setup.host_name);
+            i_req->content.setup.memimg.http_port =(NyLPC_TUInt16)(i_req->content.setup.tmp.param_buf[7]>>16);
+            i_req->content.setup.memimg.padding=0xffff;
             //一応確認。
-            if((cfg_image.ipv4_port==0)|| (cfg_image.accessmode & 0xFEFE0000)!=0x00000000){
+            if(i_req->content.setup.memimg.http_port==0){
                 NyLPC_cHttpdUtils_sendErrorResponse(i_connection,500);
             }else{
                 //FreeRTOSの停止
                 NyLPC_cIsr_enterCritical();
                 //Flashへの書き込み
-                ret=NyLPC_cMiMicConfiglation_updateConfigulation(&cfg_image);
+                ret=NyLPC_cMiMicConfiglation_updateConfigulation(&i_req->content.setup.memimg);
                 //FreeRTOSの復帰
                 NyLPC_cIsr_exitCritical();
                 if(!ret){
--- a/core/net/httpd/mod/NyLPC_cModMiMicSetting.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/net/httpd/mod/NyLPC_cModMiMicSetting.h	Wed Jun 19 09:33:01 2013 +0000
@@ -34,6 +34,7 @@
 
 /**
  * MiMicの動作設定CGIです。MiMicの設定値をオンチップフラッシュへ保存/読み出しします。
+ * uipServiceはNyLPC_TcNetConfig_tを継承したインスタンスで初期化してください。
  *
  * JSONAPIとして、以下のAPIを提供します。
  * ./setup.api?c=[update|get]&p=[:param:]
@@ -45,23 +46,22 @@
  *      mac0405xxxx: [:HEX32:],
  *      ip: [:HEX32:],
  *      mask: [:HEX32:],
- *      droute: [:HEX32:]
- *      port: [:HEX16:]
+ *      droute: [:HEX32:],
+ *
+ *      port: [:HEX16:],
  *      access\":%u}",
- * c=update pパラメタの内容でFlashをアップデートする。
- *      [:param:]=[:emac:][:hostaddr:][:subnetmask:][:defaultroot:][:port:]
- *      ROMパラメータ。固定長のHEX文字列である。
- *      [:emac:]=[[:HEX32:]{2}}
- *      ビックエンディアン48bit値+パディング16bit
- *      [:hostaddr:]=[:HEX32:]
- *      IPアドレス。32bit値。ビックエンディアン
- *      [:subnetmask:]=[:HEX32:]
- *      サブネットマスク。32bit値。ビックエンディアン
- *      [:defaultroot:]=[:HEX32:]
- *      defaultrootアドレス。32bit値。ビックエンディアン
- *      [:port:]=[:HEX32:]
- *      ポート番号。2桁のHEX値である。ビックエンディアン。値16bit、パディング16bit
- *
+ * c=update pパラメタ/hostの内容でFlashをアップデートする。
+ *      pパラメタは32bitの16進数文字列。
+ *      [ 0] emac_0123      ビックエンディアン48bit値+パディング16bit
+ *      [ 1] emac_45xx      :
+ *          [emac4][emac5][x][x]
+ *      [ 2] ipv4_flags     IPV4設定フラグ
+ *      [ 3] ipv4_ip        IPアドレス。32bit値。ビックエンディアン
+ *      [ 4] ipv4_mask      サブネットマスク。32bit値。ビックエンディアン
+ *      [ 5] ipv4_deoute    defaultrootアドレス。32bit値。ビックエンディアン
+ *      [ 6] service_flag
+ *      [ 7] http_param     HTTPサービスポート番号。2桁のHEX値である。ビックエンディアン。値16bit、パディング16bit
+ *          [port_h][port_l][x][x]
  */
 typedef struct NyLPC_TcModMiMicSetting NyLPC_TcModMiMicSetting_t;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/net/mdns/NyLPC_cMDnsServer.c	Wed Jun 19 09:33:01 2013 +0000
@@ -0,0 +1,717 @@
+/*********************************************************************************
+ * 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_cMDnsServer.h"
+#include "NyLPC_uipService.h"
+#include "NyLPC_http.h"
+#include "NyLPC_utils.h"
+#include <stdio.h>
+#include <string.h>
+
+
+/**
+ * mDNSのポート番号
+ */
+#define MDNS_MCAST_PORT         5353
+static const struct NyLPC_TIPv4Addr MDNS_MCAST_IPADDR=NyLPC_TIPv4Addr_pack(224,0,0,251);
+#define TIMEOUT_IN_MS       1000
+#define NyLPC_TcMDns_TTL 120
+
+
+struct NyLPC_TDnsHeader
+{
+    NyLPC_TUInt16 id;
+    NyLPC_TUInt16 flag;
+    NyLPC_TUInt16 qd;
+    NyLPC_TUInt16 an;
+    NyLPC_TUInt16 ns;
+    NyLPC_TUInt16 ar;
+}PACK_STRUCT_END;
+
+#define NyLPC_TDnsHeader_FLAG_MASK_QR     0x8000
+#define NyLPC_TDnsHeader_FLAG_MASK_OPCODE 0x7800
+#define NyLPC_TDnsHeader_FLAG_MASK_AA     0x0400
+#define NyLPC_TDnsHeader_FLAG_MASK_TC     0x0200
+#define NyLPC_TDnsHeader_FLAG_MASK_RD     0x0100
+#define NyLPC_TDnsHeader_FLAG_MASK_RA     0x0080
+#define NyLPC_TDnsHeader_FLAG_MASK_Z      0x0070
+#define NyLPC_TDnsHeader_FLAG_MASK_RECODE 0x000F
+
+struct NyLPC_TDnsQuestion
+{
+    const char* qname;
+    NyLPC_TUInt16 qtype;
+    NyLPC_TUInt16 qclass;
+};
+#define NyLPC_TDnsQuestion_QTYPR_A      1
+#define NyLPC_TDnsQuestion_QTYPR_NS     2
+#define NyLPC_TDnsQuestion_QTYPR_CNAME  5
+#define NyLPC_TDnsQuestion_QTYPR_SOA    6
+#define NyLPC_TDnsQuestion_QTYPR_PTR    12
+#define NyLPC_TDnsQuestion_QTYPR_MX     15
+#define NyLPC_TDnsQuestion_QTYPR_TXT    16
+#define NyLPC_TDnsQuestion_QTYPR_ANY    255
+#define NyLPC_TDnsQuestion_QCLASS_IN    1
+#define NyLPC_TDnsQuestion_QCLASS_CH    3
+#define NyLPC_TDnsQuestion_QCLASS_HS    4
+#define NyLPC_TDnsQuestion_QTYPR_SRV    33
+
+/**************************************************
+ * TLabelCache
+ **************************************************/
+
+struct TLabelCache
+{
+    NyLPC_TUInt16 idx;
+    const char* str;
+};
+static void TLabelCache_reset(struct TLabelCache* i_struct)
+{
+    i_struct->idx=0;
+    i_struct->str=NULL;
+}
+static NyLPC_TInt16 TLabelCache_compress(struct TLabelCache* i_struct,NyLPC_TChar* i_src)
+{
+    NyLPC_TInt16 s;
+    NyLPC_TInt16 k;
+    const NyLPC_TChar* q;
+    const NyLPC_TChar* d;
+    //初めてのインデクスは保存
+    if(i_struct->idx==0){
+        i_struct->idx=12;
+        i_struct->str=i_src;
+    }else{
+        d=i_struct->str;
+        do{
+            q=i_src;
+            do{
+                if(strcmp(q,d)==0){
+                    //一致,インデクスを計算
+                    s=(NyLPC_TInt16)(q-i_src);
+                    k=(NyLPC_TInt16)(d-i_struct->str);
+                    //新しい長さを返す
+                    *((NyLPC_TInt16*)(i_src+s))=NyLPC_HTONS(0xC000|(i_struct->idx+k));
+                    return s+2;
+                }
+                q+=*q+1;
+            }while(*q!=0);
+            d+=*d+1;
+        }while(*d!=0);
+    }
+    return (NyLPC_TInt16)(strlen(i_src)+1);
+}
+
+
+
+
+
+/**
+ * 受領可能なQuestionか確認する
+ * @return
+ * 受領可能なQuestionの数
+ *
+ */
+static NyLPC_TUInt16 getNumberOfQuestion(const void* i_packet,NyLPC_TUInt16 i_len)
+{
+    struct NyLPC_TDnsHeader* ptr=(struct NyLPC_TDnsHeader*)i_packet;
+    NyLPC_TUInt16 t;
+    if(i_len<12){
+        return NyLPC_TBool_FALSE;
+    }
+    //questrionの確認
+    //QR==0 && op==0 && tc=0
+    t=NyLPC_ntohs(ptr->flag);
+    if( ((t & NyLPC_TDnsHeader_FLAG_MASK_QR)!=0) &&
+        ((t & NyLPC_TDnsHeader_FLAG_MASK_OPCODE)!=0) &&
+        ((t & NyLPC_TDnsHeader_FLAG_MASK_TC)!=0))
+    {
+        //this is response
+        return 0;
+    }
+    return NyLPC_ntohs(ptr->qd);
+}
+
+static NyLPC_TInt16 NyLPC_TDnsQuestion_parse(const void* i_qpacket,NyLPC_TUInt16 i_len,struct NyLPC_TDnsQuestion* o_val)
+{
+    NyLPC_TUInt16 l;
+    NyLPC_TUInt16 i;
+    const char* p=(const char*)i_qpacket;
+    //QNameのパース'0終端'
+    l=i_len-4;//スキャン長はパケットサイズ-5まで
+    for(i=0;i<l;i++){
+        if(*(p+i)==0){
+            l=i+1;//NULL終端を加味した文字列長
+            o_val->qname=p;
+            p+=l;
+            o_val->qtype=NyLPC_ntohs(*(NyLPC_TUInt16*)p);
+            o_val->qclass=NyLPC_ntohs(*(NyLPC_TUInt16*)(p+sizeof(NyLPC_TUInt16)));
+            //OK
+            return l+4;
+        }
+    }
+    return 0;
+}
+
+/**
+ * .区切りラベル文字列とDNSラベル文字列を比較する。
+ * @param record
+ * .区切りのドメイン名
+ * @param question
+ * QuestionName文字列
+ */
+inline static NyLPC_TBool isEqualName(const char* record,const char* question)
+{
+    char s;
+    const char* q=question;
+    const char* m=record;
+    for(;;){
+        if(*m=='\0'){
+            //questionは最後のフラグメントが残るはず
+            return memcmp(q,"\5local\0",7)==0;
+        }
+        s=*q;
+        switch(*q)
+        {
+        case 0x00:
+            return NyLPC_TBool_FALSE;
+        case 0xc0:
+            return NyLPC_TBool_FALSE;//offset
+        default:
+            q++;
+            if(strncmp(m,q,s)!=0){
+                return NyLPC_TBool_FALSE;
+            }
+            m+=s;
+            q+=s;
+        }
+        m++;
+    }
+}
+/**
+ * DNSレコードのPRTフィールドとDNSラベル文字列を比較する。
+ */
+static NyLPC_TInt16 NyLPC_TDnsRecord_getMatchPtrIdx(const struct NyLPC_TDnsRecord* i_struct,const NyLPC_TChar* question)
+{
+    NyLPC_TInt16 i;
+    for(i=0;i<i_struct->num_of_srv;i++){
+        if(isEqualName(i_struct->srv[i].protocol,question)){
+            return i;
+        }
+    }
+    return -1;
+}
+static NyLPC_TInt16 NyLPC_TDnsRecord_getMatchSrvIdx(const struct NyLPC_TDnsRecord* i_struct,const NyLPC_TChar* question)
+{
+    NyLPC_TInt16 i;
+    NyLPC_TInt16 l=(NyLPC_TInt16)strlen(i_struct->name);
+    //Aレコードをチェック
+    if(l!=question[0] || memcmp(question+1,i_struct->name,l)!=0){
+        return -1;
+    }
+    for(i=0;i<i_struct->num_of_srv;i++){
+        if(isEqualName(i_struct->srv[i].protocol,question+l+1)){
+            return i;
+        }
+    }
+    return -1;
+}
+/**
+ * _services._dns-sd._udp.localであるか確認する。
+ */
+static NyLPC_TBool NyLPC_TDnsRecord_isServicesDnsSd(const NyLPC_TChar* question)
+{
+    return memcmp(question,"\x09_services\x07_dns-sd\x04_udp\5local\x00",30)==0;
+}
+
+
+/**
+ * '.'区切り文字列をDNS形式の[n]text[n]text\0へ変換する。
+ * @return
+ * 変換後のデータブロックの長さin byte
+ * 終端の\0の長さを含みます。
+ */
+static NyLPC_TInt16 str2label(NyLPC_TChar* buf,const NyLPC_TChar* name)
+{
+    //proto文字列の変換
+    NyLPC_TChar* lp;
+    const NyLPC_TChar* n=name;
+    NyLPC_TChar* b=buf;
+    while(*n!='\0'){
+        lp=b;
+        b++;
+        for(;strchr(".\0",*n)==NULL;){
+            *b=*n;
+            b++;
+            n++;
+        }
+        *lp=(char)(b-lp-1);
+        if(*n!='\0'){
+            n++;
+        }
+    }
+    *b='\0';
+    b++;
+    return b-buf;
+}
+
+/**
+ * ResourceHeaderのライタ
+ */
+static NyLPC_TInt16 writeResourceHeader(char* buf,NyLPC_TInt16 len,const char* i_name,NyLPC_TUInt16 i_type,NyLPC_TUInt16 i_class)
+{
+    NyLPC_TInt16 s;
+    NyLPC_TInt16 l=1+(NyLPC_TInt16)strlen(i_name)+1+5+1;
+    if(len<l+4+4){
+        return 0;
+    }
+    s=str2label(buf,i_name);
+    str2label(buf+s-1,"local");
+    (*(NyLPC_TUInt16*)(buf+l))=NyLPC_HTONS(i_type);
+    (*(NyLPC_TUInt16*)(buf+l+2))=NyLPC_HTONS(i_class);
+    (*(NyLPC_TUInt32*)(buf+l+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
+    return l+2+2+4;
+}
+
+inline static NyLPC_TInt16 writeSrvResourceHeader(char* buf,NyLPC_TInt16 len,const struct NyLPC_TDnsRecord* i_recode,int i_sid,NyLPC_TUInt16 i_type,NyLPC_TUInt16 i_class,struct TLabelCache* i_ca)
+{
+    NyLPC_TInt16 l=(NyLPC_TInt16)(1+strlen(i_recode->name)+1+strlen(i_recode->srv[i_sid].protocol)+1+5+1);
+    if(len<l+2+2+4){
+        return 0;
+    }
+    l=str2label(buf,i_recode->name)-1;
+    l+=str2label(buf+l,i_recode->srv[i_sid].protocol)-1;
+    l+=str2label(buf+l,"local");
+    l=TLabelCache_compress(i_ca,buf);//圧縮
+    (*(NyLPC_TUInt16*)(buf+l))=NyLPC_HTONS(i_type);
+    (*(NyLPC_TUInt16*)(buf+l+2))=NyLPC_HTONS(i_class);
+    (*(NyLPC_TUInt32*)(buf+l+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
+    return l+2+2+4;
+}
+
+inline static NyLPC_TUInt16 setResponseHeader(char* obuf,const struct NyLPC_TDnsHeader* i_in_dns_header,NyLPC_TUInt16 i_an_count,NyLPC_TUInt16 i_ns_count,NyLPC_TUInt16 i_ar_count)
+{
+    struct NyLPC_TDnsHeader* p=(struct NyLPC_TDnsHeader*)obuf;
+    if(i_in_dns_header!=NULL){
+        memcpy(p,i_in_dns_header,sizeof(struct NyLPC_TDnsHeader));
+        p->flag=p->flag | NyLPC_HTONS(NyLPC_TDnsHeader_FLAG_MASK_QR|NyLPC_TDnsHeader_FLAG_MASK_AA);
+        p->flag=p->flag & NyLPC_HTONS(~(NyLPC_TDnsHeader_FLAG_MASK_RECODE|NyLPC_TDnsHeader_FLAG_MASK_TC|NyLPC_TDnsHeader_FLAG_MASK_RA));
+    }else{
+        p->flag=0;
+        p->id=0;
+    }
+    p->qd=0;
+    p->an=NyLPC_HTONS(i_an_count);
+    p->ns=NyLPC_HTONS(i_ns_count);
+    p->ar=NyLPC_HTONS(i_ar_count);
+    return sizeof(struct NyLPC_TDnsHeader);
+}
+inline static NyLPC_TInt16 writeARecord(char* obuf,NyLPC_TInt16 obuflen,const NyLPC_TChar* a_rec,const struct NyLPC_TIPv4Addr* ip)
+{
+    NyLPC_TInt16 ret;
+    //AnswerはAレコードのみ
+    //A record header
+    ret=writeResourceHeader(obuf,obuflen,a_rec,NyLPC_TDnsQuestion_QTYPR_A,NyLPC_TDnsQuestion_QCLASS_IN);
+    if(ret==0 || obuflen-ret<8){
+        return 0;
+    }
+    //Aレコードを書く
+    //IPADDR
+    (*(NyLPC_TUInt16*)(obuf+ret))=NyLPC_HTONS(4);
+    (*(NyLPC_TUInt32*)(obuf+ret+2))=ip->v;
+    return ret+8;
+}
+static NyLPC_TInt16 writeSdPtrRecord(const char* i_qname,const struct NyLPC_TMDnsServiceRecord* i_srvlec,char* obuf,NyLPC_TInt16 obuflen)
+{
+    NyLPC_TInt16 l,s;
+    //Header
+    s=(NyLPC_TInt16)strlen(i_qname)+1;
+    //Headerの長さチェック
+    if(obuflen<s+2+2+4){
+        return 0;
+    }
+    //Header書込み
+    memcpy(obuf,i_qname,s);
+    (*(NyLPC_TUInt16*)(obuf+s))=NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_PTR);
+    (*(NyLPC_TUInt16*)(obuf+s+2))=NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN);
+    (*(NyLPC_TUInt32*)(obuf+s+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
+    l=s+2+2+4;
+
+    //Resourceの書込み
+    s=(NyLPC_TInt16)(1+strlen(i_srvlec->protocol)+1+5+1);//逆引き文字列の長さ(デリミタ×3+1)
+    if(obuflen<s+l+2){
+        return 0;
+    }
+    (*(NyLPC_TUInt16*)(obuf+l))=NyLPC_ntohs(s);
+    l+=2;
+    l+=str2label(obuf+l,i_srvlec->protocol)-1;
+    l+=str2label(obuf+l,"local");
+    return l;
+}
+static NyLPC_TInt16 writePtrRecord(const struct NyLPC_TDnsRecord* i_recode,NyLPC_TInt16 i_sid,char* obuf,NyLPC_TInt16 obuflen,struct TLabelCache* i_ca)
+{
+    NyLPC_TInt16 l,s;
+    NyLPC_TUInt16* rlen;
+    //Header:開始文字数(1)+プレフィクス(n)+終端(1)+local(5)+1
+    s=(NyLPC_TInt16)(1+strlen(i_recode->srv[i_sid].protocol)+1+5+1);
+    //Headerの長さチェック
+    if(obuflen<s+2+2+4){
+        return 0;
+    }
+    //Header書込み
+    s=str2label(obuf,i_recode->srv[i_sid].protocol)-1;
+    s+=str2label(obuf+s,"local");
+    s=TLabelCache_compress(i_ca,obuf);
+    (*(NyLPC_TUInt16*)(obuf+s))=NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_PTR);
+    (*(NyLPC_TUInt16*)(obuf+s+2))=NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN);
+    (*(NyLPC_TUInt32*)(obuf+s+4))=NyLPC_HTONS(NyLPC_TcMDns_TTL);
+    l=s+2+2+4;
+
+    //Resourceの書込み
+    s=1+strlen(i_recode->name)+1+strlen(i_recode->srv[i_sid].protocol)+1+5+1;//逆引き文字列の長さ(デリミタ×3+1)
+    if(obuflen<s+l+2){
+        return 0;
+    }
+    rlen=(NyLPC_TUInt16*)(obuf+l);
+    l+=2;
+    s=str2label(obuf+l,i_recode->name)-1;
+    s+=str2label(obuf+l+s,i_recode->srv[i_sid].protocol)-1;
+    s+=str2label(obuf+l+s,"local");
+    s=TLabelCache_compress(i_ca,obuf+l);//圧縮
+    (*rlen)=NyLPC_ntohs(s);
+    return l+s;
+}
+
+
+static NyLPC_TInt16 writeSRVRecord(NyLPC_TcMDnsServer_t* i_inst,NyLPC_TInt16 i_sid,char* obuf,NyLPC_TInt16 obuflen,struct TLabelCache* i_ca)
+{
+    NyLPC_TInt16 l,s;
+    NyLPC_TUInt16* rlen;
+
+    //SRV Record
+    s=writeSrvResourceHeader(obuf,obuflen,i_inst->_ref_record,i_sid,NyLPC_TDnsQuestion_QTYPR_SRV,NyLPC_TDnsQuestion_QCLASS_IN,i_ca);
+    if(s==0){
+        return 0;
+    }
+
+    l=1+strlen(i_inst->_ref_record->a)+1+5+1;//逆引き文字列の長さ(デリミタ×3+1)
+    if(obuflen-s-l<8){
+        return 0;
+    }
+    //IPADDR
+    rlen=(NyLPC_TUInt16*)(obuf+s);
+    (*(NyLPC_TUInt16*)(obuf+s+2))=NyLPC_HTONS(0);//Priority
+    (*(NyLPC_TUInt16*)(obuf+s+4))=NyLPC_HTONS(0);//Weight
+    (*(NyLPC_TUInt16*)(obuf+s+6))=NyLPC_HTONS(i_inst->_ref_record->srv[i_sid].port);//PORT
+    l=4*2+s;
+    s=str2label(obuf+l,i_inst->_ref_record->a)-1;
+    s+=str2label(obuf+l+s,"local");
+    s=TLabelCache_compress(i_ca,obuf+l);//圧縮
+    (*rlen)=NyLPC_HTONS(2+2+2+s);
+    return l+s;
+}
+static NyLPC_TInt16 writeTXTRecord(NyLPC_TcMDnsServer_t* i_inst,NyLPC_TInt16 i_sid,char* obuf,NyLPC_TInt16 obuflen,struct TLabelCache* i_ca)
+{
+    NyLPC_TInt16 ret;
+    NyLPC_TInt16 l;
+    //Answer
+    ret=writeSrvResourceHeader(obuf,obuflen,i_inst->_ref_record,i_sid,NyLPC_TDnsQuestion_QTYPR_TXT,NyLPC_TDnsQuestion_QCLASS_IN,i_ca);
+    if(ret==0){
+        return 0;
+    }
+    //name.proto.localを返す。
+    if(obuflen-ret<2){
+        return 0;
+    }
+    (*(NyLPC_TUInt16*)(obuf+ret))=NyLPC_ntohs(0);
+    //proto.name.local.
+    l=ret+2;
+    return l;
+}
+
+
+
+
+
+
+static void sendAnnounse(NyLPC_TcMDnsServer_t* i_inst)
+{
+    char* obuf;
+    NyLPC_TUInt16 obuflen;
+    NyLPC_TUInt16 l,s;
+    int i2;
+    struct TLabelCache cache;
+    for(i2=0;i2<i_inst->_ref_record->num_of_srv;i2++){
+        TLabelCache_reset(&cache);
+        //Bufferの取得
+        obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,TIMEOUT_IN_MS);
+        if(obuf==NULL){
+            return;
+        }
+        l=setResponseHeader(obuf,NULL,1,0,3);
+        s=writePtrRecord(i_inst->_ref_record,i2,obuf+l,obuflen-l,&cache);
+        if(s<=0){
+            NyLPC_OnErrorGoto(ERROR);
+        }
+        l+=s;
+        s=writeSRVRecord(i_inst,i2,obuf+l,obuflen-l,&cache);
+        if(s<=0){
+            NyLPC_OnErrorGoto(ERROR);
+        }
+        l+=s;
+        s=writeTXTRecord(i_inst,i2,obuf+l,obuflen-l,&cache);
+        if(s<=0){
+            NyLPC_OnErrorGoto(ERROR);
+        }
+        l+=s;
+        //Aレコード
+        s=writeARecord(obuf+l,obuflen-l,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr));
+        if(s<=0){
+            NyLPC_OnErrorGoto(ERROR);
+        }
+        l+=s;
+        if(!NyLPC_cUdpSocket_psend(&(i_inst->_super),&MDNS_MCAST_IPADDR,MDNS_MCAST_PORT,obuf,l)){
+            NyLPC_OnErrorGoto(ERROR);
+        }
+    }
+    return;
+ERROR:
+    NyLPC_cUdpSocket_releaseSendBuf(&(i_inst->_super),obuf);
+    return;
+}
+
+
+static void sendReply2(NyLPC_TcMDnsServer_t* i_inst,const struct NyLPC_TDnsHeader* i_dns_header,const struct NyLPC_TDnsQuestion* q)
+{
+    NyLPC_TInt16 ptr_recode;
+    NyLPC_TInt16 i2;
+    char* obuf;
+    NyLPC_TUInt16 obuflen;
+    NyLPC_TUInt16 l,s;
+    struct TLabelCache cache;
+    TLabelCache_reset(&cache);
+    //パケットヘッダの生成
+    switch(q->qtype){
+    case NyLPC_TDnsQuestion_QTYPR_SRV:
+        //SRV,A record
+        ptr_recode=NyLPC_TDnsRecord_getMatchSrvIdx(i_inst->_ref_record,q->qname);
+        if(ptr_recode<0){
+            goto DROP;
+        }
+        //Bufferの取得
+        obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
+        if(obuf==NULL){
+            goto DROP;
+        }
+        l=setResponseHeader(obuf,i_dns_header,1,0,2);
+        s=writeSRVRecord(i_inst,ptr_recode,obuf+l,obuflen-l,&cache);
+        if(s<=0){
+            NyLPC_OnErrorGoto(ERROR);
+        }
+        l+=s;
+        s=writeTXTRecord(i_inst,ptr_recode,obuf+l,obuflen-l,&cache);
+        if(s<=0){
+            NyLPC_OnErrorGoto(ERROR);
+        }
+        l+=s;
+        //Aレコード
+        s=writeARecord(obuf+l,obuflen-l,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr));
+        if(s<=0){
+            NyLPC_OnErrorGoto(ERROR);
+        }
+        l+=s;
+        break;
+    case NyLPC_TDnsQuestion_QTYPR_A:
+        //自分宛?(name.local)
+        if(!isEqualName(i_inst->_ref_record->a,q->qname)){
+            goto DROP;
+        }
+        //Bufferの取得
+        obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
+        if(obuf==NULL){
+            goto DROP;
+        }
+        //Headerのコピー
+        l=setResponseHeader(obuf,i_dns_header,1,0,0);
+        //Aレコードのみ
+        s=writeARecord(obuf+l,obuflen-l,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr));
+        if(s<=0){
+            NyLPC_OnErrorGoto(ERROR);
+        }
+        l+=s;
+        break;
+    case NyLPC_TDnsQuestion_QTYPR_PTR:
+        if(NyLPC_TDnsRecord_isServicesDnsSd(q->qname)){
+            //Bufferの取得
+            obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
+            if(obuf==NULL){
+                goto DROP;
+            }
+            l=setResponseHeader(obuf,i_dns_header,i_inst->_ref_record->num_of_srv,0,0);
+            for(i2=0;i2<i_inst->_ref_record->num_of_srv;i2++){
+                s=writeSdPtrRecord(q->qname,&(i_inst->_ref_record->srv[i2]),obuf+l,obuflen-l);
+                if(s<=0){
+                    NyLPC_OnErrorGoto(ERROR);
+                }
+                l+=s;
+            }
+        }else{
+            //自分宛?(proto.local)
+            ptr_recode=NyLPC_TDnsRecord_getMatchPtrIdx(i_inst->_ref_record,q->qname);
+            if(ptr_recode<0){
+                goto DROP;
+            }
+            //Bufferの取得
+            obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
+            if(obuf==NULL){
+                goto DROP;
+            }
+            l=setResponseHeader(obuf,i_dns_header,1,0,3);
+            s=writePtrRecord(i_inst->_ref_record,ptr_recode,obuf+l,obuflen-l,&cache);
+            if(s<=0){
+                NyLPC_OnErrorGoto(ERROR);
+            }
+            l+=s;
+            s=writeSRVRecord(i_inst,ptr_recode,obuf+l,obuflen-l,&cache);
+            if(s<=0){
+                NyLPC_OnErrorGoto(ERROR);
+            }
+            l+=s;
+            s=writeTXTRecord(i_inst,ptr_recode,obuf+l,obuflen-l,&cache);
+            if(s<=0){
+                NyLPC_OnErrorGoto(ERROR);
+            }
+            l+=s;
+            //Aレコード
+            s=writeARecord(obuf+l,obuflen-l,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr));
+            if(s<=0){
+                NyLPC_OnErrorGoto(ERROR);
+            }
+            l+=s;
+        }
+        break;
+    case NyLPC_TDnsQuestion_QTYPR_TXT:
+        //自分宛?(proto.local)
+        ptr_recode=NyLPC_TDnsRecord_getMatchSrvIdx(i_inst->_ref_record,q->qname);
+        if(ptr_recode<0){
+            goto DROP;
+        }
+        //Bufferの取得
+        obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
+        l=setResponseHeader(obuf,i_dns_header,1,0,1);
+        s=writeTXTRecord(i_inst,ptr_recode,obuf+l,obuflen-l,&cache);
+        if(s<=0){
+            NyLPC_OnErrorGoto(ERROR);
+        }
+        l+=s;
+        s=writeARecord(obuf+l,obuflen-l,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr));
+        if(s<=0){
+            NyLPC_OnErrorGoto(ERROR);
+        }
+        l+=s;
+        break;
+    default:
+        goto DROP;
+    }
+    if(!NyLPC_cUdpSocket_psend(&(i_inst->_super),&MDNS_MCAST_IPADDR,MDNS_MCAST_PORT,obuf,l)){
+        NyLPC_OnErrorGoto(ERROR);
+    }
+    return;
+ERROR:
+    NyLPC_cUdpSocket_releaseSendBuf(&(i_inst->_super),obuf);
+DROP:
+    return;
+}
+#define CTRL_FLAG_INIT           0x00
+#define CTRL_FLAG_STARTED        0x80
+#define CTRL_FLAG_STOP_REQUESTED 0x40
+#define CTRL_FLAG_PROCESS_PACKET 0x20   //パケット処理中の間1
+
+static NyLPC_TBool onPacket(NyLPC_TcUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info)
+{
+    NyLPC_TUInt16 in_len=i_info->size;
+    NyLPC_TUInt16 num_of_query;
+    const char* qptr;
+    struct NyLPC_TDnsQuestion q;
+    NyLPC_TUInt16 s;
+    NyLPC_TInt16 i;
+
+    if(i_info->peer_port!=MDNS_MCAST_PORT || !NyLPC_TIPv4Addr_isEqual(&MDNS_MCAST_IPADDR,&i_info->ip)){
+        return NyLPC_TBool_FALSE;
+    }
+
+    num_of_query=getNumberOfQuestion(i_buf,in_len);
+    if(num_of_query==0){
+        goto DROP;
+    }
+    qptr=(const char*)i_buf+sizeof(struct NyLPC_TDnsHeader);
+    in_len-=sizeof(struct NyLPC_TDnsHeader);
+    for(i=0;i<num_of_query;i++){
+        //Queryのパース
+        s=NyLPC_TDnsQuestion_parse(qptr,in_len,&q);
+        if(s==0){
+            goto DROP;
+        }
+        qptr+=s;
+        in_len-=s;
+        sendReply2((NyLPC_TcMDnsServer_t*)i_inst,(const struct NyLPC_TDnsHeader*)i_buf,&q);
+    }
+    //パケット処理終了
+    return NyLPC_TBool_FALSE;
+DROP:
+    return NyLPC_TBool_FALSE;
+}
+
+static void onPeriodic(NyLPC_TcUdpSocket_t* i_inst)
+{
+
+    if(NyLPC_cStopwatch_isExpired(&((NyLPC_TcMDnsServer_t*)i_inst)->_periodic_sw)){
+        //アナウンス
+        sendAnnounse(((NyLPC_TcMDnsServer_t*)i_inst));
+        //TTL(msec)*1000*80%
+        NyLPC_cStopwatch_startExpire((&((NyLPC_TcMDnsServer_t*)i_inst)->_periodic_sw),NyLPC_TcMDns_TTL*5000/4);
+    }
+}
+
+NyLPC_TBool NyLPC_cMDnsServer_initialize(
+    NyLPC_TcMDnsServer_t* i_inst,struct NyLPC_TDnsRecord* i_ref_record)
+{
+    NyLPC_cStopwatch_initialize(&(i_inst->_periodic_sw));
+    NyLPC_cStopwatch_startExpire(&(i_inst->_periodic_sw),1000);
+    NyLPC_cUdpSocket_initialize(&(i_inst->_super),MDNS_MCAST_PORT,NULL,0);
+    NyLPC_cUdpSocket_setOnRxHandler(&(i_inst->_super),onPacket);
+    NyLPC_cUdpSocket_setOnPerriodicHandler(&(i_inst->_super),onPeriodic);
+    NyLPC_cUdpSocket_joinMulticast(&(i_inst->_super),&MDNS_MCAST_IPADDR);
+    i_inst->_ref_record=i_ref_record;
+    return NyLPC_TBool_TRUE;
+}
+void NyLPC_cMDnsServer_finalize(
+    NyLPC_TcMDnsServer_t* i_inst)
+{
+    NyLPC_cUdpSocket_finalize(&(i_inst->_super));
+    NyLPC_cStopwatch_finalize(&(i_inst->_periodic_sw));
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/net/mdns/NyLPC_cMDnsServer.h	Wed Jun 19 09:33:01 2013 +0000
@@ -0,0 +1,106 @@
+/*********************************************************************************
+ * PROJECT: MiMic
+ * --------------------------------------------------------------------------------
+ *
+ * This file is part of MiMic
+ * Copyright (C)2011 Ryo Iizuka
+ *
+ * MiMic is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * For further information please contact.
+ *  http://nyatla.jp/
+ *  <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
+ *
+ *********************************************************************************/
+#ifndef NYLPC_CMDNSSERVER_H_
+#define NYLPC_CMDNSSERVER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "NyLPC_net.h"
+
+/**
+ * NyLPC_TDnsRecordで使用するサービスレコード
+ */
+struct NyLPC_TMDnsServiceRecord
+{
+    const char* protocol;
+    NyLPC_TUInt16 port;
+};
+/**
+ * DNSレコード
+ */
+struct NyLPC_TDnsRecord
+{
+    /** Service name*/
+    const NyLPC_TChar* name;
+    /** Host name recommended name[:emac:]*/
+    const NyLPC_TChar* a;
+    /**
+     * 配列の数
+     */
+    NyLPC_TUInt16 num_of_srv;
+    const struct NyLPC_TMDnsServiceRecord* srv;
+};
+
+
+
+/**
+ * MDNSサーバクラス
+ */
+typedef struct NyLPC_TcMDnsServer NyLPC_TcMDnsServer_t;
+
+
+
+struct NyLPC_TcMDnsServer
+{
+    /** マルチキャストのUDPソケット*/
+    NyLPC_TcUdpSocket_t _super;
+    /**周期実行タイマ*/
+    NyLPC_TcStopwatch_t _periodic_sw;
+    /** DNSレコードの参照情報*/
+    const struct NyLPC_TDnsRecord* _ref_record;
+};
+
+/**
+ * スケッチシステムの場合、この関数はsetup時に実行してください。
+ * @param i_ref_record
+ * DNSレコードの参照値。インスタンス
+ */
+NyLPC_TBool NyLPC_cMDnsServer_initialize(
+    NyLPC_TcMDnsServer_t* i_inst,struct NyLPC_TDnsRecord* i_ref_record);
+
+void NyLPC_cMDnsServer_finalize(
+    NyLPC_TcMDnsServer_t* i_inst);
+
+void NyLPC_cMDnsServer_periodicRecvProc(NyLPC_TcMDnsServer_t* i_inst);
+/**
+ * mDNSサービスを開始します。
+ * 関数はstop関数をコールするまでの間ブロックします。
+ */
+void NyLPC_cMDnsServer_start(NyLPC_TcMDnsServer_t* i_inst);
+/**
+ * mDNSサービスを停止します。
+ * 関数はサービスが停止するまでブロックします。
+ */
+void NyLPC_cMDnsServer_stop(NyLPC_TcMDnsServer_t* i_inst);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
--- a/core/os/NyLPC_cMutex.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/os/NyLPC_cMutex.h	Wed Jun 19 09:33:01 2013 +0000
@@ -71,6 +71,7 @@
 
 NyLPC_TBool NyLPC_cMutex_unlock(NyLPC_TcMutex_t* i_inst);
 
+#define NyLPC_cMutex_isLocked(i_inst) ((i_inst)->_lock_count>0)
 #define NyLPC_cMutex_finalize(i_inst)
 
 #ifdef __cplusplus
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/uip/NyLPC_cBaseSocket.h	Wed Jun 19 09:33:01 2013 +0000
@@ -0,0 +1,58 @@
+/*********************************************************************************
+ * PROJECT: MiMic
+ * --------------------------------------------------------------------------------
+ *
+ * This file is part of MiMic
+ * Copyright (C)2011 Ryo Iizuka
+ *
+ * MiMic is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * For further information please contact.
+ *  http://nyatla.jp/
+ *  <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
+ *
+ *********************************************************************************/
+#ifndef NYLPC_CBASESOCKET_H_
+#define NYLPC_CBASESOCKET_H_
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "NyLPC_stdlib.h"
+
+/**
+ * Base socket class
+ * cIPv4 classが管理するソケットオブジェクトのベースクラスです。
+ */
+typedef struct NyLPC_TcBaseSocket NyLPC_TcBaseSocket_t;
+
+#define NyLPC_TcBaseSocket_TYPEID_UDP_SOCK 1
+#define NyLPC_TcBaseSocket_TYPEID_TCP_SOCK 2
+#define NyLPC_TcBaseSocket_TYPEID_TCP_LISTENER 3
+
+struct NyLPC_TcBaseSocket
+{
+    /**タイプID 継承クラスのinitializerで設定。*/
+    NyLPC_TUInt32 _typeid;
+};
+#define NyLPC_cBaseSocket_initialize(i_inst,i_typeid) ((i_inst)->_typeid=i_typeid)
+#define NyLPC_cBaseSocket_finalize(i_inst)
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* NYLPC_CBASESOCKET_H_ */
--- a/core/uip/NyLPC_cIPv4.c	Thu May 16 16:06:46 2013 +0000
+++ b/core/uip/NyLPC_cIPv4.c	Wed Jun 19 09:33:01 2013 +0000
@@ -53,9 +53,11 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "NyLPC_stdlib.h"
+#include "NyLPC_uip.h"
 #include "NyLPC_cIPv4.h"
 #include "NyLPC_cIPv4Payload_protected.h"
 #include "NyLPC_cTcpSocket_protected.h"
+#include "NyLPC_cUdpSocket_protected.h"
 #include "NyLPC_cTcpListener_protected.h"
 #include "NyLPC_cIPv4IComp_protected.h"
 #include "NyLPC_cUipService_protected.h"
@@ -63,86 +65,192 @@
 
 
 /****************************************************
- * Listenerテーブルに関する宣言
- ***************************************************/
-
-
-
-#define cListenerTbl_initialize(i_inst,buf) NyLPC_cPtrTbl_initialize(i_inst,buf,NyLPC_cIPv4_MAX_TCP_LISTENER)
-
-/**
- * i_peer番号に一致するリスナを返します。
- */
-static NyLPC_TcTcpListener_t* cListenerTbl_getByPeerPort(NyLPC_TcPtrTbl_t* i_inst,NyLPC_TUInt16 i_peer_port)
-{
-    NyLPC_TcTcpListener_t** p=(NyLPC_TcTcpListener_t**)(i_inst->buf);
-    int i;
-    //一致するポートを検索して、acceptをコールする。
-    for(i=i_inst->size-1;i>=0;i--){
-        if(p[i]==NULL){
-            continue;
-        }
-        if(p[i]->_port!=i_peer_port){
-            continue;
-        }
-        return p[i];
-    }
-    return NULL;
-}
-
-/****************************************************
  * Socketテーブルに関する宣言
  ***************************************************/
 
-#define cSocketTbl_initialize(i_inst,buf) NyLPC_cPtrTbl_initialize(i_inst,buf,NyLPC_cIPv4_MAX_TCP_SOCKET)
-
+#define cSocketTbl_initialize(i_inst,buf) NyLPC_cPtrTbl_initialize(i_inst,buf,NyLPC_cIPv4_MAX_SOCKET)
+#define cSocketTbl_finalize(i_inst)
 
 /**
- * 条件に一致する、アクティブなソケットオブジェクトを取得します。
+ * 条件に一致する、アクティブなTCPソケットオブジェクトを取得します。
  * この関数は、ローカルIPが一致していると仮定して検索をします。
  * @param i_rip
  * リモートIPアドレスを指定します。
  */
-static NyLPC_TcTcpSocket_t* cSocketTbl_getMatchSocket(
+static NyLPC_TcTcpSocket_t* cSocketTbl_getMatchTcpSocket(
     NyLPC_TcPtrTbl_t* i_inst,
     NyLPC_TUInt16 i_lport,
     struct NyLPC_TIPv4Addr i_rip,
     NyLPC_TUInt16 i_rport)
 {
-    NyLPC_TcTcpSocket_t** p=(NyLPC_TcTcpSocket_t**)(i_inst->buf);
+    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 || p[i]->_typeid!=NyLPC_TcBaseSocket_TYPEID_TCP_SOCK){
+            continue;
+        }
+        tp=(NyLPC_TcTcpSocket_t*)p[i];
+        if(tp->tcpstateflags==UIP_CLOSED){
+            continue;
+        }
+        //パラメータの一致チェック
+        if(i_lport!=tp->uip_connr.lport || i_rport!= tp->uip_connr.rport || i_rip.v!=tp->uip_connr.ripaddr.v)
+        {
+            continue;
+        }
+        return tp;
+    }
+    return NULL;
+}
+static NyLPC_TcUdpSocket_t* cSocketTbl_getMatchUdpSocket(
+    NyLPC_TcPtrTbl_t* i_inst,
+    NyLPC_TUInt16 i_lport)
+{
+    NyLPC_TcBaseSocket_t** p=(NyLPC_TcBaseSocket_t**)(i_inst->buf);
+    NyLPC_TcUdpSocket_t* tp;
+    int i;
+    //一致するポートを検索
+    for(i=i_inst->size-1;i>=0;i--){
+        if(p[i]==NULL || p[i]->_typeid!=NyLPC_TcBaseSocket_TYPEID_UDP_SOCK){
+            continue;
+        }
+        tp=(NyLPC_TcUdpSocket_t*)p[i];
+        //パラメータの一致チェック
+        if(i_lport!=tp->uip_udp_conn.lport)
+        {
+            continue;
+        }
+        return tp;
+    }
+    return NULL;
+}
+static NyLPC_TcUdpSocket_t* cSocketTbl_getMatchMulticastUdpSocket(
+    NyLPC_TcPtrTbl_t* i_inst,
+    struct NyLPC_TIPv4Addr* i_mcast_ip,
+    NyLPC_TUInt16 i_lport)
+{
+    NyLPC_TcBaseSocket_t** p=(NyLPC_TcBaseSocket_t**)(i_inst->buf);
+    NyLPC_TcUdpSocket_t* tp;
+    int i;
+    //一致するポートを検索
+    for(i=i_inst->size-1;i>=0;i--){
+        if(p[i]==NULL || p[i]->_typeid!=NyLPC_TcBaseSocket_TYPEID_UDP_SOCK){
+            continue;
+        }
+        tp=(NyLPC_TcUdpSocket_t*)p[i];
+        //パラメータの一致チェック
+        if(i_lport!=tp->uip_udp_conn.lport || NyLPC_TIPv4Addr_isEqual(i_mcast_ip,&(tp->uip_udp_conn.lipaddr)))
+        {
+            continue;
+        }
+        return tp;
+    }
+    return NULL;
+}
+
+/**
+ * i_peer番号に一致するリスナを返します。
+ */
+static NyLPC_TcTcpListener_t* cSocketTbl_getListenerByPeerPort(NyLPC_TcPtrTbl_t* i_inst,NyLPC_TUInt16 i_peer_port)
+{
+    NyLPC_TcBaseSocket_t** p=(NyLPC_TcBaseSocket_t**)(i_inst->buf);
+    NyLPC_TcTcpListener_t* lp;
     int i;
     //一致するポートを検索して、acceptをコールする。
     for(i=i_inst->size-1;i>=0;i--){
-        if(p[i]==NULL){
-            continue;
-        }
-        if(p[i]->tcpstateflags==UIP_CLOSED){
+        if(p[i]==NULL || p[i]->_typeid!=NyLPC_TcBaseSocket_TYPEID_TCP_LISTENER){
             continue;
         }
-        //パラメータの一致チェック
-        if(i_lport!=p[i]->uip_connr.lport || i_rport!= p[i]->uip_connr.rport || i_rip.v!=p[i]->uip_connr.ripaddr.v)
-        {
+        lp=(NyLPC_TcTcpListener_t*)p[i];
+        if(lp->_port!=i_peer_port){
             continue;
         }
-        return p[i];
+        return lp;
     }
     return NULL;
 }
+
 /**
  * テーブルにある有効なソケットのperiodicをすべて呼び出します。
  */
 static void cSocketTbl_callPeriodic(
     NyLPC_TcPtrTbl_t* i_inst)
 {
-    NyLPC_TcTcpSocket_t** p=(NyLPC_TcTcpSocket_t**)(i_inst->buf);
+    NyLPC_TcBaseSocket_t** p=(NyLPC_TcBaseSocket_t**)(i_inst->buf);
+    int i;
+    for(i=i_inst->size-1;i>=0;i--){
+        if(p[i]==NULL){
+            continue;
+        }
+        switch(p[i]->_typeid){
+        case NyLPC_TcBaseSocket_TYPEID_TCP_SOCK:
+            //downcast!
+            NyLPC_cTcpSocket_periodic((NyLPC_TcTcpSocket_t*)(p[i]));
+            break;
+        case NyLPC_TcBaseSocket_TYPEID_UDP_SOCK:
+            NyLPC_cUdpSocket_periodic((NyLPC_TcUdpSocket_t*)(p[i]));
+            break;
+        default:
+            continue;
+        }
+    }
+}
+
+/**
+ * テーブルにある有効なソケットのstartを全て呼び出します。
+ */
+static void cSocketTbl_callSocketStart(
+    NyLPC_TcPtrTbl_t* i_inst,
+    const NyLPC_TcIPv4Config_t* i_cfg)
+{
+    NyLPC_TcBaseSocket_t** p=(NyLPC_TcBaseSocket_t**)(i_inst->buf);
     int i;
     for(i=i_inst->size-1;i>=0;i--){
         if(p[i]==NULL){
             continue;
         }
-        NyLPC_cTcpSocket_periodic(p[i]);
+        switch(p[i]->_typeid){
+        case NyLPC_TcBaseSocket_TYPEID_UDP_SOCK:
+            NyLPC_cUdpSocket_startService((NyLPC_TcUdpSocket_t*)(p[i]),i_cfg);
+            break;
+        case NyLPC_TcBaseSocket_TYPEID_TCP_SOCK:
+            NyLPC_cTcpSocket_startService((NyLPC_TcTcpSocket_t*)(p[i]),i_cfg);
+            break;
+        default:
+            continue;
+        }
     }
 }
+/**
+ * テーブルにある有効なソケットのstartを全て呼び出します。
+ */
+static void cSocketTbl_callSocketStop(
+    NyLPC_TcPtrTbl_t* i_inst)
+{
+    NyLPC_TcBaseSocket_t** p=(NyLPC_TcBaseSocket_t**)(i_inst->buf);
+    int i;
+    for(i=i_inst->size-1;i>=0;i--){
+        if(p[i]==NULL){
+            continue;
+        }
+        switch(p[i]->_typeid){
+        case NyLPC_TcBaseSocket_TYPEID_UDP_SOCK:
+            NyLPC_cUdpSocket_stopService((NyLPC_TcUdpSocket_t*)(p[i]));
+            break;
+        case NyLPC_TcBaseSocket_TYPEID_TCP_SOCK:
+            NyLPC_cTcpSocket_stopService((NyLPC_TcTcpSocket_t*)(p[i]));
+            break;
+        default:
+            continue;
+        }
+    }
+}
+
+/****************************************************
+ * NyLPC_cIPv4
+ ***************************************************/
 
 /**
  * Static関数
@@ -151,10 +259,9 @@
 static NyLPC_TBool tcp_rx(
     NyLPC_TcIPv4_t* i_inst,
     NyLPC_TcIPv4Payload_t* i_ipp);
-
-/****************************************************
- * NyLPC_cIPv4
- ***************************************************/
+static NyLPC_TBool udp_rx(
+    NyLPC_TcIPv4_t* i_inst,
+    NyLPC_TcIPv4Payload_t* i_ipp);
 
 /**
  * See Header file.
@@ -163,9 +270,10 @@
     NyLPC_TcIPv4_t* i_inst)
 {
     //内部テーブルの初期化
-    cListenerTbl_initialize(&(i_inst->_listener_tbl),(void**)(i_inst->_listener_array_buf));
     cSocketTbl_initialize(&(i_inst->_socket_tbl),(void**)(i_inst->_socket_array_buf));
     //instanceの初期化
+    NyLPC_cMutex_initialize(&(i_inst->_sock_mutex));
+    NyLPC_cMutex_initialize(&(i_inst->_listener_mutex));
     i_inst->_ref_config=NULL;
     return;
 }
@@ -176,6 +284,9 @@
 void NyLPC_cIPv4_finalize(
     NyLPC_TcIPv4_t* i_inst)
 {
+    cSocketTbl_finalize(&(i_inst->_socket_tbl));
+    NyLPC_cMutex_finalize(&(i_inst->_sock_mutex));
+    NyLPC_cMutex_finalize(&(i_inst->_listener_mutex));
     return;
 }
 
@@ -189,6 +300,8 @@
     NyLPC_ArgAssert(i_ref_configlation!=NULL);
     //リストの初期化、ここでするべき?しないべき?
     i_inst->_ref_config=i_ref_configlation;
+    //configulationのアップデートを登録されてるソケットに通知
+    cSocketTbl_callSocketStart(&(i_inst->_socket_tbl),i_ref_configlation);
     return;
 }
 
@@ -198,8 +311,7 @@
 void NyLPC_cIPv4_stop(
     NyLPC_TcIPv4_t* i_inst)
 {
-    //実行タイミングが未設計。当分は使わないこと。
-    //新規ソケットの生成を打ち切って、すべてのソケットが停止するのを待つ?
+    cSocketTbl_callSocketStop(&(i_inst->_socket_tbl));
     i_inst->_ref_config=NULL;
     return;
 }
@@ -209,7 +321,7 @@
  */
 NyLPC_TBool NyLPC_cIPv4_addSocket(
     NyLPC_TcIPv4_t* i_inst,
-    NyLPC_TcTcpSocket_t* i_sock)
+    NyLPC_TcBaseSocket_t* i_sock)
 {
     //当面、stop中しか成功しない。
     NyLPC_Assert(!NyLPC_cUipService_isRun());
@@ -221,7 +333,7 @@
  */
 NyLPC_TBool NyLPC_cIPv4_removeSocket(
     NyLPC_TcIPv4_t* i_inst,
-    NyLPC_TcTcpSocket_t* i_sock)
+    NyLPC_TcBaseSocket_t* i_sock)
 {
     NyLPC_TInt16 i;
     NyLPC_Assert(!NyLPC_cUipService_isRun());
@@ -233,38 +345,6 @@
     return NyLPC_TBool_FALSE;
 }
 
-/**
- * See header file.
- */
-NyLPC_TBool NyLPC_cIPv4_addListener(
-    NyLPC_TcIPv4_t* i_inst,
-    NyLPC_TcTcpListener_t* i_listener)
-{
-    //当面、stop中しか成功しない。
-    NyLPC_Assert(!NyLPC_cUipService_isRun());
-    return NyLPC_cPtrTbl_add(&(i_inst->_listener_tbl),i_listener)>=0;
-}
-
-/**
- * See header file.
- */
-NyLPC_TBool NyLPC_cIPv4_removeListener(
-    NyLPC_TcIPv4_t* i_inst,
-    NyLPC_TcTcpListener_t* i_listener)
-{
-    NyLPC_TInt16 i;
-    NyLPC_Assert(!NyLPC_cUipService_isRun());
-    i=NyLPC_cPtrTbl_getIndex(&(i_inst->_listener_tbl),i_listener);
-    if(i>=0){
-        NyLPC_cPtrTbl_remove(&(i_inst->_listener_tbl),i);
-        return NyLPC_TBool_TRUE;
-    }
-    return NyLPC_TBool_FALSE;
-}
-
-
-
-
 
 #define IS_START(i_inst) ((i_inst)->_ref_config!=NULL)
 
@@ -306,8 +386,9 @@
         //TCP受信処理
         return tcp_rx(i_inst,&ipv4);
     case UIP_PROTO_UDP:
-        //  //uip_process_UDP();//実装したら解除いして
-        NyLPC_OnErrorGoto(ERROR_DROP);
+        //UDP処理
+        udp_rx(i_inst,&ipv4);//r
+        return NyLPC_TBool_FALSE;
     case UIP_PROTO_ICMP:
         if(!NyLPC_cIPv4IComp_rx(&(inst->_icomp),&ipv4)){
             NyLPC_OnErrorGoto(ERROR_DROP);
@@ -346,8 +427,8 @@
         //受信エラーのあるパケットはドロップ
         goto DROP;
     }
-    //アクティブなソケットを探す。
-    sock=cSocketTbl_getMatchSocket(&(i_inst->_socket_tbl),i_ipp->payload.tcp->destport,i_ipp->header->srcipaddr,i_ipp->payload.tcp->srcport);
+    //アクティブなTCPソケットを探す。
+    sock=cSocketTbl_getMatchTcpSocket(&(i_inst->_socket_tbl),i_ipp->payload.tcp->destport,i_ipp->header->srcipaddr,i_ipp->payload.tcp->srcport);
     if(sock!=NULL)
     {
         //既存の接続を処理
@@ -361,20 +442,18 @@
             return NyLPC_TBool_TRUE;
         }
         //このポートに対応したListenerを得る。
-        listener=cListenerTbl_getByPeerPort(&(i_inst->_listener_tbl),i_ipp->payload.tcp->destport);
+        listener=cSocketTbl_getListenerByPeerPort(&(i_inst->_socket_tbl),i_ipp->payload.tcp->destport);
         if(listener==NULL){
             //Listen対象ではない。RST送信
             NyLPC_cIPv4Payload_setTcpReverseRstAck(i_ipp);
             return NyLPC_TBool_TRUE;
         }
         //リスナにソケットのバインドを依頼する。
-        sock=NyLPC_cTcpListener_makeSynRcvdSocket(listener,i_inst->_ref_config,i_ipp);
+        sock=NyLPC_cTcpListener_makeSynRcvdSocket(listener,i_ipp);
         if(sock==NULL){
             //Listen失敗。ドロップ
             goto DROP;
         }
-//      //Socketの割当に成功。管理リストへ追加
-//      NyLPC_AbortIfNot(NyLPC_cPtrTbl_add(&(i_inst->_socket_tbl),sock)>=0);
         return NyLPC_TBool_FALSE;//LISTEN成功。送信データなし
     }
     return NyLPC_TBool_TRUE;
@@ -384,6 +463,53 @@
 
 
 
+static NyLPC_TBool udp_rx(
+    NyLPC_TcIPv4_t* i_inst,
+    NyLPC_TcIPv4Payload_t* i_ipp)
+{
+    NyLPC_TcUdpSocket_t* sock;
+    //Multicastか調べる
+    if(NyLPC_TIPv4Addr_isEqualWithMask(&(i_ipp->header->destipaddr),&NyLPC_TIPv4Addr_MULTICAST,&NyLPC_TIPv4Addr_MULTICAST_MASK)){
+        //Multicastパケット
+
+        //チェックサムの計算
+        if((NyLPC_TIPv4Header_makeTcpChecksum(i_ipp->header) != 0xffff))
+        {
+            //受信エラーのあるパケットはドロップ
+            goto DROP;
+        }
+        //マルチキャストに参加している&&portの一致するソケットを検索
+        sock=cSocketTbl_getMatchMulticastUdpSocket(&(i_inst->_socket_tbl),&(i_ipp->header->destipaddr),i_ipp->payload.udp->destport);
+        if(sock==NULL)
+        {
+            goto DROP;
+        }
+    }else{
+        //ユニキャストパケット
+
+        //自分自身のIPに対する呼び出し?
+        if(!NyLPC_TIPv4Addr_isEqual(&(i_ipp->header->destipaddr),&(i_inst->_ref_config->ip_addr)))
+        {
+            //自分以外のパケットはドロップ
+            goto DROP;
+        }
+        //チェックサムの計算
+        if((NyLPC_TIPv4Header_makeTcpChecksum(i_ipp->header) != 0xffff))
+        {
+            //受信エラーのあるパケットはドロップ
+            goto DROP;
+        }
+        //ポートの一致するUDPソケットを探す。
+        sock=cSocketTbl_getMatchUdpSocket(&(i_inst->_socket_tbl),i_ipp->payload.udp->destport);
+        if(sock==NULL)
+        {
+            goto DROP;
+        }
+    }
+    //既存の接続を処理
+    return NyLPC_cUdpSocket_parseRx(sock,i_ipp);
+DROP:
+    return NyLPC_TBool_FALSE;
+}
 
 
-
--- a/core/uip/NyLPC_cIPv4.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/uip/NyLPC_cIPv4.h	Wed Jun 19 09:33:01 2013 +0000
@@ -71,12 +71,6 @@
 #endif /* __cplusplus */
 
 
-
-
-
-
-
-
 /**
  * クラス型を定義します。
  * NyLPC_cIPv4クラスは、NyLPC_cUipServiceクラスの一部として働きます。
@@ -95,17 +89,18 @@
  *
  **********************************************************************/
 
-/**
- * 環境定数です。NyLPC_TcTcpListenerインスタンスリストの数を設定します。
- * この値は、NyLPC_cTcpListenerクラスの最大生成数になります。
- */
-#define NyLPC_cIPv4_MAX_TCP_LISTENER 10
+
+///**
+// * 環境定数です。NyLPC_TcTcpListenerインスタンスリストの数を設定します。
+// * この値は、NyLPC_cTcpListenerクラスの最大生成数になります。
+// */
+//#define NyLPC_cIPv4_MAX_TCP_LISTENER 10
 
 /**
- * TCPSocketの最大生成数
- * この値は、NyLPC_cTcpSocketクラスの最大生成数になります。
+ * Socketの最大生成数
+ * この値は、NyLPC_cTcpSocketクラス,NyLPC_cTcpListener,NyLPC_cUdpの最大生成数になります。
  */
-#define NyLPC_cIPv4_MAX_TCP_SOCKET 10
+#define NyLPC_cIPv4_MAX_SOCKET 10
 
 
 
@@ -116,15 +111,14 @@
 {
     /** 参照しているIPスタックの環境値です。この値は、start関数が設定します。*/
     const NyLPC_TcIPv4Config_t* _ref_config;
-    /** NyLPC_cTcpListernerを管理するポインタリストです。*/
-    NyLPC_TcPtrTbl_t _listener_tbl;
+    /** ソケットリソースの保護用。コールバック関数から呼び出されるソケット内部のリソース保護に使用する共通MUTEX*/
+    NyLPC_TcMutex_t _sock_mutex;
+    /** リスナリソースの保護用。コールバック関数から呼び出されるソケット内部のリソース保護に使用する共通MUTEX*/
+    NyLPC_TcMutex_t _listener_mutex;
     /** NyLPC_cTcpSocketを管理するポインタリストです。*/
     NyLPC_TcPtrTbl_t _socket_tbl;
-    /** _listener_tblが使用するメモリ領域です。*/
-    NyLPC_TcTcpListener_t* _listener_array_buf[NyLPC_cIPv4_MAX_TCP_LISTENER];
     /** _socket_tblが使用するメモリ領域です。*/
-    NyLPC_TcTcpSocket_t* _socket_array_buf[NyLPC_cIPv4_MAX_TCP_SOCKET];
-
+    NyLPC_TcBaseSocket_t* _socket_array_buf[NyLPC_cIPv4_MAX_SOCKET];
 };
 
 /**
@@ -168,8 +162,7 @@
     NyLPC_TcIPv4_t* i_inst);
 
 /**
- * この関数は、NyLPC_cTcpSocketオブジェクトを管理リストへ追加します。
- * NyLPC_cTcpSocketが使います。
+ * この関数は、NyLPC_TcBaseSocketオブジェクトを管理リストへ追加します。
  * @param i_inst
  * 操作するインスタンス。
  * @param i_sock
@@ -179,11 +172,11 @@
  */
 NyLPC_TBool NyLPC_cIPv4_addSocket(
     NyLPC_TcIPv4_t* i_inst,
-    NyLPC_TcTcpSocket_t* i_sock);
+    NyLPC_TcBaseSocket_t* i_sock);
 
 /**
  * この関数は、NyLPC_cTcpSocketオブジェクトを管理リストから除外します。
- * NyLPC_cTcpSocketが使います。
+ * NyLPC_TcBaseSocketが使います。
  * @param i_inst
  * 操作するインスタンス。
  * @param i_sock
@@ -193,41 +186,15 @@
  */
 NyLPC_TBool NyLPC_cIPv4_removeSocket(
     NyLPC_TcIPv4_t* i_inst,
-    NyLPC_TcTcpSocket_t* i_sock);
+    NyLPC_TcBaseSocket_t* i_sock);
 
-/**
- * この関数は、NyLPC_cTcpListenerオブジェクトを管理リストへ追加します。
- * NyLPC_cTcpListenerが使います。
- * @param i_inst
- * 操作するインスタンス。
- * @param i_sock
- * 追加するインスタンスのポインタ
- * @return
- * 追加が成功するとTRUEを返します。
- */
-NyLPC_TBool NyLPC_cIPv4_addListener(
-    NyLPC_TcIPv4_t* i_inst,
-    NyLPC_TcTcpListener_t* i_listener);
-
-/**
- * この関数は、NyLPC_cTcpListenerオブジェクトを管理リストから除外します。
- * NyLPC_cTcpListenerが使います。
- * @param i_inst
- * 操作するインスタンス。
- * @param i_sock
- * 削除するインスタンスのポインタ
- * @return
- * 削除が成功するとTRUEを返します。
- */
-NyLPC_TBool NyLPC_cIPv4_removeListener(
-    NyLPC_TcIPv4_t* i_inst,
-    NyLPC_TcTcpListener_t* i_listener);
 
 /**
  * この関数は、RxIPパケットを処理して、管理下のインスタンスに処理を依頼します。
  * 現在の関数は、i_rxに最大64バイトの応答パケットのイメージを格納することがあります。
  * 応答パケットは、RXに対するACKパケットです。
  * 格納の有無は戻り値を確認することで判ります。
+ * この関数はstart-stopの間だけコールすることが出来ます。start,stopと非同期に実行しないでください。
  * @param i_inst
  * 操作するインスタンスです。
  * @param i_rx
@@ -248,6 +215,16 @@
  */
 void NyLPC_cIPv4_periodec(NyLPC_TcIPv4_t* i_inst);
 
+/**
+ * ソケットリソースとコールバックの排他処理に使う共通MUTEXを返します。
+ * このMutexはソケット同士の干渉が起こらない処理にだけ使ってください。
+ */
+#define NyLPC_cIPv4_getSockMutex(i_inst) (&((i_inst)->_sock_mutex))
+/**
+ * リスナーリソースとコールバックの排他処理に使う共通MUTEXを返します。
+ */
+#define NyLPC_cIPv4_getListenerMutex(i_inst) (&((i_inst)->_listener_mutex))
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
--- a/core/uip/NyLPC_cIPv4Arp.c	Thu May 16 16:06:46 2013 +0000
+++ b/core/uip/NyLPC_cIPv4Arp.c	Wed Jun 19 09:33:01 2013 +0000
@@ -234,22 +234,11 @@
 const struct NyLPC_TEthAddr* NyLPC_cIPv4Arp_IPv4toEthAddr(NyLPC_TcIPv4Arp_t* i_inst,const struct NyLPC_TIPv4Addr i_ip_addr)
 {
     int i;
-    struct NyLPC_TIPv4Addr ip;
     struct NyLPC_TArpTableItem *tabptr;
-    //ブロードキャストならそのまま
-    if (NyLPC_TIPv4Addr_isEqual(&i_ip_addr,&NyLPC_TIPv4Addr_BROADCAST)) {
-        return &NyLPC_TEthAddr_BROADCAST;
-    }
-    //LocalIPでなければ、デフォルトゲートウェイのアドレスに設定。
-    if (!NyLPC_cIPv4Config_isLocalIP(i_inst->_cfg, &i_ip_addr)) {
-        ip = i_inst->_cfg->dr_addr;
-    } else {
-        ip = i_ip_addr;
-    }
     //ARPテーブルから検索
     for (i = NyLPC_TcIPv4Arp_ARPTAB_SIZE - 1; i >= 0; i--) {
         tabptr = &i_inst->arp_table[i];
-        if (NyLPC_TIPv4Addr_isEqual(&ip,&(tabptr->ipaddr))) {
+        if (NyLPC_TIPv4Addr_isEqual(&i_ip_addr,&(tabptr->ipaddr))) {
             return &tabptr->ethaddr;
         }
     }
--- a/core/uip/NyLPC_cIPv4Config.c	Thu May 16 16:06:46 2013 +0000
+++ b/core/uip/NyLPC_cIPv4Config.c	Wed Jun 19 09:33:01 2013 +0000
@@ -41,7 +41,10 @@
     i_inst->default_mss=i_ether_frame_len-(UIP_ETHERHEADER_LEN+UIP_TCPH_LEN + UIP_IPH_LEN);
     return;
 }
-
+void NyLPC_cIPv4Config_initialzeCopy(NyLPC_TcIPv4Config_t* i_inst,const NyLPC_TcIPv4Config_t* i_src)
+{
+    memcpy(i_inst,i_src,sizeof(NyLPC_TcIPv4Config_t));
+}
 /**
  * See header file.
  */
--- a/core/uip/NyLPC_cIPv4Config.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/uip/NyLPC_cIPv4Config.h	Wed Jun 19 09:33:01 2013 +0000
@@ -82,6 +82,11 @@
  */
 void NyLPC_cIPv4Config_initialzeForEthernet(NyLPC_TcIPv4Config_t* i_inst,const struct NyLPC_TEthAddr* i_ether_addr,NyLPC_TUInt16 i_ether_frame_len);
 
+/**
+ * コピーコンストラクタ
+ */
+void NyLPC_cIPv4Config_initialzeCopy(NyLPC_TcIPv4Config_t* i_inst,const NyLPC_TcIPv4Config_t* i_src);
+
 
 /**
  * デストラクタです。インスタンスを破棄して、確保している動的リソースを元に戻します。
--- a/core/uip/NyLPC_cIPv4Payload.c	Thu May 16 16:06:46 2013 +0000
+++ b/core/uip/NyLPC_cIPv4Payload.c	Wed Jun 19 09:33:01 2013 +0000
@@ -104,7 +104,17 @@
     i_struct->urgp[0]  = i_struct->urgp[1] = 0;
     i_struct->tcpchksum= 0;
 }
-
+/**
+ * UDPヘッダに値をセットする。checksumは0初期化する。
+ */
+static void setUdpTxHeader(struct NyLPC_TUdpHeader* i_struct,const struct uip_udp_conn* i_conn,NyLPC_TUInt16 i_dest_port)
+{
+    //sorce & destination port
+    i_struct->srcport  = i_conn->lport;
+    i_struct->destport = i_dest_port;
+    //uip_func_tcp_send_noconn(BUF);
+    i_struct->udpchksum= 0;
+}
 
 
 /*********************************************************************************
@@ -149,9 +159,11 @@
     return NyLPC_TBool_FALSE;
 }
 
-/**
+/*
  * TcpIpのRxバッファをセットします。
+ * @todo いらない?
  */
+/*
 void* NyLPC_cIPv4Payload_setTcpRxBuf(NyLPC_TcIPv4Payload_t* i_inst,void* i_buf,NyLPC_TUInt16 i_flagment_size)
 {
     if(!NyLPC_cIPv4Payload_setRxBuf(i_inst,i_buf,i_flagment_size)){
@@ -160,6 +172,7 @@
     i_inst->header=(struct NyLPC_TIPv4Header*)i_buf;
     return i_inst->payload.rawbuf+(i_inst->payload.tcp->tcpoffset>>4)*4;
 }
+*/
 
 /**
  * セット済みのバッファを、TCPの送信ペイロードへ初期化します。
@@ -327,3 +340,36 @@
     }*/
 }
 
+///////////////UDP//////////////
+
+/**
+ * UDPの送信バッファを初期化します。
+ */
+void* NyLPC_cIPv4Payload_initUdpTx(NyLPC_TcIPv4Payload_t* i_inst,NyLPC_TUInt8 i_iph_word,NyLPC_TUInt16 i_tcp_payload_size)
+{
+    i_inst->header->vhl=0x40|(0x0f&i_iph_word);
+    i_inst->payload.rawbuf=((NyLPC_TUInt8*)(i_inst->header))+i_iph_word*4;
+    i_inst->header->len16=NyLPC_htons(i_tcp_payload_size+(i_iph_word*4+8));
+    i_inst->payload.udp->udplen=NyLPC_htons(i_tcp_payload_size+(8));
+    return i_inst->payload.rawbuf+8;
+}
+
+/**
+ * コネクション情報から、UDPのコントロールヘッダをセットします。
+ */
+void NyLPC_cIPv4Payload_setUdpTxHeaderByConnection(NyLPC_TcIPv4Payload_t* i_inst,const struct uip_udp_conn* i_conn,const struct NyLPC_TIPv4Addr* i_dest_ip,NyLPC_TUInt16 i_dest_port)
+{
+    //IPv4のTxヘッダを書き込む。
+    i_inst->header->destipaddr=*i_dest_ip;
+    i_inst->header->srcipaddr =i_conn->lipaddr;
+    writeTxIpHeader(i_inst->header,UIP_PROTO_UDP);
+    //UDPのTxヘッダを書き込む
+    setUdpTxHeader(i_inst->payload.udp,i_conn,NyLPC_htons(i_dest_port));
+    return;
+}
+void NyLPC_cIPv4Payload_closeUdpTxPacket(
+    NyLPC_TcIPv4Payload_t* i_inst)
+{
+    i_inst->payload.udp->udpchksum=~(NyLPC_TIPv4Header_makeTcpChecksum(i_inst->header));
+    i_inst->header->ipchksum = ~(NyLPC_TIPv4Header_makeIpChecksum(i_inst->header));
+}
--- a/core/uip/NyLPC_cIPv4Payload.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/uip/NyLPC_cIPv4Payload.h	Wed Jun 19 09:33:01 2013 +0000
@@ -77,6 +77,7 @@
         NyLPC_TUInt8* rawbuf;
         struct NyLPC_TIcmpHeader* icmp;
         struct NyLPC_TTcpHeader* tcp;
+        struct NyLPC_TUdpHeader* udp;
     }payload;
     NyLPC_TUInt16 buf_len;
 };
--- a/core/uip/NyLPC_cIPv4Payload_protected.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/uip/NyLPC_cIPv4Payload_protected.h	Wed Jun 19 09:33:01 2013 +0000
@@ -58,6 +58,7 @@
 #include "NyLPC_cIPv4Payload.h"
 #include "NyLPC_cIPv4.h"
 #include "NyLPC_cTcpSocket.h"
+#include "NyLPC_cUdpSocket.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -114,6 +115,20 @@
     const NyLPC_TcIPv4Payload_t* i_inst,
     NyLPC_TcIPv4Payload_t* o_inst);
 
+
+
+/**
+ * UDPの送信バッファを初期化します。
+ */
+void* NyLPC_cIPv4Payload_initUdpTx(NyLPC_TcIPv4Payload_t* i_inst,NyLPC_TUInt8 i_iph_word,NyLPC_TUInt16 i_tcp_payload_size);
+/**
+ * UDPの送信情報を設定します。
+ */
+void NyLPC_cIPv4Payload_setUdpTxHeaderByConnection(NyLPC_TcIPv4Payload_t* i_inst,const struct uip_udp_conn* i_conn,const struct NyLPC_TIPv4Addr* i_dest_ip,NyLPC_TUInt16 i_dest_port);
+
+void NyLPC_cIPv4Payload_closeUdpTxPacket(
+    NyLPC_TcIPv4Payload_t* i_inst);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
--- a/core/uip/NyLPC_cTcpListener.c	Thu May 16 16:06:46 2013 +0000
+++ b/core/uip/NyLPC_cTcpListener.c	Wed Jun 19 09:33:01 2013 +0000
@@ -30,20 +30,27 @@
 #include "NyLPC_stdlib.h"
 
 
+#define lockResource(i_inst) NyLPC_cMutex_lock(((i_inst)->_mutex))
+#define unlockResource(i_inst) NyLPC_cMutex_unlock(((i_inst)->_mutex))
+
+
 /**
  * uipサービスが稼働中にのみ機能します。
  */
 NyLPC_TBool NyLPC_cTcpListener_initialize(NyLPC_TcTcpListener_t* i_inst,NyLPC_TUInt16 i_port)
 {
     NyLPC_TcUipService_t* srv=_NyLPC_TcUipService_inst;
+    NyLPC_cBaseSocket_initialize(&(i_inst->_super),NyLPC_TcBaseSocket_TYPEID_TCP_LISTENER);
+
     //uipサービスは初期化済であること。
     NyLPC_Assert(NyLPC_TcUipService_isInitService());
     //初期化
-    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);
     i_inst->_ref_sock=NULL;
     //管理リストへ登録。
-    return NyLPC_cIPv4_addListener(&(srv->_tcpv4),i_inst);
+    return NyLPC_cIPv4_addSocket(&(srv->_tcpv4),&(i_inst->_super));
 }
 
 void NyLPC_cTcpListener_finaize(NyLPC_TcTcpListener_t* i_inst)
@@ -51,10 +58,11 @@
     NyLPC_TcUipService_t* srv=_NyLPC_TcUipService_inst;
     NyLPC_Assert(NyLPC_TcUipService_isInitService());
     //uipサービスは初期化済であること。
-    if(!NyLPC_cIPv4_removeListener(&(srv->_tcpv4),i_inst)){
+    if(!NyLPC_cIPv4_removeSocket(&(srv->_tcpv4),&(i_inst->_super))){
         //削除失敗、それは死を意味する。
         NyLPC_Abort();
     }
+    NyLPC_cBaseSocket_finalize(&(i_inst->_super));
     return;
 }
 
@@ -70,11 +78,11 @@
         return NyLPC_TBool_FALSE;
     }
     //Listenerのリソースロック
-    NyLPC_cMutex_lock(&(i_inst->_mutex));
+    lockResource(i_inst);
     //listenターゲットのセット
     i_inst->_ref_sock=i_sock;
     //Listenerのリソースアンロック
-    NyLPC_cMutex_unlock(&(i_inst->_mutex));
+    unlockResource(i_inst);
 
 
     //一定時間待つ。
@@ -82,15 +90,15 @@
     NyLPC_cStopwatch_setNow(&sw);
     while(NyLPC_cStopwatch_elapseInMsec(&sw)<i_wait_msec){
         NyLPC_cThread_yield();
-//        led1=(a++)%2;
         //ステータス遷移が実行されていたら、ブレーク
         if(i_inst->_ref_sock->tcpstateflags==UIP_SYN_RCVD){
             break;
         }
     }
     NyLPC_cStopwatch_finalize(&sw);
+
     //Listenerのリソースロック
-    NyLPC_cMutex_lock(&(i_inst->_mutex));
+    lockResource(i_inst);
     //受領確認と戻り値の決定
     if(i_inst->_ref_sock->tcpstateflags==UIP_SYN_RCVD){
         ret=NyLPC_TBool_TRUE;
@@ -100,14 +108,14 @@
     //バインドしてあるソケットを解除
     i_inst->_ref_sock=NULL;
     //Listenerのリソースアンロック
-    NyLPC_cMutex_unlock(&(i_inst->_mutex));
+    unlockResource(i_inst);
     return ret;
 }
 
 /**
  * この関数は、Uip受信タスクから実行します。
  */
-NyLPC_TcTcpSocket_t* NyLPC_cTcpListener_makeSynRcvdSocket(NyLPC_TcTcpListener_t* i_inst,const NyLPC_TcIPv4Config_t* i_config,const NyLPC_TcIPv4Payload_t* i_payload)
+NyLPC_TcTcpSocket_t* NyLPC_cTcpListener_makeSynRcvdSocket(NyLPC_TcTcpListener_t* i_inst,const NyLPC_TcIPv4Payload_t* i_payload)
 {
     NyLPC_TcTcpSocket_t* sock=NULL;
     //パケットチェック。SYN設定されてる?
@@ -116,16 +124,16 @@
         return NULL;
     }
     //Listenerのリソースロック
-    NyLPC_cMutex_lock(&(i_inst->_mutex));
+    lockResource(i_inst);
     if(i_inst->_ref_sock!=NULL){
         //listenターゲットが指定されていたら、ソケットステータスの遷移。CLOSED->SYN_RCVD
-        if(NyLPC_cTcpSocket_setSynPayload(i_inst->_ref_sock ,i_config,i_payload))
+        if(NyLPC_cTcpSocket_setSynPayload(i_inst->_ref_sock,i_payload))
         {
             sock=i_inst->_ref_sock;
         }
     }
     //Listenerのリソースアンロック
-    NyLPC_cMutex_unlock(&(i_inst->_mutex));
+    unlockResource(i_inst);
     return sock;
 }
 
--- a/core/uip/NyLPC_cTcpListener.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/uip/NyLPC_cTcpListener.h	Wed Jun 19 09:33:01 2013 +0000
@@ -29,10 +29,10 @@
 typedef struct NyLPC_TcTcpListener NyLPC_TcTcpListener_t;
 
 
-#include "../include/NyLPC_stdlib.h"
-#include "NyLPC_cTcpSocket.h"
 #include "NyLPC_stdlib.h"
 #include "NyLPC_os.h"
+#include "NyLPC_cBaseSocket.h"
+#include "NyLPC_cTcpSocket.h"
 /**********************************************************************
  *
  * NyLPC_TcTcpListener class
@@ -47,11 +47,14 @@
  */
 struct NyLPC_TcTcpListener
 {
+    NyLPC_TcBaseSocket_t _super;
     NyLPC_TUInt16 _port;                /**<ネットワークオーダーのポート番号*/
     /** バインドするためのソケット*/
     NyLPC_TcTcpSocket_t* _ref_sock;
-    /** タスク間の調停用Mutex*/
-    NyLPC_TcMutex_t _mutex;
+    /** タスク間の調停用Mutex
+     * Listener用の共通Mutexポインタ
+     */
+    NyLPC_TcMutex_t* _mutex;
 };
 /**
  * この関数は、TCPのリスナーを初期化します。
--- a/core/uip/NyLPC_cTcpListener_protected.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/uip/NyLPC_cTcpListener_protected.h	Wed Jun 19 09:33:01 2013 +0000
@@ -48,7 +48,7 @@
 
 
 
-NyLPC_TcTcpSocket_t* NyLPC_cTcpListener_makeSynRcvdSocket(NyLPC_TcTcpListener_t* i_inst,const NyLPC_TcIPv4Config_t* i_config,const NyLPC_TcIPv4Payload_t* i_payload);
+NyLPC_TcTcpSocket_t* NyLPC_cTcpListener_makeSynRcvdSocket(NyLPC_TcTcpListener_t* i_inst,const NyLPC_TcIPv4Payload_t* i_payload);
 
 #ifdef __cplusplus
 }
--- a/core/uip/NyLPC_cTcpSocket.c	Thu May 16 16:06:46 2013 +0000
+++ b/core/uip/NyLPC_cTcpSocket.c	Wed Jun 19 09:33:01 2013 +0000
@@ -44,6 +44,12 @@
     #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))
+
 static void sendRst(NyLPC_TcTcpSocket_t* i_inst);
 
 
@@ -139,7 +145,7 @@
     }
     i_inst->txbuf.rp=i_inst->txbuf.wp=0;
     //ロック解除
-    NyLPC_cMutex_unlock(&(i_inst->_smutex));
+    unlockResource(i_inst);
     //セーブしたバッファを開放
     for(i=0;i<l;i++){
         NyLPC_cUipService_releaseTxBuf(dlist[i]);
@@ -272,11 +278,11 @@
         //キューの空きをチェック。wp+1==rpなら、キューがいっぱい。rp==wpなら、キューが空。
         if(((i_inst->txbuf.wp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ)==i_inst->txbuf.rp){
             //一時的なアンロック
-            NyLPC_cMutex_unlock(&(i_inst->_smutex));
+            unlockResource(i_inst);
             //タスクスイッチ
             NyLPC_cThread_yield();
             //ロック
-            NyLPC_cMutex_lock(&(i_inst->_smutex));
+            lockResource(i_inst);
             continue;
         }
         i=i_inst->txbuf.wp;
@@ -296,23 +302,24 @@
  * public 関数
  **********************************************************************/
 
-
 NyLPC_TBool NyLPC_cTcpSocket_initialize(NyLPC_TcTcpSocket_t* i_inst,void* i_rbuf,NyLPC_TUInt16 i_rbuf_len)
 {
     int i;
     NyLPC_TcUipService_t* srv=_NyLPC_TcUipService_inst;
+    NyLPC_cBaseSocket_initialize(&(i_inst->_super),NyLPC_TcBaseSocket_TYPEID_TCP_SOCK);
     //uipサービスは初期化済であること。
     NyLPC_Assert(NyLPC_TcUipService_isInitService());
 
     NyLPC_cFifoBuffer_initialize(&(i_inst->rxbuf),i_rbuf,i_rbuf_len);
-    NyLPC_AbortIfNot(NyLPC_cMutex_initialize(&(i_inst->_smutex)));
+    //  NyLPC_AbortIfNot(NyLPC_cMutex_initialize(&(i_inst->_smutex)));//個別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++){
         NyLPC_cIPv4Payload_initialize(&(i_inst->txbuf.txq[i].data));
     }
     //管理リストへ登録。
-    return NyLPC_cIPv4_addSocket(&(srv->_tcpv4),i_inst);
+    return NyLPC_cIPv4_addSocket(&(srv->_tcpv4),&(i_inst->_super));
 }
 void NyLPC_cTcpSocket_finalize(NyLPC_TcTcpSocket_t* i_inst)
 {
@@ -320,49 +327,44 @@
     NyLPC_TcUipService_t* srv=_NyLPC_TcUipService_inst;
     NyLPC_Assert(NyLPC_TcUipService_isInitService());
     //uipサービスは初期化済であること。
-    if(!NyLPC_cIPv4_removeSocket(&(srv->_tcpv4),i_inst)){
+    if(!NyLPC_cIPv4_removeSocket(&(srv->_tcpv4),&(i_inst->_super))){
         //削除失敗、それは死を意味する。
         NyLPC_Abort();
     }
     //開放漏れの保険
     if(i_inst->txbuf.rp!=i_inst->txbuf.wp){
-        NyLPC_cMutex_lock(&(i_inst->_smutex));
+        lockResource(i_inst);
         resetTxQWithUnlock(i_inst);
     }
     for(i=0;i<NyLPC_TcTcpSocket_NUMBER_OF_TXQ;i++){
         NyLPC_cIPv4Payload_finalize(&(i_inst->txbuf.txq[i].data));
     }
     NyLPC_cFifoBuffer_finalize(&(i_inst->rxbuf));
-    NyLPC_cMutex_finalize(&(i_inst->_smutex));
-
+//  NyLPC_cMutex_finalize(&(i_inst->_smutex));
+    NyLPC_cBaseSocket_finalize(&(i_inst->_super));
     return;
 }
 
-/**
- * この関数は、cIPv4Tcpが呼び出すシステムAPIです。
- * uipコアタスクが実行します。
- * ソケットを、SYNパケットで初期化して、UIP_SYN_RECV状態にします。
- * @return
- * 遷移に成功すると、TRUEを返します。
- */
-NyLPC_TBool NyLPC_cTcpSocket_setSynPayload(NyLPC_TcTcpSocket_t* i_inst,const NyLPC_TcIPv4Config_t* i_config,const NyLPC_TcIPv4Payload_t* i_ipp)
+
+NyLPC_TBool NyLPC_cTcpSocket_setSynPayload(NyLPC_TcTcpSocket_t* i_inst,const NyLPC_TcIPv4Payload_t* i_ipp)
 {
     NyLPC_TUInt16 tmp16;
+//  NyLPC_Assert(NyLPC_cMutex_isLocked(i_inst->_smutex));
+    lockResource(i_inst);
     //ソケットが無効であること。
-    NyLPC_cMutex_lock(&(i_inst->_smutex));
     if(i_inst->tcpstateflags==UIP_CLOSED)
     {
+        //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.lport = i_ipp->payload.tcp->destport;
         i_inst->uip_connr.rport = i_ipp->payload.tcp->srcport;
         i_inst->uip_connr.ripaddr=i_ipp->header->srcipaddr;
         i_inst->uip_connr.snd_nxt32=iss32;
-        i_inst->uip_connr.lipaddr=&(i_config->ip_addr);
         /* rcv_nxt should be the seqno from the incoming packet + 1. */
         i_inst->uip_connr.rcv_nxt32= NyLPC_ntohl(i_ipp->payload.tcp->seqno32)+1;
         //MSSの設定
-        i_inst->uip_connr.default_mss=i_inst->uip_connr.peer_mss=i_config->default_mss;
+        i_inst->uip_connr.peer_mss=i_inst->uip_connr.default_mss;
         if(NyLPC_TTcpHeader_getTcpMmsOpt(i_ipp->payload.tcp,&tmp16)){
             i_inst->uip_connr.peer_mss=tmp16;
         }
@@ -372,13 +374,13 @@
         if(i_inst->txbuf.rp!=i_inst->txbuf.wp){
             resetTxQWithUnlock(i_inst);
         }else{
-            NyLPC_cMutex_unlock(&(i_inst->_smutex));
+            unlockResource(i_inst);
         }
         //ここでステータスがかわる。
         i_inst->tcpstateflags = UIP_SYN_RCVD;
         return NyLPC_TBool_TRUE;
     }
-    NyLPC_cMutex_unlock(&(i_inst->_smutex));
+    unlockResource(i_inst);
     return NyLPC_TBool_FALSE;
 }
 /**
@@ -400,22 +402,22 @@
 static NyLPC_TBool waitForTxRemove(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_sq,NyLPC_TcStopwatch_t* i_timer)
 {
     NyLPC_TUInt8 f;
-    NyLPC_cMutex_lock(&(i_inst->_smutex));
+    lockResource(i_inst);
     while(!NyLPC_cStopwatch_isExpired(i_timer)){
         //パケットが送信中か調べる。
         if(!isPacketAcked(i_inst,i_sq)){
             //まだある場合は、タスクスイッチを繰り返して消失を待つ。
-            NyLPC_cMutex_unlock(&(i_inst->_smutex));
+            unlockResource(i_inst);
             NyLPC_cThread_yield();
-            NyLPC_cMutex_lock(&(i_inst->_smutex));
+            lockResource(i_inst);
             continue;
         }
         //なくなった場合は、原因を調べる。
         f=i_inst->tcpstateflags;
-        NyLPC_cMutex_unlock(&(i_inst->_smutex));
+        unlockResource(i_inst);
         return (f==UIP_CLOSED)?NyLPC_TBool_FALSE:NyLPC_TBool_TRUE;
     }
-    NyLPC_cMutex_unlock(&(i_inst->_smutex));
+    unlockResource(i_inst);
     return NyLPC_TBool_FALSE;
 }
 
@@ -452,17 +454,17 @@
             return -1;
         }
     };
-    NyLPC_cMutex_lock(&(i_inst->_smutex));
+    lockResource(i_inst);
     //ペイロードがある場合のみ、相手のwindowサイズが0以上になるのを待つ。
     if(i_len>0){
         while(i_inst->uip_connr.peer_win==0){
-            NyLPC_cMutex_unlock(&(i_inst->_smutex));
+            unlockResource(i_inst);
             //時間切れならエラー。
             if(NyLPC_cStopwatch_isExpired(i_timer)){
                 return -1;
             }
             NyLPC_cThread_yield();
-            NyLPC_cMutex_lock(&(i_inst->_smutex));
+            lockResource(i_inst);
         }
     }
     //送信キューの取得
@@ -470,7 +472,7 @@
     //送信キューが取れなかった。
     if(txq==NULL){
         //シーケンス番号をロールバックできないので、エラーとする。
-        NyLPC_cMutex_unlock(&(i_inst->_smutex));
+        unlockResource(i_inst);
         NyLPC_cUipService_releaseTxBuf(buf);
         return -1;
     }
@@ -504,7 +506,7 @@
     i_inst->uip_connr.peer_win-=s;
     //ACK番号の返却
     *o_ack=txq->ackno=NyLPC_HTONL(next_ack);
-    NyLPC_cMutex_unlock(&(i_inst->_smutex));
+    unlockResource(i_inst);
     NyLPC_cUipService_sendIPv4Tx(buf);
     return s;
 }
@@ -528,11 +530,11 @@
     do{
         buf=NyLPC_cUipService_allocTxBuf((SIZE_OF_IPv4_TCPIP_HEADER)+5,&s);
     }while(buf==NULL);
-    NyLPC_cMutex_lock(&(i_inst->_smutex));
+    lockResource(i_inst);
     NyLPC_cIPv4Payload_setTxBuf(&ipv4,buf);
     i_inst->uip_connr.snd_nxt32++;
     setPacket(i_inst,&ipv4,TCP_RST|TCP_ACK,buf,0);
-    NyLPC_cMutex_unlock(&(i_inst->_smutex));
+    unlockResource(i_inst);
 
     NyLPC_cUipService_sendIPv4Tx(buf);
     NyLPC_cUipService_releaseTxBuf(buf);
@@ -543,7 +545,7 @@
 
 
 /**
- * 受信データを排他処理してバッファに書き込む。
+ * 受信データをバッファに書き込む。
  * 十分な空き領域がない場合、失敗する。
  * この関数は、ロックして実行してください。
  */
@@ -605,12 +607,12 @@
         }
     }
     //ロックして、強制的なステータス遷移
-    NyLPC_cMutex_lock(&(i_inst->_smutex));
+    lockResource(i_inst);
     f=i_inst->tcpstateflags;
     if(f!=UIP_CLOSED){
         i_inst->tcpstateflags=UIP_CLOSED;
     }
-    NyLPC_cMutex_unlock(&(i_inst->_smutex));
+    unlockResource(i_inst);
     //もし、強制CLOSE遷移であれば、RSTも送信。
     if(f!=UIP_CLOSED){
         sendRst(i_inst);
@@ -639,12 +641,12 @@
         //読み出しバッファ情報のコピー
 
         //MUTEX LOCK
-        NyLPC_cMutex_lock(&(i_inst->_smutex));
+        lockResource(i_inst);
         st=i_inst->tcpstateflags;
         rlen=NyLPC_cFifoBuffer_getLength(&(i_inst->rxbuf));
         *o_buf_ptr=NyLPC_cFifoBuffer_getPtr(&(i_inst->rxbuf));
         //MUTEX UNLOCK
-        NyLPC_cMutex_unlock(&(i_inst->_smutex));
+        unlockResource(i_inst);
 
         //バッファが空の場合は、ステータスチェック。ESTABLISHEDでなければ、エラー(PASVCLOSE等の場合)
         switch(st){
@@ -697,14 +699,14 @@
     }while(buf==NULL);
 
     //MUTEX LOCK
-    NyLPC_cMutex_lock(&(i_inst->_smutex));
+    lockResource(i_inst);
 
     //受信バッファを読み出しシーク
     NyLPC_cFifoBuffer_pop(&(i_inst->rxbuf),i_seek);
     //ACKパケットの生成
     NyLPC_cIPv4Payload_setTxBuf(&ipv4payload,buf);
     setPacket(i_inst,&ipv4payload,TCP_ACK,buf,0);
-    NyLPC_cMutex_unlock(&(i_inst->_smutex));
+    unlockResource(i_inst);
     //ACK送信
     NyLPC_cUipService_sendIPv4Tx(buf);
     NyLPC_cUipService_releaseTxBuf(buf);
@@ -727,21 +729,28 @@
     //送信バッファを取得
     //@bug バッファが取れるまで通信がブロックするの。ここはなんとかしないと。
     for(;;){
-        //ESTABLISHED以外に非同期遷移 orタイムアウト確認
-        if(NyLPC_cStopwatch_isExpired(&sw)||(i_inst->tcpstateflags!=UIP_ESTABLISHED)){
+        //ESTABLISHED以外に非同期遷移
+        if(i_inst->tcpstateflags!=UIP_ESTABLISHED){
+            NyLPC_cStopwatch_finalize(&sw);
             return NULL;
         }
         buf=NyLPC_cUipService_allocTxBuf(i_hint+(SIZE_OF_IPv4_TCPIP_HEADER),&s);
         if(buf!=NULL){
             break;
         }
+        //タイムアウト時もエラー
+        if(NyLPC_cStopwatch_isExpired(&sw)){
+            NyLPC_cStopwatch_finalize(&sw);
+            return NULL;
+        }
     }
 
-//ここ、要求サイズとpeerのwinのうち、小さいほうを割り当てたほうが良くない?
-    NyLPC_cMutex_lock(&(i_inst->_smutex));
+//@todo 前段処理と順番を入れ替えて、要求サイズとpeerのwinのうち、小さいほうを割り当てたほうが良くない?
+//ここで相手のwin待ちをする理由は、相手に確実に受け取れるサイズを決定する為。
+    lockResource(i_inst);
     //ペイロードがある場合のみ、相手のwindowサイズが0以上になるのを待つ。
     while(i_inst->uip_connr.peer_win==0){
-        NyLPC_cMutex_unlock(&(i_inst->_smutex));
+        unlockResource(i_inst);
         //ESTABLISHED以外に非同期遷移 orタイムアウト確認
         if(NyLPC_cStopwatch_isExpired(&sw)||(i_inst->tcpstateflags!=UIP_ESTABLISHED)){
             NyLPC_cUipService_releaseTxBuf(buf);
@@ -749,7 +758,7 @@
             return NULL;
         }
         NyLPC_cThread_yield();
-        NyLPC_cMutex_lock(&(i_inst->_smutex));
+        lockResource(i_inst);
     }
     //送信バッファを基準とした送信サイズを計算
     s-=SIZE_OF_IPv4_TCPIP_HEADER;
@@ -761,7 +770,7 @@
     if(i_inst->uip_connr.peer_win<s){
         s=i_inst->uip_connr.peer_win;
     }
-    NyLPC_cMutex_unlock(&(i_inst->_smutex));
+    unlockResource(i_inst);
     //バッファサイズ確定。
     *o_buf_size=s;
     NyLPC_cStopwatch_finalize(&sw);
@@ -804,13 +813,13 @@
 
     //先頭ポインタは、i_buf-sizeof(SIZE_OF_IPv4_TCPIP_HEADER)固定
     buf=(NyLPC_TUInt8*)i_buf_ptr-SIZE_OF_IPv4_TCPIP_HEADER;
-    NyLPC_cMutex_lock(&(i_inst->_smutex));
+    lockResource(i_inst);
     //送信キューの取得
     txq=getTxQ(i_inst,&sw);
     //送信キューが取れなかった。
     if(txq==NULL){
         //シーケンス番号をロールバックできないので、エラーとする。
-        NyLPC_cMutex_unlock(&(i_inst->_smutex));
+        unlockResource(i_inst);
         NyLPC_cStopwatch_finalize(&sw);
         return NyLPC_TBool_FALSE;
     }
@@ -833,7 +842,7 @@
     i_inst->uip_connr.peer_win-=i_len;
     //ACK番号の返却
     txq->ackno=NyLPC_HTONL(i_inst->uip_connr.snd_nxt32);
-    NyLPC_cMutex_unlock(&(i_inst->_smutex));
+    unlockResource(i_inst);
     NyLPC_cUipService_sendIPv4Tx(buf);
     NyLPC_cStopwatch_finalize(&sw);
     return NyLPC_TBool_TRUE;
@@ -860,6 +869,7 @@
     memcpy(buf,i_buf_ptr,s);
     if(!NyLPC_cTcpSocket_psend(i_inst,buf,s,i_wait_in_msec)){
         NyLPC_cTcpSocket_releaseSendBuf(i_inst,buf);
+        return -1;//error
     }
     return s;
 }
@@ -872,7 +882,7 @@
     NyLPC_TUInt32 sq;
     NyLPC_cStopwatch_initialize(&sw);
     NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec);
-    NyLPC_cMutex_lock(&(i_inst->_smutex));
+    lockResource(i_inst);
 
     f=i_inst->tcpstateflags;
     //ステータスチェック
@@ -885,7 +895,7 @@
         //アクティブクローズ。
         i_inst->tcpstateflags=UIP_FIN_WAIT_1;
         //送信のために一旦解除
-        NyLPC_cMutex_unlock(&(i_inst->_smutex));
+        unlockResource(i_inst);
         //FINの送信
         if(sendWithRetransmit(i_inst,TCP_FIN|TCP_ACK,NULL,0,&sw,&sq)==0){
             //ちょっと待つ。
@@ -893,7 +903,7 @@
             //TXの消去待ち
             if(waitForTxRemove(i_inst,sq,&sw)){
                 //再ロック
-                NyLPC_cMutex_lock(&(i_inst->_smutex));
+                lockResource(i_inst);
                 //タイムアウトするか、UIP_CLOSED、もしくはTIME_WAITに遷移するのを待つ。(遷移はRxprocで自動的に実行。)
                 while(!NyLPC_cStopwatch_isExpired(&sw)){
                     switch(i_inst->tcpstateflags)
@@ -908,14 +918,14 @@
                     case UIP_FIN_WAIT_2:
                     case UIP_CLOSING:
                         //一時的なアンロック
-                        NyLPC_cMutex_unlock(&(i_inst->_smutex));
+                        unlockResource(i_inst);
                         NyLPC_cThread_yield();
-                        NyLPC_cMutex_lock(&(i_inst->_smutex));
+                        lockResource(i_inst);
                     default:
                         break;
                     }
                 }
-                NyLPC_cMutex_unlock(&(i_inst->_smutex));
+                unlockResource(i_inst);
             }
         }
         break;
@@ -923,41 +933,41 @@
         //LAST_ACKへ遷移
         i_inst->tcpstateflags=UIP_LAST_ACK;
         //送信のために一旦解除
-        NyLPC_cMutex_unlock(&(i_inst->_smutex));
+        unlockResource(i_inst);
         if(sendWithRetransmit(i_inst,TCP_FIN|TCP_ACK,NULL,0,&sw,&sq)==0){
             //ちょっと待つ。
             NyLPC_cThread_yield();
             //TXの消去待ち
             if(waitForTxRemove(i_inst,sq,&sw)){
                 //再ロック
-                NyLPC_cMutex_lock(&(i_inst->_smutex));
+                lockResource(i_inst);
                 //TX消去後にCLOSEDに遷移していればOK
                 if(i_inst->tcpstateflags==UIP_CLOSED)
                 {
                     NyLPC_Assert(i_inst->txbuf.rp==i_inst->txbuf.wp);
                     goto ReturnWithUnlock;
                 }
-                NyLPC_cMutex_unlock(&(i_inst->_smutex));
+                unlockResource(i_inst);
             }
         }
         //エラー。RSTで切断。
         break;
     default:
-        NyLPC_cMutex_unlock(&(i_inst->_smutex));
+        unlockResource(i_inst);
         NyLPC_Warning();
         break;
     }
-    if(i_inst->_smutex._lock_count>0){
-        NyLPC_Warning();
-    }
+//  if(i_inst->_smutex._lock_count>0){
+//      NyLPC_Warning();
+//  }
     //このパスに到達するのは、FIN送信/ACKに成功したにも拘らず、規定時間内にCLOSEDに遷移しなかった場合。
     //コネクションを強制遷移して、RST
-    NyLPC_cMutex_lock(&(i_inst->_smutex));
+    lockResource(i_inst);
     f=i_inst->tcpstateflags;
     if(f!=UIP_CLOSED){
         i_inst->tcpstateflags=UIP_CLOSED;
     }
-    NyLPC_cMutex_unlock(&(i_inst->_smutex));
+    unlockResource(i_inst);
     //もし、強制CLOSE遷移であれば、RSTも送信。
     if(f!=UIP_CLOSED){
         sendRst(i_inst);
@@ -965,14 +975,14 @@
     NyLPC_cStopwatch_finalize(&sw);
     return;
 ReturnWithUnlock:
-    NyLPC_cMutex_unlock(&(i_inst->_smutex));
+    unlockResource(i_inst);
     NyLPC_cStopwatch_finalize(&sw);
     return;
 }
 
 /**
+ * uipサービスタスクが実行する関数です。
  * 定期的に実行する関数。最低でも1s単位で実行してください。
- * 動作
  */
 void NyLPC_cTcpSocket_periodic(
     NyLPC_TcTcpSocket_t* i_inst)
@@ -985,17 +995,17 @@
     NyLPC_cStopwatch_initialize(&sw);
     now=NyLPC_cStopwatch_now();
     //MUTEX LOCK
-    NyLPC_cMutex_lock(&(i_inst->_smutex));
+    lockResource(i_inst);
     if(i_inst->tcpstateflags==UIP_CLOSED)
     {
         //CLOSEDなら、バッファ開放。
         resetTxQWithUnlock(i_inst);
     }else if(i_inst->txbuf.rp==i_inst->txbuf.wp){
         //再送信パケットがなければ何もしないよ。
-        NyLPC_cMutex_unlock(&(i_inst->_smutex));
+        unlockResource(i_inst);
     }else if(i_inst->uip_connr.peer_win==0){
         //peer_winが0の場合は何もしない。
-        NyLPC_cMutex_unlock(&(i_inst->_smutex));
+        unlockResource(i_inst);
     }else{
         //再送信処理
         rp=i_inst->txbuf.rp;
@@ -1017,16 +1027,46 @@
                 for(i=rp;i!=i_inst->txbuf.wp;i=(i+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ){
                     NyLPC_cUipService_sendIPv4Tx(NyLPC_cIPv4Payload_getBuf(&(q[i].data)));
                 }
-                NyLPC_cMutex_unlock(&(i_inst->_smutex));
+                unlockResource(i_inst);
             }
         }else{
-            NyLPC_cMutex_unlock(&(i_inst->_smutex));
+            unlockResource(i_inst);
         }
     }
     NyLPC_cStopwatch_finalize(&sw);
     return;
 }
-
+void led(int i);
+/**
+ * uipサービスタスクが実行する関数です。
+ * サービスの開始を通知します。
+ */
+void NyLPC_cTcpSocket_startService(NyLPC_TcTcpSocket_t* i_inst,const NyLPC_TcIPv4Config_t* i_config)
+{
+    NyLPC_Assert(i_inst->tcpstateflags==UIP_CLOSED);//閉じてなければおかしい。
+    i_inst->uip_connr.lipaddr=&(i_config->ip_addr); 
+    i_inst->uip_connr.default_mss=i_config->default_mss;
+    //NyLPC_cTcpSocket_setSynPayload関数でも実行するけど、IFのリセット時なのでここでもやる。
+    NyLPC_cFifoBuffer_clear(&(i_inst->rxbuf));
+    return;
+}
+/**
+ * uipサービスタスクが実行する関数です。
+ * サービスの停止を通知します。
+ */
+void NyLPC_cTcpSocket_stopService(NyLPC_TcTcpSocket_t* i_inst)
+{
+    lockResource(i_inst);
+    if(i_inst->tcpstateflags==UIP_CLOSED)
+    {
+        unlockResource(i_inst);
+    }else{
+        i_inst->tcpstateflags=UIP_CLOSED;
+        resetTxQWithUnlock(i_inst);
+        sendRst(i_inst);
+    }
+    return;
+}
 
 /**
  * この関数は、rxパケットを処理して、ソケットの状態を更新します。
@@ -1057,7 +1097,7 @@
     tcp_data_offset=o_ipp->payload.rawbuf+tmp16;
 
     //インスタンスをロックする。
-    NyLPC_cMutex_lock(&(i_inst->_smutex));
+    lockResource(i_inst);
 
     //RSTのチェック。RST受信時は、状態にかかわらず、CLOSEDステータスに移行する。
     if (in_tcpflag & TCP_RST)
@@ -1194,7 +1234,7 @@
     }else{
         ret=NyLPC_TBool_FALSE;
     }
-    NyLPC_cMutex_unlock(&(i_inst->_smutex));
+    unlockResource(i_inst);
     //取り外したTXメモリの開放
     for(i=0;i<s;i++){
         //取り外したTXメモリを開放
@@ -1204,7 +1244,7 @@
     return ret;
 DROP:
     //ACKしたパケットを送信キューから削除
-    NyLPC_cMutex_unlock(&(i_inst->_smutex));
+    unlockResource(i_inst);
 NyLPC_Trace();
     return NyLPC_TBool_FALSE;
 }
@@ -1214,3 +1254,5 @@
 
 
 
+
+
--- a/core/uip/NyLPC_cTcpSocket.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/uip/NyLPC_cTcpSocket.h	Wed Jun 19 09:33:01 2013 +0000
@@ -31,6 +31,7 @@
 #include "NyLPC_uip.h"
 #include "NyLPC_os.h"
 #include "NyLPC_cIPv4Payload.h"
+#include "NyLPC_cBaseSocket.h"
 
 
 #ifdef __cplusplus
@@ -64,8 +65,8 @@
     NyLPC_TUInt16                rport;     /**< The local remote TCP port, in network byte order. */
     NyLPC_TUInt32 rcv_nxt32;    /**< The sequence number that we expect to receive next. */
     NyLPC_TUInt32 snd_nxt32;    /**< 送信用sqカウンター*/
-    NyLPC_TUInt16 peer_mss;          /**< PeerのMSS*/
-    NyLPC_TUInt16 default_mss;   /**< Peerの初期MMS*/
+    NyLPC_TUInt16 peer_mss;     /**< PeerのMSS*/
+    NyLPC_TUInt16 default_mss;  /**< Peerの初期MMS*/
     /**Peerのウインドウサイズ*/
     NyLPC_TUInt16 peer_win;
     NyLPC_TUInt16 _padding;
@@ -88,10 +89,17 @@
 
 /**
  * uipサービスを使用したTCPソケットクラスです。
+ * この関数は2つのタスクから呼び出されます。
+ * [uipTask]  ->  [cTcpSocket] <- [Application]
+ * ApplicationとuipTaskとの間での排他処理はインスタンスで制御されています。
+ * Application側からのコールは内部でuipTaskとの間で排他処理を実行します。
+ * Application側からのコールはリエントラントではありません。
  */
 
 struct NyLPC_TcTcpSocket
 {
+    /** Base class*/
+    NyLPC_TcBaseSocket_t _super;
     //この変数は、uipタスクの実行する関数のみが変更する。
     struct uip_conn uip_connr;
     NyLPC_TcFifoBuffer_t rxbuf;
@@ -102,8 +110,8 @@
         struct NyLPC_TcTcpSocket_TxQItem txq[NyLPC_TcTcpSocket_NUMBER_OF_TXQ];
     }txbuf;
     volatile NyLPC_TUInt8 tcpstateflags; /**< TCP state and flags. */
-
-    NyLPC_TcMutex_t _smutex;
+    /** 共通MUTEXへのポインタ(うまくいtったらこのままで)*/
+    NyLPC_TcMutex_t* _smutex;
 };
 
 /**
@@ -148,6 +156,8 @@
  * @return
  * 成功した場合、送信バッファを返します。
  * アプリケーションは、可能な限り速やかにデータを書き込んで、NyLPC_cTcpSocket_psendをコールしてください。
+ * @note
+ * Optionフィールドを持つパケットを送信する場合は、オプションデータサイズの合計をデータサイズに指定して、payloadwriterで調整すること。
  */
 void* NyLPC_cTcpSocket_allocSendBuf(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_buf_size,NyLPC_TUInt32 i_wait_in_msec);
 
--- a/core/uip/NyLPC_cTcpSocket_protected.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/uip/NyLPC_cTcpSocket_protected.h	Wed Jun 19 09:33:01 2013 +0000
@@ -63,6 +63,7 @@
 
 /**
  * TCPペイロードを処理して、応答パケットをペイロードに返します。
+ * uipサービスタスクが実行する関数です。
  * @return
  * 応答ペイロードの有無を返します。
  */
@@ -71,9 +72,36 @@
     NyLPC_TcIPv4Payload_t* o_ipp);
 
 /**
- * ソケットをlisten済みにマークします。cTcpListenerからコールします。
+ * 定期的に実行する関数。最低でも1s単位で実行してください。
+ * uipサービスタスクが実行する関数です。
+ */
+void NyLPC_cTcpSocket_periodic(
+    NyLPC_TcTcpSocket_t* i_inst);
+
+/**
+ * uipサービスタスクが実行する関数です。
+ * uipコアタスクが実行します。
+ * コール前に共有MUTEXにロックをかけてください。
+ * ソケットを、SYNパケットで初期化して、UIP_SYN_RECV状態にします。
+ * @return
+ * 遷移に成功すると、TRUEを返します。
  */
-NyLPC_TBool NyLPC_cTcpSocket_setSynPayload(NyLPC_TcTcpSocket_t* i_inst,const NyLPC_TcIPv4Config_t* i_config,const NyLPC_TcIPv4Payload_t* i_ipp);
+NyLPC_TBool NyLPC_cTcpSocket_setSynPayload(NyLPC_TcTcpSocket_t* i_inst,const NyLPC_TcIPv4Payload_t* i_ipp);
+
+/**
+ * uipサービスタスクが実行する関数です。
+ * サービスの開始を通知します。
+ * この関数は他のAPIが非同期に実行されないことが保証される状況で使用する必要があります。
+ */
+void NyLPC_cTcpSocket_startService(NyLPC_TcTcpSocket_t* i_inst,const NyLPC_TcIPv4Config_t* i_config);
+
+/**
+ * uipサービスタスクが実行する関数です。
+ * サービスの停止を通知します。
+ * この関数は他のAPIが非同期に実行されないことが保証される状況で使用する必要があります。
+ */
+void NyLPC_cTcpSocket_stopService(NyLPC_TcTcpSocket_t* i_inst);
+
 
 #ifdef __cplusplus
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/uip/NyLPC_cUdpSocket.c	Wed Jun 19 09:33:01 2013 +0000
@@ -0,0 +1,339 @@
+/*********************************************************************************
+ * 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>
+ *
+ *
+ * Parts of this file were leveraged from uIP:
+ *
+ * Copyright (c) 2001-2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "NyLPC_cUdpSocket_protected.h"
+#include "NyLPC_cIPv4Payload_protected.h"
+#include "NyLPC_cUipService_protected.h"
+
+/**
+ * フラグ値
+ */
+#define NyLPC_cUdpSocket_FLAG_BROADCAST 0x01
+
+#define lockResource(i_inst) NyLPC_cMutex_lock(((i_inst)->_smutex))
+#define unlockResource(i_inst) NyLPC_cMutex_unlock(((i_inst)->_smutex))
+
+#define SIZE_OF_IPv4_UDPIP_HEADER 28
+
+NyLPC_TBool NyLPC_cUdpSocket_initialize(NyLPC_TcUdpSocket_t* i_inst,NyLPC_TUInt16 i_port,void* i_rbuf,NyLPC_TUInt16 i_rbuf_len)
+{
+    NyLPC_TcUipService_t* srv=_NyLPC_TcUipService_inst;
+    NyLPC_cBaseSocket_initialize(&(i_inst->_super),NyLPC_TcBaseSocket_TYPEID_UDP_SOCK);
+    //uipサービスは初期化済であること。
+    NyLPC_Assert(NyLPC_TcUipService_isInitService());
+    i_inst->_smutex=NyLPC_cIPv4_getSockMutex(&(srv->_tcpv4));
+    i_inst->uip_udp_conn.lport=NyLPC_htons(i_port);
+    i_inst->uip_udp_conn.mcastaddr=NyLPC_TIPv4Addr_ZERO;
+    i_inst->uip_udp_conn.flags=0x00;
+    i_inst->as_handler.rx=NULL;
+    i_inst->as_handler.periodic=NULL;
+
+    NyLPC_cFifoBuffer_initialize(&(i_inst->rxbuf),i_rbuf,i_rbuf_len);
+    //管理リストへ登録。
+    return NyLPC_cIPv4_addSocket(&(srv->_tcpv4),&(i_inst->_super));
+}
+
+void NyLPC_cUdpSocket_finalize(NyLPC_TcUdpSocket_t* i_inst)
+{
+    NyLPC_TcUipService_t* srv=_NyLPC_TcUipService_inst;
+    NyLPC_Assert(NyLPC_TcUipService_isInitService());
+    //uipサービスは初期化済であること。
+    if(!NyLPC_cIPv4_removeSocket(&(srv->_tcpv4),&(i_inst->_super))){
+        //削除失敗、それは死を意味する。
+        NyLPC_Abort();
+    }
+    NyLPC_cFifoBuffer_finalize(&(i_inst->rxbuf));
+    NyLPC_cBaseSocket_finalize(&(i_inst->_super));
+    return;
+}
+void NyLPC_cUdpSocket_joinMulticast(NyLPC_TcUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr)
+{
+    i_inst->uip_udp_conn.mcastaddr=*i_addr;
+}
+void NyLPC_cUdpSocket_setBroadcast(NyLPC_TcUdpSocket_t* i_inst)
+{
+    i_inst->uip_udp_conn.flags|=NyLPC_cUdpSocket_FLAG_BROADCAST;
+}
+
+
+
+/**
+ * この関数は、rxパケットを処理して、ソケットの状態を更新します。
+ * uipサービスタスクが実行する関数です。
+ * o_ippのペイロードに、応答ペイロードを設定することがあります。
+ * この関数はNyLPC_cTcpSocket_periodicと排他実行すること。
+ */
+NyLPC_TBool NyLPC_cUdpSocket_parseRx(
+    NyLPC_TcUdpSocket_t* i_inst,
+    NyLPC_TcIPv4Payload_t* o_ipp)
+{
+    NyLPC_TUInt16 tmp16;
+    struct NyLPC_TIPv4RxInfo dheader;
+    void* data_offset;
+    //ブロードキャストの場合、フラグを確認
+    if(NyLPC_TIPv4Addr_isEqual(&(o_ipp->header->destipaddr),&NyLPC_TIPv4Addr_BROADCAST)){
+        if(!NyLPC_TUInt8_isBitOn(i_inst->uip_udp_conn.flags,NyLPC_cUdpSocket_FLAG_BROADCAST)){
+            goto DROP;
+        }
+    }
+    //パラメータの計算
+    tmp16=NyLPC_TUdpHeader_getHeaderLength(o_ipp->payload.tcp);
+    //UDPペイロードの長さは、IPパケットの長さ-(IPヘッダ+UDPヘッダ)
+    dheader.size=NyLPC_TIPv4Header_getPacketLength(o_ipp->header)-NyLPC_TIPv4Header_getHeaderLength(o_ipp->header)-tmp16;
+    dheader.peer_ip=o_ipp->header->srcipaddr;
+    dheader.peer_port=NyLPC_ntohs(o_ipp->payload.udp->srcport);
+    dheader.ip=o_ipp->header->destipaddr;
+    dheader.port=NyLPC_ntohs(o_ipp->payload.udp->destport);
+    if(i_inst->as_handler.rx!=NULL){
+        if(!i_inst->as_handler.rx(i_inst,o_ipp->payload.rawbuf+tmp16,&dheader)){
+            return NyLPC_TBool_FALSE;//UDPはReturnパケットなし
+        }
+    }
+    //TCPデータオフセット
+    data_offset=o_ipp->payload.rawbuf+tmp16;
+
+    //インスタンスをロックする。
+    lockResource(i_inst);
+    //受信キューへ追加(データ構造はsize[2]+data[n]).sizeに16ビットの受信サイズ,後続にデータ
+
+    //受信データサイズを確認
+    if(NyLPC_cFifoBuffer_getSpace(&(i_inst->rxbuf))<dheader.size+sizeof(struct NyLPC_TIPv4RxInfo)){
+        goto DROP;
+    }
+    //バッファに格納可能なら、格納。
+    NyLPC_cFifoBuffer_push(&(i_inst->rxbuf),&dheader,sizeof(struct NyLPC_TIPv4RxInfo));
+    NyLPC_cFifoBuffer_push(&(i_inst->rxbuf),data_offset,dheader.size);
+    unlockResource(i_inst);
+    return NyLPC_TBool_FALSE;//UDPはReturnパケットなし
+DROP:
+    unlockResource(i_inst);
+    return NyLPC_TBool_FALSE;
+}
+
+
+
+/**
+ * see Header file
+ */
+NyLPC_TInt32 NyLPC_cUdpSocket_precv(NyLPC_TcUdpSocket_t* i_inst,const void** o_buf_ptr,const struct NyLPC_TIPv4RxInfo** o_info,NyLPC_TUInt32 i_wait_msec)
+{
+    NyLPC_TUInt16 rlen;
+    //タイマを生成
+    NyLPC_TcStopwatch_t sw;
+    NyLPC_cStopwatch_initialize(&sw);
+    const char* b;
+    const struct NyLPC_TIPv4RxInfo* rh;
+
+    //ESTABLISHED以外の場合は、エラー。
+    NyLPC_cStopwatch_setNow(&sw);
+    while(NyLPC_cStopwatch_elapseInMsec(&sw)<i_wait_msec)
+    {
+        //MUTEX LOCK
+        lockResource(i_inst);
+        rlen=NyLPC_cFifoBuffer_getLength(&(i_inst->rxbuf));
+        //MUTEX UNLOCK
+        unlockResource(i_inst);
+        if(rlen>0){
+            //受信キューにデータがあれば返す。
+            b=(char*)NyLPC_cFifoBuffer_getPtr(&(i_inst->rxbuf));
+            rh=(const struct NyLPC_TIPv4RxInfo*)b;
+            *o_buf_ptr=b+sizeof(struct NyLPC_TIPv4RxInfo);
+            if(o_info!=NULL){
+                *o_info=rh;
+            }
+            return rh->size;
+        }
+        //タスクスイッチ
+        NyLPC_cThread_yield();
+    };
+    NyLPC_cStopwatch_finalize(&sw);
+    return 0;
+}
+/**
+ * See header file
+ */
+void NyLPC_cUdpSocket_pseek(NyLPC_TcUdpSocket_t* i_inst)
+{
+    NyLPC_TUInt16 s;
+    const struct NyLPC_TIPv4RxInfo* rh;
+    //シークサイズを決定
+    s=NyLPC_cFifoBuffer_getLength(&(i_inst->rxbuf));
+    if(s==0){
+        return;
+    }
+    rh=(const struct NyLPC_TIPv4RxInfo*)NyLPC_cFifoBuffer_getPtr(&(i_inst->rxbuf));
+    NyLPC_cFifoBuffer_pop(&(i_inst->rxbuf),rh->size+sizeof(struct NyLPC_TIPv4RxInfo));
+}
+
+/**
+ * See header file.
+ */
+void* NyLPC_cUdpSocket_allocSendBuf(NyLPC_TcUdpSocket_t* i_inst,NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_buf_size,NyLPC_TUInt32 i_wait_in_msec)
+{
+    NyLPC_TUInt16 s;
+    void* buf;
+    NyLPC_TcStopwatch_t sw;
+
+    NyLPC_cStopwatch_initialize(&sw);
+    NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec);
+
+    //送信バッファを取得
+    //@bug バッファが取れるまで通信がブロックするの。ここはなんとかしないと。
+    for(;;){
+        buf=NyLPC_cUipService_allocTxBuf(i_hint+(SIZE_OF_IPv4_UDPIP_HEADER),&s);
+        if(buf!=NULL){
+            break;
+        }
+        //タイムアウト確認
+        if(NyLPC_cStopwatch_isExpired(&sw)){
+            return NULL;
+        }
+    }
+    //バッファサイズ確定。
+    *o_buf_size=s;
+    NyLPC_cStopwatch_finalize(&sw);
+    return (NyLPC_TUInt8*)buf+SIZE_OF_IPv4_UDPIP_HEADER;
+}
+/**
+ * See Header file.
+ */
+void NyLPC_cUdpSocket_releaseSendBuf(NyLPC_TcUdpSocket_t* i_inst,void* i_buf_ptr)
+{
+    NyLPC_cUipService_releaseTxBuf((NyLPC_TUInt8*)i_buf_ptr-SIZE_OF_IPv4_UDPIP_HEADER);
+}
+
+/**
+ * See header file
+ */
+NyLPC_TBool NyLPC_cUdpSocket_psend(NyLPC_TcUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_port,void* i_buf_ptr,int i_len)
+{
+    void* buf;
+    NyLPC_TcIPv4Payload_t ipp;
+    //ブロードキャストの場合、フラグを確認
+    if(NyLPC_TIPv4Addr_isEqual(i_addr,&NyLPC_TIPv4Addr_BROADCAST)){
+        if(!NyLPC_TUInt8_isBitOn(i_inst->uip_udp_conn.flags,NyLPC_cUdpSocket_FLAG_BROADCAST)){
+            return NyLPC_TBool_FALSE;
+        }
+    }
+
+    //先頭ポインタは、i_buf-sizeof(SIZE_OF_IPv4_TCPIP_HEADER)固定
+    buf=(NyLPC_TUInt8*)i_buf_ptr-SIZE_OF_IPv4_UDPIP_HEADER;
+    NyLPC_cIPv4Payload_initialize(&ipp);
+
+    lockResource(i_inst);
+    //IPv4ペイロードの書き込み
+    NyLPC_cIPv4Payload_setTxBuf(&ipp,buf);
+    //パケットヘッダの生成
+    NyLPC_cIPv4Payload_initUdpTx(&ipp,0x05,i_len);
+    NyLPC_cIPv4Payload_setUdpTxHeaderByConnection(&ipp,&(i_inst->uip_udp_conn),i_addr,i_port);
+    NyLPC_cIPv4Payload_closeUdpTxPacket(&ipp);
+    unlockResource(i_inst);
+    // !(BroadCast || Multicast)の場合は送信前にARPテーブルをチェックする。
+    if(!(NyLPC_TIPv4Addr_isEqual(i_addr,&NyLPC_TIPv4Addr_BROADCAST) || NyLPC_TIPv4Addr_isEqualWithMask(i_addr,&NyLPC_TIPv4Addr_MULTICAST,&NyLPC_TIPv4Addr_MULTICAST_MASK))){
+        if(!NyLPC_cUipService_hasArpInfo(i_addr)){
+            NyLPC_cUipService_sendArpRequest(i_addr);
+            NyLPC_cThread_sleep(30);
+        }
+    }
+    NyLPC_cUipService_sendIPv4Tx(buf);
+    NyLPC_cUipService_releaseTxBuf(buf);
+    NyLPC_cIPv4Payload_finalize(&ipp);
+    return NyLPC_TBool_TRUE;
+}
+
+/**
+ * See header file.
+ */
+NyLPC_TInt32 NyLPC_cUdpSocket_send(NyLPC_TcUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_port,const void* i_buf_ptr,NyLPC_TInt32 i_len,NyLPC_TUInt32 i_wait_in_msec)
+{
+    NyLPC_TUInt16 s;
+    int i;
+    void* buf;
+    if(i_len<1 || i_len>1200){
+        return 0;
+    }
+    //バッファの取得確率を上げるために2倍のサイズを要求
+    for(i=0;i<3;i++){
+        buf=NyLPC_cUdpSocket_allocSendBuf(i_inst,i_len*2,&s,i_wait_in_msec);
+        if(buf==NULL || s<i_len){
+            continue;
+        }
+        break;
+    }
+    if(buf==NULL){
+        return -1;
+    }
+    //送信サイズの計算
+    memcpy(buf,i_buf_ptr,i_len);
+    if(!NyLPC_cUdpSocket_psend(i_inst,i_addr,i_port,buf,i_len)){
+        NyLPC_cUdpSocket_releaseSendBuf(i_inst,buf);
+        return -1;
+    }
+    return i_len;
+}
+
+void NyLPC_cUdpSocket_startService(NyLPC_TcUdpSocket_t* i_inst,const NyLPC_TcIPv4Config_t* i_config)
+{
+    i_inst->uip_udp_conn.lipaddr=i_config->ip_addr;
+    //受信バッファのクリア
+    NyLPC_cFifoBuffer_clear(&(i_inst->rxbuf));
+    return;
+}
+
+
+void NyLPC_cUdpSocket_stopService(NyLPC_TcUdpSocket_t* i_inst)
+{
+    //停止処理?
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/uip/NyLPC_cUdpSocket.h	Wed Jun 19 09:33:01 2013 +0000
@@ -0,0 +1,154 @@
+/*
+ * NyLPC_cUdpSocket.h
+ *
+ *  Created on: 2013/05/20
+ *      Author: nyatla
+ */
+
+#ifndef NYLPC_CUDPSOCKET_H_
+#define NYLPC_CUDPSOCKET_H_
+#include "NyLPC_uip.h"
+#include "NyLPC_os.h"
+#include "NyLPC_cBaseSocket.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+typedef struct NyLPC_TcUdpSocket NyLPC_TcUdpSocket_t;
+/**
+ * 受信情報を格納する構造体
+ */
+struct NyLPC_TIPv4RxInfo
+{
+    NyLPC_TUInt16 size;//パケットサイズ
+    NyLPC_TUInt16 port;//受信ポート
+    NyLPC_TUInt16 peer_port;//PEERポート
+    struct NyLPC_TIPv4Addr ip;//受信IP
+    struct NyLPC_TIPv4Addr peer_ip;//PEERIP
+};
+
+/**
+ * Representation of a uIP UDP connection.
+ */
+struct uip_udp_conn{
+    struct NyLPC_TIPv4Addr lipaddr;   /**< The IP address of the remote peer. */
+    /** マルチキャスとアドレス(ZEROで無効)*/
+    struct NyLPC_TIPv4Addr mcastaddr;
+    NyLPC_TUInt16 lport;        /**< The local port number in network byte order. */
+    NyLPC_TUInt8  flags;        /**フラグ*/
+    NyLPC_TUInt8  padding;      /***/
+};
+
+/**
+ * 受信時に非同期にコールされるハンドラ
+ * UIPサービスタスクが実行する。
+ * @return
+ * TRUEならパケットを受信キューへ追加する。FALSEならパケットを受信キューへ追加しない。
+ */
+typedef NyLPC_TBool (*NyLPC_TcUdpSocket_onRxHandler)(NyLPC_TcUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info);
+/**
+ * 非同期にコールされるハンドラ。
+ * UIPサービスタスクが実行する。
+ */
+typedef void (*NyLPC_TcUdpSocket_onPeriodic)(NyLPC_TcUdpSocket_t* i_inst);
+
+struct NyLPC_TcUdpSocket
+{
+    NyLPC_TcBaseSocket_t _super;
+    //この変数は、uipタスクの実行する関数のみが変更する。
+    struct uip_udp_conn uip_udp_conn;
+    NyLPC_TcFifoBuffer_t rxbuf;
+    NyLPC_TcMutex_t* _smutex;
+    struct{
+        /** 受信ハンドラ。サービス実装に使用する。*/
+        NyLPC_TcUdpSocket_onRxHandler rx;
+        /** 定期実行ハンドラ。サービス実装に使用する。最低保障周期は1s*/
+        NyLPC_TcUdpSocket_onPeriodic periodic;
+    }as_handler;
+};
+
+
+
+
+
+/**
+ * @param i_rbuf
+ * 受信バッファアアドレス。サイズは、(最大受信サイズ-4バイト)*キュー数で計算します。
+ * @param i_rbuf_len
+ * 受信バッファのサイズ。
+ */
+NyLPC_TBool NyLPC_cUdpSocket_initialize(NyLPC_TcUdpSocket_t* i_inst,NyLPC_TUInt16 i_port,void* i_rbuf,NyLPC_TUInt16 i_rbuf_len);
+void NyLPC_cUdpSocket_finalize(NyLPC_TcUdpSocket_t* i_inst);
+
+/**
+ * マルチキャストアドレスに参加する。
+ * @param i_addr
+ * 参加するマルチキャストグループを指定する。
+ * 同じマルチキャスとグループに参加できるのは、システムの中で1つに限られます。
+ * 0を指定した場合、マルチキャスとグループから離脱します。
+ */
+void NyLPC_cUdpSocket_joinMulticast(NyLPC_TcUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr);
+
+/**
+ * ブロードキャストに参加する。
+ */
+void NyLPC_cUdpSocket_setBroadcast(NyLPC_TcUdpSocket_t* i_inst);
+
+
+/**
+ * この関数は、ソケットの受信バッファの読み取り位置と、読み出せるデータサイズを返却します。
+ * 関数はポインターを返却するだけで、バッファの読み取り位置をシークしません。
+ * シークするにはNyLPC_cTcpSocket_pseekを使います。
+ */
+NyLPC_TInt32 NyLPC_cUdpSocket_precv(NyLPC_TcUdpSocket_t* i_inst,const void** o_buf_ptr,const struct NyLPC_TIPv4RxInfo** o_info,NyLPC_TUInt32 i_wait_msec);
+/**
+ * 受信バッファを次のバッファまでシークします。
+ */
+void NyLPC_cUdpSocket_pseek(NyLPC_TcUdpSocket_t* i_inst);
+
+/**
+ * 送信バッファを割り当てて返します。
+ * 割り当てたメモリは、releaseSendBuf関数か、psend関数を成功させて開放する必要があります。
+ * @param i_hint
+ * 取得したいメモリサイズをセットします。
+ * 関数は要求サイズより小さいメモリを返すことがあります。
+ */
+void* NyLPC_cUdpSocket_allocSendBuf(NyLPC_TcUdpSocket_t* i_inst,NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_buf_size,NyLPC_TUInt32 i_wait_in_msec);
+
+void NyLPC_cUdpSocket_releaseSendBuf(NyLPC_TcUdpSocket_t* i_inst,void* i_buf_ptr);
+
+/**
+ * 事前にAllocしたTxパケットを送信します。
+ * このAPIはゼロコピー送信をサポートするためのものです。
+ * @param i_buf_ptr
+ * allocSendBufで取得したメモリを指定します。
+ * @return
+ * 関数が失敗した場合、i_buf_ptrは「開放されません。」
+ */
+NyLPC_TBool NyLPC_cUdpSocket_psend(NyLPC_TcUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_port,void* i_buf_ptr,int i_len);
+
+/**
+ * 最大送信サイズは1200バイトです。
+ */
+NyLPC_TInt32 NyLPC_cUdpSocket_send(NyLPC_TcUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_port,const void* i_buf_ptr,NyLPC_TInt32 i_len,NyLPC_TUInt32 i_wait_in_msec);
+
+/**
+ * 非同期パケットハンドラを設定する。
+ */
+#define NyLPC_cUdpSocket_setOnRxHandler(i_inst,i_handler) (i_inst)->as_handler.rx=i_handler;
+
+/**
+ * 非同期タイマ呼び出しハンドラを設定する。
+ */
+#define NyLPC_cUdpSocket_setOnPerriodicHandler(i_inst,i_handler) (i_inst)->as_handler.periodic=i_handler;
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* NYLPC_CUDPSOCKET_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/uip/NyLPC_cUdpSocket_protected.h	Wed Jun 19 09:33:01 2013 +0000
@@ -0,0 +1,53 @@
+/*
+ * NyLPC_cUdpSocket.h
+ *
+ *  Created on: 2013/05/20
+ *      Author: nyatla
+ */
+
+#ifndef NYLPC_CUDPSOCKET_PROTECTED_H_
+#define NYLPC_CUDPSOCKET_PROTECTED_H_
+#include "NyLPC_cUdpSocket.h"
+#include "NyLPC_cIPv4Payload.h"
+#include "NyLPC_cIPv4Config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/**
+ * この関数は、rxパケットを処理して、ソケットの状態を更新します。
+ * uipサービスタスクが実行する関数です。
+ */
+NyLPC_TBool NyLPC_cUdpSocket_parseRx(
+    NyLPC_TcUdpSocket_t* i_inst,
+    NyLPC_TcIPv4Payload_t* o_ipp);
+
+/**
+ * uipサービスタスクが実行する関数です。
+ * サービスの開始を通知します。
+ * この関数は他のAPIが非同期に実行されないことが保証される状況で使用する必要があります。
+ */
+void NyLPC_cUdpSocket_startService(NyLPC_TcUdpSocket_t* i_inst,const NyLPC_TcIPv4Config_t* i_config);
+
+/**
+ * uipサービスタスクが実行する関数です。
+ * サービスの停止を通知します。
+ * この関数は他のAPIが非同期に実行されないことが保証される状況で使用する必要があります。
+ */
+void NyLPC_cUdpSocket_stopService(NyLPC_TcUdpSocket_t* i_inst);
+
+
+/**
+ * 定期的に実行する関数。最低でも1s単位で実行してください。
+ * uipサービスタスクが実行する関数です。
+ */
+#define NyLPC_cUdpSocket_periodic(i_inst) if((i_inst)->as_handler.periodic!=NULL){(i_inst)->as_handler.periodic(i_inst);}
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* NYLPC_CUDPSOCKET_H_ */
--- a/core/uip/NyLPC_cUipService.c	Thu May 16 16:06:46 2013 +0000
+++ b/core/uip/NyLPC_cUipService.c	Wed Jun 19 09:33:01 2013 +0000
@@ -52,6 +52,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+#include "NyLPC_cUipService_protected.h"
 #include "NyLPC_cIPv4IComp_protected.h"
 #include "NyLPC_cTcpListener_protected.h"
 #include "NyLPC_stdlib.h"
@@ -137,7 +138,6 @@
 
 NyLPC_TBool NyLPC_cUipService_initialize(void)
 {
-
     NyLPC_TcUipService_t* inst=&_service_instance;
     //サービスは停止している事。 - Service must be uninitialized.
     NyLPC_Assert(!NyLPC_TcUipService_isInitService());
@@ -156,18 +156,9 @@
     NyLPC_AbortIfNot(NyLPC_cMutex_initialize(&(inst->_mutex)));
 
     _NyLPC_TcUipService_inst=inst;
-    inst->stx.h.is_lock=NyLPC_TUInt8_FALSE;
-    inst->stx.h.ref=0;
     //タスク起動
     NyLPC_cThread_initialize(&th,NyLPC_TcUipService_config_STACK_SIZE,NyLPC_TcThread_PRIORITY_SERVICE);
     NyLPC_cThread_start(&th,uipTask,NULL);
-//  NyLPC_AbortIfNot(pdPASS==xTaskCreate(
-//      uipTask,
-//      (signed char*)NyLPC_TcUipService_config_TASK_NAME,
-//      NyLPC_TcUipService_config_STACK_SIZE,
-//      ( void * ) NULL,
-//      NyLPC_TcUipService_config_TASK_PRIORITY,
-//      (void*)_NyLPC_TcUipService_inst));
     return NyLPC_TBool_TRUE;
 }
 
@@ -274,6 +265,8 @@
 #define PERIODIC_TIMER (1*200)
 #define ARP_TIMER (60*1000*10)
 
+
+
 /**
  * 操作キューを確認して、タスクのステータスをアップデートします。
  * 高速化のため、Proc-Callerを使用していません。複雑なタスク操作をするときには、書き換えてください。
@@ -307,6 +300,10 @@
         NyLPC_cIPv4Arp_initialize(&(inst->_arp),inst->_ref_config);
         NyLPC_cStopwatch_startExpire(&(inst->_arp_sw),1);//1度ARPを起動するため。
         NyLPC_cStopwatch_startExpire(&(inst->_periodic_sw),PERIODIC_TIMER);
+        //InBuffer初期化
+        inst->stx.h.is_lock=NyLPC_TUInt8_FALSE;
+        inst->stx.h.ref=0;
+        //EtherNETデバイス初期化
         while(!inst->_ethif->start(&(inst->_ref_config->eth_mac)));
         inst->_status=NyLPC_TcUipService_STATUS_RUN;
         break;
@@ -320,6 +317,7 @@
         inst->_ethif->stop();
         NyLPC_cIPv4_stop(&(inst->_tcpv4));
         NyLPC_cIPv4IComp_finalize(&(inst->_icomp));
+        NyLPC_cIPv4Arp_finalize(&(inst->_arp));
         inst->_status=NyLPC_TcUipService_STATUS_STOP;
         break;
     default:
@@ -409,7 +407,9 @@
             NyLPC_cStopwatch_startExpire(&(inst->_arp_sw),ARP_TIMER);
         }
         if(NyLPC_cStopwatch_isExpired(&(inst->_periodic_sw))){
+            NyLPC_cMutex_unlock(&(inst->_mutex));
             NyLPC_cIPv4_periodec(&(inst->_tcpv4));
+            NyLPC_cMutex_lock(&(inst->_mutex));
             NyLPC_cStopwatch_startExpire(&(inst->_periodic_sw),PERIODIC_TIMER);
         }
         //リソースロックの解除
@@ -442,8 +442,35 @@
     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_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_addr);
+    tx_len=NyLPC_TEthernetIIHeader_setArpTx(&(ethbuf->header),&(inst->_ref_config->eth_mac));
+    //送信
+    inst->_ethif->sendTxEthFrame(&(inst->stx.h),tx_len);
+    return;
+}
 
-
+/**
+ * ARPテーブルに指定したIPがあるかを返します。
+ */
+NyLPC_TBool NyLPC_cUipService_hasArpInfo(const struct NyLPC_TIPv4Addr* i_addr)
+{
+    NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
+    return NyLPC_cIPv4Arp_IPv4toEthAddr(&inst->_arp,*i_addr)!=NULL;
+}
 
 
 /**
@@ -452,14 +479,17 @@
  * @param i_hint
  * 取得したいメモリサイズを指定します。(このサイズは、イーサネットヘッダのサイズを含みません。)
  * このサイズよりも小さなサイズが割り当てられることがあります。
+ * @param o_size
+ * イーサネットヘッダを除いたペイロード部分の長さ
  * @return
  * 成功:IPペイロードのためのメモリブロックを返します。/失敗:NULL
+ * 返されるメモリはブロックの[TEthPacket][payload]の構造で、[payload]のアドレスが返されます。
  */
 void* NyLPC_cUipService_allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size)
 {
-    //排他処理をして、メモリを取得する。
     NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
     struct NyLPC_TTxBufferHeader* ethbuf;
+    //排他処理をして、メモリを取得する。
     NyLPC_cMutex_lock(&(inst->_mutex));
     ethbuf=(struct NyLPC_TTxBufferHeader*)inst->_ethif->allocTxBuf(i_hint+sizeof(struct NyLPC_TEthernetIIHeader),o_size);
     NyLPC_cMutex_unlock(&(inst->_mutex));
@@ -562,6 +592,20 @@
     return;
 }
 
+/**
+ * マルチキャスとアドレスへ変換する。
+ */
+static void ip2MulticastEmacAddr(const struct NyLPC_TIPv4Addr* i_addr,struct NyLPC_TEthAddr* o_emac)
+{
+    NyLPC_TUInt32 n=NyLPC_htonl(i_addr->v);
+    o_emac->addr[0]=0x01;
+    o_emac->addr[1]=0x00;
+    o_emac->addr[2]=0x5E;
+    o_emac->addr[3]=((n>>16) & 0x7f);
+    o_emac->addr[4]=((n>> 8) & 0xff);
+    o_emac->addr[5]=(n & 0xff);
+    return;
+};
 
 /**
  * ペイロードをIPパケットとしてネットワークへ送出します。
@@ -573,23 +617,32 @@
 static NyLPC_TBool sendIPv4Tx(struct NyLPC_TTxBufferHeader* i_eth_buf)
 {
     NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
+    struct NyLPC_TEthAddr emac;
     NyLPC_TUInt16 tx_len;
+    const struct NyLPC_TEthAddr* eth_dest;
     struct TEthPacket* ethbuf=(struct TEthPacket*)(i_eth_buf+1);
-NyLPC_Trace();
     //ペイロードのアドレスから、イーサネットフレームバッファのアドレスを復元
-    //const struct NyLPC_TEthAddr* eth_dest=uip_arp_IPv4toEthAddr(ethbuf->data.ipv4.destipaddr);
-    const struct NyLPC_TEthAddr* eth_dest=NyLPC_cIPv4Arp_IPv4toEthAddr(&inst->_arp,ethbuf->data.ipv4.destipaddr);
-    //IP->MAC変換をテスト。
-    if(eth_dest==NULL){
-        //失敗
-NyLPC_Trace();
-        return NyLPC_TBool_FALSE;
+
+    if(NyLPC_TIPv4Addr_isEqual(&(ethbuf->data.ipv4.destipaddr),&NyLPC_TIPv4Addr_BROADCAST)) {
+        //ブロードキャストならそのまま
+        eth_dest=&NyLPC_TEthAddr_BROADCAST;
+    }else if(NyLPC_TIPv4Addr_isEqualWithMask(&(ethbuf->data.ipv4.destipaddr),&NyLPC_TIPv4Addr_MULTICAST,&NyLPC_TIPv4Addr_MULTICAST_MASK)){
+        //マルチキャスト
+        ip2MulticastEmacAddr(&(ethbuf->data.ipv4.destipaddr),&emac);
+        eth_dest=&emac;
+    }else{
+        //LocalIP以外ならdefaultRootへ変換
+        eth_dest=NyLPC_cIPv4Arp_IPv4toEthAddr(
+            &inst->_arp,
+            NyLPC_cIPv4Config_isLocalIP(inst->_ref_config, &(ethbuf->data.ipv4.destipaddr))?(ethbuf->data.ipv4.destipaddr):(inst->_ref_config->dr_addr));
+        //IP->MAC変換をテスト。
+        if(eth_dest==NULL){
+            return NyLPC_TBool_FALSE;
+        }
     }
-NyLPC_Trace();
     //変換可能なら、イーサネットヘッダを更新して、送信処理へ。
     tx_len=NyLPC_TEthernetIIHeader_setIPv4Tx(&(ethbuf->header),&(inst->_ref_config->eth_mac),eth_dest);
     inst->_ethif->sendTxEthFrame(i_eth_buf,tx_len);
-NyLPC_Trace();
     return NyLPC_TBool_TRUE;
 }
 
--- a/core/uip/NyLPC_cUipService.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/uip/NyLPC_cUipService.h	Wed Jun 19 09:33:01 2013 +0000
@@ -84,7 +84,7 @@
 /** サービスタスクスタックサイズ
  *  LPCXpressonなら200バイトで動くけど、Mbedだと256
  */
-#define NyLPC_TcUipService_config_STACK_SIZE (256)
+#define NyLPC_TcUipService_config_STACK_SIZE (256+64)
 /** 登録できるリスナの最大数*/
 #define NyLPC_TcUipService_config_MAX_LISTENER 4
 
@@ -93,12 +93,12 @@
 
 /**
  * \param i_mac_addr
- * MACアドレスです。この値は、インスタンスに保存します。
+ * システムで唯一のUIPサービスを初期化します。1度だけ実行できます。
  */
 NyLPC_TBool NyLPC_cUipService_initialize(void);
 
 /**
- * UIP処理を開始します。
+ * 処理を開始します。
  * この関数はリエントラントではありません。複数のタスクから共有するときには、排他ロックを掛けてください。
  * @param i_ref_config
  * このコンフィギュレーションは、stopを実行するまでの間、インスタンスから参照します。外部で保持してください。
@@ -108,6 +108,7 @@
 /**
  * UIP処理を停止します。
  * この関数はリエントラントではありません。複数のタスクから共有するときには、排他ロックを掛けてください。
+ * 関数を使用する前に、全ての非同期ソケット操作を停止してください。
  */
 void NyLPC_cUipService_stop(void);
 
@@ -115,11 +116,11 @@
  * イーサネットデバイスの名前を返します。
  * この関数は、サービスが開始されているときのみ、動作します。
  */
-const char*  NyLPC_cUipService_refDeviceName(void);
+const char* NyLPC_cUipService_refDeviceName(void);
 const NyLPC_TcIPv4Config_t* NyLPC_cUipService_refCurrentConfig(void);
 
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 
-#endif
\ No newline at end of file
+#endif
--- a/core/uip/NyLPC_cUipService_protected.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/uip/NyLPC_cUipService_protected.h	Wed Jun 19 09:33:01 2013 +0000
@@ -24,8 +24,8 @@
  *
  *********************************************************************************/
 
-#ifndef NyLPC_uipService_H
-#define NyLPC_uipService_H
+#ifndef NyLPC_uipService_protected_H
+#define NyLPC_uipService_protected_H
 #include "NyLPC_cUipService.h"
 #include "../driver/uip/EthDev.h"
 #include "../driver/uip/EthDev_LPC17xx.h"
@@ -45,7 +45,7 @@
 struct NyLPC_TcUipService
 {
     const NyLPC_TcIPv4Config_t* _ref_config;
-    NyLPC_TUInt16   _status;            /**< ステータスビット*/
+    volatile NyLPC_TUInt16   _status;            /**< ステータスビット*/
     void*           _task_cmd;          /**< タスク操作用コマンド*/
     NyLPC_TcSemaphore_t _emac_semapho;  /** EMACの制御用セマフォです。*/
     NyLPC_TcStopwatch_t _arp_sw;        /**<ARP用のストップウォッチ*/
@@ -56,7 +56,7 @@
     NyLPC_TcIPv4_t _tcpv4;
     /** ICOMP処理インスタンス*/
     NyLPC_TcIPv4IComp_t _icomp;
-    /** 排他制御用*/
+    /** (Ethernetメモリ排他制御用)*/
     NyLPC_TcMutex_t _mutex;
     const struct TiEthernetDevice* _ethif;
     /** ipタスクが使う小サイズ送信バッファ*/
@@ -114,10 +114,14 @@
 /**
  * 送信ペイロードメモリを返します。
  * この関数は、リエントラントを許容します。
- * 取得したメモリは、releaseTxBufで必ず開放してください。
  * @param i_hint
  * 取得したいメモリサイズを指定します。(このサイズは、イーサネットヘッダのサイズを含みません。)
  * このサイズよりも小さなサイズが割り当てられることがあります。
+ * @param o_size
+ * 取得メモリのイーサネットヘッダを除いたペイロード部分の長さ
+ * @return
+ * 成功:IPペイロードのためのメモリブロックを返します。/失敗:NULL
+ * メモリは、[TEthPacket][payload]の構造で返されます。
  */
 void* NyLPC_cUipService_allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size);
 
@@ -126,8 +130,20 @@
  */
 void* NyLPC_cUipService_releaseTxBuf(void* i_buf);
 
-void NyLPC_cTcpSocket_periodic(
-    NyLPC_TcTcpSocket_t* i_inst);
+/**
+ * 指定したIPアドレスを要求するARPリクエストを発行します。
+ */
+void NyLPC_cUipService_sendArpRequest(const struct NyLPC_TIPv4Addr* i_addr);
+
+/**
+ * ARPテーブルに指定したIPがあるかを返します。
+ */
+NyLPC_TBool NyLPC_cUipService_hasArpInfo(const struct NyLPC_TIPv4Addr* i_addr);
+
+
+
+
+
 
 #ifdef __cplusplus
 }
--- a/core/uip/NyLPC_uip.c	Thu May 16 16:06:46 2013 +0000
+++ b/core/uip/NyLPC_uip.c	Wed Jun 19 09:33:01 2013 +0000
@@ -58,8 +58,10 @@
 
 const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_ZERO={0x00000000};
 const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_ALL ={0xffffffff};
-const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_BROADCAST = { 0xfffffff };
-
+const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_BROADCAST = { 0xffffffff };
+const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_MULTICAST = NyLPC_TIPv4Addr_pack(224,0,0,0);
+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_TUInt16 NyLPC_uip_chksum(NyLPC_TUInt16 sum, const NyLPC_TUInt8 *data, NyLPC_TUInt16 len)
@@ -145,7 +147,7 @@
     case UIP_PROTO_TCP:
         return sizeof(struct NyLPC_TEthernetIIHeader)+NyLPC_htons(iph->len16);
     case UIP_PROTO_UDP:
-        break;
+        return sizeof(struct NyLPC_TEthernetIIHeader)+NyLPC_htons(iph->len16);
     case UIP_PROTO_ICMP:
         return sizeof(struct NyLPC_TEthernetIIHeader)+NyLPC_htons(iph->len16);
     }
@@ -340,6 +342,11 @@
 {
     return (ip_header->tcpoffset>>4)*4;
 }
+/*--------------------------------------------------------------------------------
+ *
+ * struct NyLPC_TUdpHeader
+ *
+ *------------------------------------------------------------------------------*/
 
 
 
--- a/core/uip/NyLPC_uip.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/uip/NyLPC_uip.h	Wed Jun 19 09:33:01 2013 +0000
@@ -93,6 +93,9 @@
 extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_ZERO;
 extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_ALL;
 extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_BROADCAST;
+extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_MULTICAST;
+extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_MULTICAST_MASK;
+extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_APIPA_MASK;
 
 /**
  * addr1とaddr2が全く同じであるかをテストします。
@@ -113,8 +116,8 @@
  NyLPC_TIpv4Addr_set(&ip,1,2,3,4);
  \endcode
  */
-#define NyLPC_TIPv4Addr_set(s,a0,a1,a2,a3) (s)->v=NyLPC_htonl((0xff000000&(a0<<24))|(0x00ff0000&(a1<<16))|(0x0000ff00&(a2<<8))|(0x000000ff&(a3)))
-#define NyLPC_TIPv4Addr_pack(a0,a1,a2,a3) {NyLPC_HTONL((0xff000000&(a0<<24))|(0x00ff0000&(a1<<16))|(0x0000ff00&(a2<<8))|(0x000000ff&(a3)))}
+#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))))}
 
 
 
@@ -380,6 +383,11 @@
     NyLPC_TUInt16 udpchksum;
 } PACK_STRUCT_END;
 
+/**
+ * UDPヘッダの長さを返す。
+ */
+#define NyLPC_TUdpHeader_getHeaderLength(i_struct) (8)
+
 /**********************************************************************
  *
  * struct NyLPC_TIcmpipHeader
--- a/core/utils/NyLPC_cFormatTextReader.c	Thu May 16 16:06:46 2013 +0000
+++ b/core/utils/NyLPC_cFormatTextReader.c	Wed Jun 19 09:33:01 2013 +0000
@@ -9,7 +9,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include "NyLPC_cFormatTextReader.h"
-
 /**
  * [a-zA-Z0-9_-]で構成されるワードを取得します。
  * This function peek a word from string.
@@ -28,10 +27,12 @@
  * 文字列からIPアドレスを取得します。
  * [:number:]\.[:number:]\.[:number:]\.[:number:]
  * [:number:]は0-255までに制限されます。
+ * @param v
+ * uint8[4]
  * @return
  * next pointer
  */
-NyLPC_TInt32 NyLPC_cFormatTextReader_readIpAddr(const NyLPC_TChar* buf,NyLPC_TUInt8 v[4])
+NyLPC_TInt32 NyLPC_cFormatTextReader_readIpAddr(const NyLPC_TChar* buf,NyLPC_TUInt8* v)
 {
     NyLPC_TInt32 t;
     const NyLPC_TChar* p=buf;
@@ -57,12 +58,30 @@
     return (p-buf);
 }
 /**
+ * 文字列から10進数の数値を読み出します。
+ * @return
+ * 読み出した文字数
+ */
+NyLPC_TInt32 NyLPC_cFormatTextReader_readUInt(const NyLPC_TChar* buf,NyLPC_TUInt32* v)
+{
+    NyLPC_TUInt32 t;
+    const NyLPC_TChar* p=buf;
+    t=0;
+    for(;isdigit(*p);p++){
+        t=t*10+NyLPC_ctoi(*p);
+    }
+    *v=t;
+    return (p-buf);
+}
+
+/**
  * 文字列からMACアドレスを取得します。
  * [:hex:]:[:hex:]:[:hex:]:[:hex:]
+ * @param v
+ * uint8[6]
  */
-NyLPC_TInt32 NyLPC_cFormatTextReader_readMacAddr(const NyLPC_TChar* buf,NyLPC_TUInt8 v[6])
+NyLPC_TInt32 NyLPC_cFormatTextReader_readMacAddr(const NyLPC_TChar* buf,NyLPC_TUInt8* v)
 {
-
     NyLPC_TInt32 t,i;
     const NyLPC_TChar* p=buf;
     for(i=0;i<6;i++){
@@ -70,17 +89,17 @@
         for(;isxdigit(*p);p++){
             t=t*16+NyLPC_ctox(*p);
             if(t>255){
-                return -1;
+                return 0;
             }
         }
         v[i]=t;
         if(i<5){
             if(*p!=':'){
-                return -2;
+                return 0;
             }
             p++;
         }else if(!isspace(*p) && *p!='\0'){
-            return -3;
+            return 0;
         }
     }
     return (p-buf);
--- a/core/utils/NyLPC_cFormatTextReader.h	Thu May 16 16:06:46 2013 +0000
+++ b/core/utils/NyLPC_cFormatTextReader.h	Wed Jun 19 09:33:01 2013 +0000
@@ -1,7 +1,7 @@
 /**
  * @file
  * NyLPC_cFormattextReader.h
- * NULL書式テキストを読み出す為の関数群です。
+ * 書式テキストを読み出す為の関数群です。
  *  Created on: 2013/04/20
  *      Author: nyatla
  */
@@ -25,25 +25,34 @@
  * 文字列からIPアドレスを取得します。
  * [:number:]\.[:number:]\.[:number:]\.[:number:]
  * [:number:]は0-255までに制限されます。
+ * @param v
+ * uint8[4]
  * @return
  * next pointer
  */
-NyLPC_TInt32 NyLPC_cFormatTextReader_readIpAddr(const NyLPC_TChar* buf,NyLPC_TUInt8 v[4]);
+NyLPC_TInt32 NyLPC_cFormatTextReader_readIpAddr(const NyLPC_TChar* buf,NyLPC_TUInt8* v);
 
 /**
  * 文字列からMACアドレスを取得します。
  * [:hex:]:[:hex:]:[:hex:]:[:hex:]
+ * @param v
+ * uint8[6]
  */
-NyLPC_TInt32 NyLPC_cFormatTextReader_readMacAddr(const NyLPC_TChar* buf,NyLPC_TUInt8 v[6]);
+NyLPC_TInt32 NyLPC_cFormatTextReader_readMacAddr(const NyLPC_TChar* buf,NyLPC_TUInt8* v);
 
 /**
  * 連続するスペースを読み飛ばします。
+ */
+NyLPC_TInt32 NyLPC_cFormatTextReader_seekSpace(const NyLPC_TChar* s);
+
+/**
+ * 文字列から10進数の数値を読み出します。
  * @return
  * 読み飛ばしたスペース
  */
-NyLPC_TInt32 NyLPC_cFormatTextReader_seekSpace(const NyLPC_TChar* s);
+NyLPC_TInt32 NyLPC_cFormatTextReader_readUInt(const NyLPC_TChar* buf,NyLPC_TUInt32* v);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
-
 #endif /* NYLPC_CFORMATTEXTREADER_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/utils/NyLPC_cFormatWriter.c	Wed Jun 19 09:33:01 2013 +0000
@@ -0,0 +1,134 @@
+#include "NyLPC_cFormatWriter.h"
+
+
+#define FTYPE_LENGTH 0x00000001
+#define FTYPE_NOTHING 0x00000000
+
+#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)
+{
+    const char* rp=i_fmt;
+    const char* sp;
+    char wk[NUM_OF_WORK];
+    NyLPC_TUInt32 ftype;
+    NyLPC_TUInt32 ut;
+    int 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){
+                        i_handler(i_inst,wk,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){
+                    i_handler(i_inst,wk,ol);
+                    ol=0;
+                }
+                NyLPC_itoa((va_arg(args,int)),wk,10);
+                //強制コミット
+                i_handler(i_inst,wk,strlen(wk));
+                rp++;
+                continue;
+            case 'u':
+                //ワークを空にする。
+                if(ol>0){
+                    i_handler(i_inst,wk,ol);
+                }
+                ut=va_arg(args,NyLPC_TUInt32);
+                ol=15;
+                wk[ol--]='\0';
+                do{
+                    wk[ol--]='0'+(ut%10);
+                    ut/=10;
+                }while(ut>0);
+                i_handler(i_inst,(wk+ol+1),14-ol);
+                ol=0;
+                rp++;
+                continue;
+            case 'x':
+                //ワークを空にする。
+                if(ol>0){
+                    i_handler(i_inst,wk,ol);
+                    ol=0;
+                }
+                NyLPC_uitoa((va_arg(args,unsigned int)),wk,16);
+                //強制コミット
+                i_handler(i_inst,wk,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){
+                i_handler(i_inst,wk,NUM_OF_WORK);
+                ol=0;
+            }
+        }else if(*rp==0){
+            //オワタ
+            break;
+        }else{
+            wk[ol]=*rp;
+            ol++;
+            rp++;
+            if(ol>=NUM_OF_WORK){
+                i_handler(i_inst,wk,NUM_OF_WORK);
+                ol=0;
+            }
+        }
+    }
+    //どこかでエラーが起こってればFALSE返す。
+    return i_handler(i_inst,wk,ol);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/utils/NyLPC_cFormatWriter.h	Wed Jun 19 09:33:01 2013 +0000
@@ -0,0 +1,28 @@
+#include "NyLPC_stdlib.h"
+#include <stdarg.h>
+#ifndef NYLPC_CFORMATTEXTWRITER_H_
+#define NYLPC_CFORMATTEXTWRITER_H_
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+typedef NyLPC_TBool(*NyLPC_cFormatWriter_printHandler)(void* i_inst,const void* i_buf,NyLPC_TUInt32 i_len);
+/**
+ * printfライクな書式出力関数です。i_handlerへi_fmtに示される書式文字列を出力します。
+ * @param i_fmt
+ * フォーマット文字列。以下の形式をサポートします。
+ * %d
+ * %u
+ * %c
+ * %%
+ * %s,%.*s
+ *
+ */
+NyLPC_TBool NyLPC_cFormatWriter_print(NyLPC_cFormatWriter_printHandler i_handler,void* i_inst,const NyLPC_TChar* i_fmt,va_list args);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* NYLPC_CFORMATTEXTREADER_H_ */
--- a/mbed/Net.cpp	Thu May 16 16:06:46 2013 +0000
+++ b/mbed/Net.cpp	Wed Jun 19 09:33:01 2013 +0000
@@ -4,16 +4,58 @@
 ////////////////////////////////////////////////////////////////////////////////
 #include "Net.h"
 #include "NetConfig.h"
+#include "mbed.h"
 
+extern "C" void led(int i);
 namespace MiMic
 {
-    Net::Net(NetConfig& i_cfg)
+
+    Net::Net()
     {
         NyLPC_cNet_initialize(&(this->_inst));
-        NyLPC_cNet_start(&(this->_inst),&(i_cfg._inst));
+        this->_mdns=NULL;
     }
     Net::~Net()
     {
         NyLPC_cNet_finalize(&(this->_inst));
     }
+    void Net::start(NetConfig& i_cfg)
+    {
+        //DHCP & autoIP request
+        if(i_cfg._inst.tcp_mode & NyLPC_TcNetConfig_IPV4_FLAG_MODE_MASK!=0){
+            for(;;){
+                //DHCP
+                if((i_cfg._inst.tcp_mode & NyLPC_TcNetConfig_IPV4_FLAG_MODE_DHCP)!=0){
+                    if(NyLPC_cNet_requestAddrDhcp(&(this->_inst),&(i_cfg._inst.super),3)){
+                        break;
+                    }
+                }
+                //AUTOIP
+                if((i_cfg._inst.tcp_mode & NyLPC_TcNetConfig_IPV4_FLAG_MODE_AUTOIP)!=0){
+                    NyLPC_TcApipa_t apipa;
+                    NyLPC_cApipa_initialize(&apipa);
+                    if(NyLPC_cApipa_requestAddr(&apipa,&(i_cfg._inst.super),3)){
+                        break;
+                    }
+                }
+            }
+        }
+        //start mDNS
+        if(i_cfg._inst.services.flags & NyLPC_TcNetConfig_SERVICE_FLAG_MDNS !=0){
+            this->_mdns=(NyLPC_TcMDnsServer_t*)malloc(sizeof(NyLPC_TcMDnsServer_t));
+            NyLPC_cMDnsServer_initialize(this->_mdns,&(i_cfg._dns_record));        
+        }
+        NyLPC_cNet_start(&(this->_inst),&(i_cfg._inst));
+    }
+    void Net::stop()
+    {
+        NyLPC_cNet_stop(&(this->_inst));
+        //stop mDNS
+        if(this->_mdns!=NULL){
+            NyLPC_cMDnsServer_finalize(this->_mdns);        
+            free(this->_mdns);
+            this->_mdns=NULL;
+        }
+    }
+    
 }
\ No newline at end of file
--- a/mbed/Net.h	Thu May 16 16:06:46 2013 +0000
+++ b/mbed/Net.h	Wed Jun 19 09:33:01 2013 +0000
@@ -9,15 +9,25 @@
     class NetConfig;
     class Net
     {
+    private:
+        NyLPC_TcMDnsServer_t* _mdns;
     public:
         NyLPC_TcNet_t _inst;
     public:
         /**
          * The constructor.
-         * @param i_cfg
-         * The instance references the object. Must hold until the instance deleted.
+         * Must be call after the RTOS started.
          */
-        Net(NetConfig& i_cfg);
+        Net();
         virtual ~Net();
+        /**
+         * This function starts networking with configulation. 
+         * @param i_cfg
+         * configuration parameter.
+         * Must be hold until instance is freed.
+         * This may be changed by initializer it has DHCP or AUTOIP flag.
+         */
+        void start(NetConfig& i_cfg);
+        void stop();
     };
 }
\ No newline at end of file
--- a/mbed/NetConfig.cpp	Thu May 16 16:06:46 2013 +0000
+++ b/mbed/NetConfig.cpp	Wed Jun 19 09:33:01 2013 +0000
@@ -7,23 +7,49 @@
 #include <stdlib.h>
 #include "mbed.h"
 
+//default mdns records
+const static char* MDNS_SRV_HTTP="_http._tcp\0";
+const static char* MDNS_NAME="LPC176x(MiMic)\0";
+
 extern "C" void mbed_mac_address(char *s);
-void overrideMacAddrIfmbed(NyLPC_TcNetConfig& v)
+
+static void printHex2(char* out,int v,int d)
 {
-    mbed_mac_address((char*)(v.interface_setting.ethernet.eth_mac.addr));
+    size_t l;
+    NyLPC_itoa(v,out,16);
+    l=strlen(out);
+    if(l<d){
+        memcpy(out+(d-l),out,l);
+        memset(out,'0',(d-l));
+    }
+    *(out+d)='\0';
 }
-void updateOnchipConfig(NyLPC_TcNetConfig& v)
+
+static void overrideMacAddrIfmbed(NyLPC_TcNetConfig& v)
 {
-    struct NyLPC_TMimicConfigulation cfg_image;    
+    mbed_mac_address((char*)(v.super.eth_mac.addr));
+    //update default hostname
+    strcpy(v.hostname,"MiMic");
+    printHex2(v.hostname+5,NyLPC_TcIPv4Config_getEtherMac000120203(&(v.super)),8);
+    printHex2(v.hostname+13,(NyLPC_TcIPv4Config_getEtherMac0405xxxx(&(v.super))>>16)&0xffff,4);    
+    v.services.flags=NyLPC_TcNetConfig_SERVICE_FLAG_MDNS;
+}
+
+static void updateOnchipConfig(NyLPC_TcNetConfig& v)
+{   
+    struct NyLPC_TMiMicConfigulation cfg_image;    
     //パラメータ→ROMイメージ変換
     cfg_image.fast_boot=0xffffffff;
-    cfg_image.mac_00_01_02_03=NyLPC_TcIPv4Config_getEtherMac000120203(&(v.interface_setting.ethernet));
-    cfg_image.mac_04_05_xx_xx=NyLPC_TcIPv4Config_getEtherMac0405xxxx(&(v.interface_setting.ethernet));
-    cfg_image.ipv4_addr_net  =NyLPC_ntohl(v.interface_setting.ethernet.ip_addr.v);
-    cfg_image.ipv4_mask_net  =NyLPC_ntohl(v.interface_setting.ethernet.netmask.v);
-    cfg_image.ipv4_drut_net  =NyLPC_ntohl(v.interface_setting.ethernet.dr_addr.v);
-    cfg_image.ipv4_port = 80;//dummy!
-    cfg_image.accessmode= 0x0000FFFF;//dummy!
+    cfg_image.mac_00_01_02_03=NyLPC_TcIPv4Config_getEtherMac000120203(&(v.super));
+    cfg_image.mac_04_05_xx_xx=NyLPC_TcIPv4Config_getEtherMac0405xxxx(&(v.super));
+    cfg_image.ipv4_addr_net  =NyLPC_ntohl(v.super.ip_addr.v);
+    cfg_image.ipv4_mask_net  =NyLPC_ntohl(v.super.netmask.v);
+    cfg_image.ipv4_drut_net  =NyLPC_ntohl(v.super.dr_addr.v);
+    //additional information
+    cfg_image.ipv4_flags=v.tcp_mode;
+    cfg_image.http_port=v.services.http_port;
+    cfg_image.srv_flags=v.services.flags;
+    strcpy(cfg_image.hostname,v.hostname);
     //FreeRTOSの停止
     NyLPC_cIsr_enterCritical();
     //Flashへの書き込み
@@ -31,9 +57,12 @@
     //FreeRTOSの復帰
     NyLPC_cIsr_exitCritical();
 }
+
+
 namespace MiMic
 {
 
+
     NetConfig::NetConfig(bool i_is_factory_default)
     {
         NyLPC_cNetConfig_initialize(&(this->_inst),i_is_factory_default);
@@ -58,46 +87,93 @@
                 //nothing to do
             }
         }
+        //update DNS record
+        this->_dns_record.name=MDNS_NAME;
+        this->_dns_record.a=this->_inst.hostname;
+        this->_dns_record.num_of_srv=1;
+        this->_srv_record.protocol=MDNS_SRV_HTTP;
+        this->_srv_record.port=this->_inst.services.http_port;
+        this->_dns_record.srv=&(this->_srv_record);
     }
     NetConfig::~NetConfig()
     {
         NyLPC_cNetConfig_finalize(&(this->_inst));
     }
+
+    void NetConfig::setZeroconf(bool v)
+    {
+        this->_inst.tcp_mode=(v?NyLPC_TcNetConfig_IPV4_FLAG_MODE_APIPA:NyLPC_TcNetConfig_IPV4_FLAG_MODE_MANUAL);
+    }
     /**
       * Set IPv4 ip address to instance.
       */
     void NetConfig::setIpAddr(unsigned char ip1,unsigned char ip2,unsigned char ip3,unsigned char ip4)
     {
-        NyLPC_TIPv4Addr_set(&(this->_inst.interface_setting.ethernet.ip_addr),ip1,ip2,ip3,ip4);
+        NyLPC_TIPv4Addr_set(&(this->_inst.super.ip_addr),ip1,ip2,ip3,ip4);
     }
     /**
      * Set IPv4 network mask value to instance.
      */
     void NetConfig::setNetMask(unsigned char ip1,unsigned char ip2,unsigned char ip3,unsigned char ip4)
     {
-        NyLPC_TIPv4Addr_set(&(this->_inst.interface_setting.ethernet.netmask),ip1,ip2,ip3,ip4);
+        NyLPC_TIPv4Addr_set(&(this->_inst.super.netmask),ip1,ip2,ip3,ip4);
     }
     /**
      * Set IPv4 default gateway address to instance.
      */
     void NetConfig::setGateway(unsigned char ip1,unsigned char ip2,unsigned char ip3,unsigned char ip4)
     {
-        NyLPC_TIPv4Addr_set(&(this->_inst.interface_setting.ethernet.dr_addr),ip1,ip2,ip3,ip4);   
+        NyLPC_TIPv4Addr_set(&(this->_inst.super.dr_addr),ip1,ip2,ip3,ip4);   
     }
     /**
      * Set ethernet mac address to instance.
      */
     void NetConfig::setEmac(unsigned char a1,unsigned char a2,unsigned char a3,unsigned char a4,unsigned char a5,unsigned char a6)
     {
-        NyLPC_TEthAddr_set(&(this->_inst.interface_setting.ethernet.eth_mac),a1,a2,a3,a4,a5,a6);
+        NyLPC_TEthAddr_set(&(this->_inst.super.eth_mac),a1,a2,a3,a4,a5,a6);
+    }
+    void NetConfig::setSrvHttpPort(unsigned short port)
+    {
+        this->_inst.services.http_port=port;
     }
+    void NetConfig::setSrvMdns(bool i_enable)
+    {
+        if(i_enable){
+            this->_inst.services.flags|=NyLPC_TcNetConfig_SERVICE_FLAG_MDNS;
+        }else{
+            this->_inst.services.flags&=(~NyLPC_TcNetConfig_SERVICE_FLAG_MDNS);
+        }
+    }
+    void NetConfig::setHostName(const char* i_hostname)
+    {
+        this->setHostName(i_hostname,strlen(i_hostname));
+    }
+    void NetConfig::setHostName(const char* i_hostname,int len)
+    {
+        int l=(len>(NyLPC_TcNetConfig_HOSTNAME_LEN-1))?NyLPC_TcNetConfig_HOSTNAME_LEN-1:len;
+        memcpy(this->_inst.hostname,i_hostname,l);
+        *(this->_inst.hostname+l)='\0';
+    }
+    
     bool NetConfig::loadFromFile(const char* i_file)
     {
-        const static char* tbl[]={"macaddr","ipaddr","netmask","gateway"};
+        const static char* tbl[]={
+            "macaddr",  //0
+            "ipaddr",   //1
+            "netmask",  //2
+            "gateway",  //3
+            "srv_http_port",//4
+            "srv_mdns",//5
+            "host",//6
+            };
         char tmp[32];
-        unsigned char v[6];
-        const char* p;
+        union{
+            unsigned char u8[6];
+            NyLPC_TUInt32 u32;
+        }v;
+        const char* p;//pointer to read
         const char* key;
+        const char* t;
         int l;
         FILE* fp = fopen(i_file,"r");
         if(fp==NULL){
@@ -107,7 +183,7 @@
         while(fgets(tmp,31,fp)){
             p=NyLPC_cFormatTextReader_seekSpace(tmp)+tmp;//skip space
             l=NyLPC_cFormatTextReader_readWord(p,&key);
-            for(int i=0;i<4;i++){
+            for(int i=0;i<7;i++){
                 if(l>=0 && NyLPC_strnicmp(key,tbl[i],l)==0){
                     p+=l;//skip keyname
                     p=NyLPC_cFormatTextReader_seekSpace(p)+p;//skip space
@@ -115,26 +191,53 @@
                         break;//check equal
                     }
                     p++;
+                    //skip space
                     p=NyLPC_cFormatTextReader_seekSpace(p)+p;//skip space
                     switch(i){
-                    case 0:
-                        if(NyLPC_cFormatTextReader_readMacAddr(p,v)!=0){
-                            this->setEmac(v[0],v[1],v[2],v[3],v[4],v[5]);
+                    case 0://macaddr
+                        if(NyLPC_cFormatTextReader_readMacAddr(p,v.u8)!=0){
+                            this->setEmac(v.u8[0],v.u8[1],v.u8[2],v.u8[3],v.u8[4],v.u8[5]);
                         }
                         break;
-                    case 1:
-                        if(NyLPC_cFormatTextReader_readIpAddr(p,v)!=0){
-                            this->setIpAddr(v[0],v[1],v[2],v[3]);
+                    case 1://ipaddr
+                        if(NyLPC_cFormatTextReader_readIpAddr(p,v.u8)!=0){
+                            this->setIpAddr(v.u8[0],v.u8[1],v.u8[2],v.u8[3]);
+                            this->setZeroconf(false);
+                        }else{
+                            if(NyLPC_cFormatTextReader_readWord(p,&t)==4){
+                                if(NyLPC_strnicmp(t,"auto",4)==0){
+                                    this->setZeroconf(true);
+                                }
+                            }
                         }
                         break;
                     case 2:
-                        if(NyLPC_cFormatTextReader_readIpAddr(p,v)!=0){
-                            this->setNetMask(v[0],v[1],v[2],v[3]);
+                        if(NyLPC_cFormatTextReader_readIpAddr(p,v.u8)!=0){
+                            this->setNetMask(v.u8[0],v.u8[1],v.u8[2],v.u8[3]);
                         }
                         break;
                     case 3:
-                        if(NyLPC_cFormatTextReader_readIpAddr(p,v)!=0){
-                            this->setGateway(v[0],v[1],v[2],v[3]);
+                        if(NyLPC_cFormatTextReader_readIpAddr(p,v.u8)!=0){
+                            this->setGateway(v.u8[0],v.u8[1],v.u8[2],v.u8[3]);
+                        }
+                        break;
+                    case 4:
+                        if(NyLPC_cFormatTextReader_readUInt(p,&(v.u32))!=0){
+                            this->setSrvHttpPort((unsigned short)v.u32);
+                        }
+                        break;
+                    case 5:
+                        l=NyLPC_cFormatTextReader_readWord(p,&t);
+                        if((*t=='y' || *t=='Y')){
+                            this->setSrvMdns(true);
+                        }else if((*t=='n' || *t=='N')){
+                            this->setSrvMdns(false);
+                        }
+                        break;
+                    case 6:
+                        l=NyLPC_cFormatTextReader_readWord(p,&t);
+                        if(l>1){
+                            this->setHostName(t,l);
                         }
                         break;
                     default:
@@ -145,6 +248,5 @@
         }
         fclose(fp);
         return true;
-    }   
-
+    }
 };
\ No newline at end of file
--- a/mbed/NetConfig.h	Thu May 16 16:06:46 2013 +0000
+++ b/mbed/NetConfig.h	Wed Jun 19 09:33:01 2013 +0000
@@ -5,6 +5,8 @@
 
 #include "NyLPC_net.h"
 
+
+
 namespace MiMic
 {
     /**
@@ -13,7 +15,12 @@
      */
     class NetConfig
     {
+    private:
+        /**service record*/
+        struct NyLPC_TMDnsServiceRecord _srv_record;
     public:
+        /** dns record*/
+        struct NyLPC_TDnsRecord _dns_record;
         NyLPC_TcNetConfig_t _inst;
     public:
         /**
@@ -27,7 +34,7 @@
          * </ul>
          */
         NetConfig(bool i_is_factory_default=false);
-        virtual ~NetConfig();
+        virtual ~NetConfig();        
         /**
          * Set IPv4 ip address to instance.
          */
@@ -42,29 +49,68 @@
          */
         void setGateway(unsigned char ip4,unsigned char ip3,unsigned char ip2,unsigned char ip1);
         /**
+         * Set Zero configuration enable flag.
+         * @param v
+         * True, Zero configuration mode. The mimic will try DHCP and AutoIP configuration.
+         * ipaddress,netmask,gateway are ignored.
+         * False, Manual mode. The mimic will set ip address from on chip data.
+         */
+        void setZeroconf(bool v);
+        /**
+         * This function set a recommended HTTP port number to the application.
+         */
+        void setSrvHttpPort(unsigned short port);
+        /**
+         * Set mDNS operation flag.
+         * This function recommends to the application to provide mDNS service to network.
+         */
+        void setSrvMdns(bool i_enable);
+        void setHostName(const char* i_hostname);
+        void setHostName(const char* i_hostname,int len);
+        /**
          * Set ethernet mac address to instance.
          */
         void setEmac(unsigned char ip6,unsigned char ip5,unsigned char ip4,unsigned char ip3,unsigned char ip2,unsigned char ip1);
+        
         /**
          * Load configulation from text file.
          * <p>File format example
          * <pre>
          * macaddr=00:00:00:00:00:00
+         * host=MiMic01
          * ipaddr=192.168.0.1
          * netmask=255.255.255.0
          * gateway=192.168.0.254
+         * srv_http_port=80
+         * srv_mdns=yes
          * </pre>
          * <p>Keys
          * <ul>
          * <li>macaddr=[:macaddr:] - 48bit ethernet mac address that are separated by ':'</li>
-         * <li>ipaddr=[:ip:] - 32 bit IP address</li>
+         * <li>ipaddr=[:ip:] || AUTO
+         * - 32 bit IP address or auto detection. AUTO will be to try DHCP and AUTOIP.
+         * </li>
          * <li>netmask=[:ip:]- 32 bit network mask value.</li>
          * <li>gateway=[:ip:] - 32 bit default gateway address.</li>
+         * <li>srv_http_port=[:UINT16:] - 16bit http service port number(not ZERO)</li>
+         * <li>srv_mdns=[yes|no] - mDNS service flag.</li>
+         * </ul>
+         * </p>
+         * <p>Default setting
+         * <ul>
+         * <li>macaddr=02:01:02:03:04:05 (In case of mbed it is preset value.)
+         * <li>host=MiMic020102030405
+         * <li>ipaddr =192.168.0.39
+         * <li>netmask=255.255.255.0
+         * <li>gateway=192.168.0.254
+         * <li>srv_http_port=80
+         * <li>srv_mdns=yes</li>
          * </ul>
          * </p>
          * Maximum line length is 31.
          * Specified values are override on-chip setting value.
          * If the same value appeared, then the last one is enabled.
+         * In case of ipaddr=AUTO, gateway and netmask are ignored.
          * </p>
          * @return
          * true if file read. false is not read.