OSDN Git Service

UDPソケットにタイマ実行ハンドラ追加
authornyatla <nyatla@47198e57-cb75-475f-84c4-a814cd6f29e0>
Mon, 17 Jun 2013 08:54:39 +0000 (08:54 +0000)
committernyatla <nyatla@47198e57-cb75-475f-84c4-a814cd6f29e0>
Mon, 17 Jun 2013 08:54:39 +0000 (08:54 +0000)
mdnsバグ修正
mdnsの非同期サービスをuipサービスタスク実行に変更

git-svn-id: http://svn.osdn.jp/svnroot/mimic/trunk@262 47198e57-cb75-475f-84c4-a814cd6f29e0

13 files changed:
lib/src/net/NyLPC_cNetConfig.h
lib/src/net/apipa/NyLPC_cApipa.h
lib/src/net/mdns/NyLPC_cMDnsServer.c
lib/src/net/mdns/NyLPC_cMDnsServer.h
lib/src/uip/NyLPC_cIPv4.c
lib/src/uip/NyLPC_cUdpSocket.c
lib/src/uip/NyLPC_cUdpSocket.h
lib/src/uip/NyLPC_cUdpSocket_protected.h
lib/src/uip/NyLPC_cUipService.c
lib/src/uip/NyLPC_cUipService_protected.h
lib/src/utils/NyLPC_cFormatTextReader.c
lib/src/utils/NyLPC_cFormatTextReader.h
projects/example/sample.net.mdns/src/sketch.c

index 737fcf3..e259e03 100644 (file)
@@ -56,13 +56,13 @@ struct NyLPC_TcNetConfig
        /**\r
         * tcp初期設定モードのフラグ値\r
         * NyLPC_TcNetConfig_IPV4_FLAG_Xの組み合わせ\r
+        * bit 01:IP初期設定のモード. 0:Manual指定,1:DHCP指定,2:AutoIP指定,3:APIPA指定\r
         */\r
        NyLPC_TUInt32 tcp_mode;\r
        struct{\r
                /**\r
                 * サービスのフラグセット。\r
                 * NyLPC_TcNetConfig_SERVICE_FLAG_xの組み合わせ\r
-                * bit 01:IP初期設定のモード. 0:Manual指定,1:DHCP指定,2:AutoIP指定,3:APIPA指定\r
                 */\r
                NyLPC_TUInt32 flags;\r
                NyLPC_TUInt16 http_port;\r
index e08264d..53637c3 100644 (file)
  *********************************************************************************/\r
 #ifndef NYLPC_CAPIPA_H_\r
 #define NYLPC_CAPIPA_H_\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif /* __cplusplus */\r
+\r
 #include "NyLPC_stdlib.h"\r
-typedef struct NyLPC_cApipa NyLPC_TcApipa_t;\r
 #include "NyLPC_net.h"\r
 \r
+typedef struct NyLPC_cApipa NyLPC_TcApipa_t;\r
+\r
 struct NyLPC_cApipa\r
 {\r
        NyLPC_TUInt32 _seed;\r
@@ -44,5 +50,7 @@ void NyLPC_cApipa_initialize(NyLPC_TcApipa_t* i_inst);
  */\r
 NyLPC_TBool NyLPC_cApipa_requestAddr(NyLPC_TcApipa_t* i_inst,NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat);\r
 \r
-\r
+#ifdef __cplusplus\r
+}\r
+#endif /* __cplusplus */\r
 #endif /* NYLPC_CAPIPA_H_ */\r
index 5548484..c5ba2ef 100644 (file)
@@ -159,7 +159,7 @@ static NyLPC_TInt16 NyLPC_TDnsQuestion_parse(const void* i_qpacket,NyLPC_TUInt16
        NyLPC_TUInt16 i;\r
        const char* p=(const char*)i_qpacket;\r
        //QNameのパース'0終端'\r
-       l=i_len-4-1;//スキャン長はパケットサイズ-5まで\r
+       l=i_len-4;//スキャン長はパケットサイズ-5まで\r
        for(i=0;i<l;i++){\r
                if(*(p+i)==0){\r
                        l=i+1;//NULL終端を加味した文字列長\r
@@ -654,14 +654,6 @@ static NyLPC_TBool onPacket(NyLPC_TcUdpSocket_t* i_inst,const void* i_buf,const
        if(i_info->peer_port!=MDNS_MCAST_PORT || !NyLPC_TIPv4Addr_isEqual(&MDNS_MCAST_IPADDR,&i_info->ip)){\r
                return NyLPC_TBool_FALSE;\r
        }\r
-       //パケット処理中\r
-       NyLPC_TUInt8_setBit(((NyLPC_TcMDnsServer_t*)i_inst)->_ctrlflag,CTRL_FLAG_PROCESS_PACKET);\r
-\r
-       if(!NyLPC_TUInt8_isBitOn(((NyLPC_TcMDnsServer_t*)i_inst)->_ctrlflag,CTRL_FLAG_STARTED)){\r
-               //停止中なら何もしない\r
-               NyLPC_TUInt8_unsetBit(((NyLPC_TcMDnsServer_t*)i_inst)->_ctrlflag,CTRL_FLAG_PROCESS_PACKET);\r
-               return NyLPC_TBool_FALSE;\r
-       }\r
 \r
        num_of_query=getNumberOfQuestion(i_buf,in_len);\r
        if(num_of_query==0){\r
@@ -680,72 +672,40 @@ static NyLPC_TBool onPacket(NyLPC_TcUdpSocket_t* i_inst,const void* i_buf,const
                sendReply2((NyLPC_TcMDnsServer_t*)i_inst,(const struct NyLPC_TDnsHeader*)i_buf,&q);\r
        }\r
        //パケット処理終了\r
-       NyLPC_TUInt8_unsetBit(((NyLPC_TcMDnsServer_t*)i_inst)->_ctrlflag,CTRL_FLAG_PROCESS_PACKET);\r
        return NyLPC_TBool_FALSE;\r
 DROP:\r
-       NyLPC_TUInt8_unsetBit(((NyLPC_TcMDnsServer_t*)i_inst)->_ctrlflag,CTRL_FLAG_PROCESS_PACKET);\r
        return NyLPC_TBool_FALSE;\r
 }\r
 \r
+static void onPeriodic(NyLPC_TcUdpSocket_t* i_inst)\r
+{\r
 \r
+       if(NyLPC_cStopwatch_isExpired(&((NyLPC_TcMDnsServer_t*)i_inst)->_periodic_sw)){\r
+               //アナウンス\r
+               sendAnnounse(((NyLPC_TcMDnsServer_t*)i_inst));\r
+               //TTL(msec)*1000*80%\r
+               NyLPC_cStopwatch_startExpire((&((NyLPC_TcMDnsServer_t*)i_inst)->_periodic_sw),NyLPC_TcMDns_TTL*5000/4);\r
+       }\r
+}\r
 \r
 NyLPC_TBool NyLPC_cMDnsServer_initialize(\r
        NyLPC_TcMDnsServer_t* i_inst,struct NyLPC_TDnsRecord* i_ref_record)\r
 {\r
+       NyLPC_cStopwatch_initialize(&(i_inst->_periodic_sw));\r
+       NyLPC_cStopwatch_startExpire(&(i_inst->_periodic_sw),1000);\r
        NyLPC_cUdpSocket_initialize(&(i_inst->_super),MDNS_MCAST_PORT,NULL,0);\r
        NyLPC_cUdpSocket_setOnRxHandler(&(i_inst->_super),onPacket);\r
+       NyLPC_cUdpSocket_setOnPerriodicHandler(&(i_inst->_super),onPeriodic);\r
        NyLPC_cUdpSocket_joinMulticast(&(i_inst->_super),&MDNS_MCAST_IPADDR);\r
-       i_inst->_ctrlflag=CTRL_FLAG_INIT;\r
        i_inst->_ref_record=i_ref_record;\r
        return NyLPC_TBool_TRUE;\r
 }\r
 void NyLPC_cMDnsServer_finalize(\r
        NyLPC_TcMDnsServer_t* i_inst)\r
 {\r
-       //起動中なら停止\r
-       if(i_inst->_ctrlflag & CTRL_FLAG_STARTED){\r
-               NyLPC_cMDnsServer_stop(i_inst);\r
-       }\r
        NyLPC_cUdpSocket_finalize(&(i_inst->_super));\r
+       NyLPC_cStopwatch_finalize(&(i_inst->_periodic_sw));\r
 }\r
 \r
-void NyLPC_cMDnsServer_start(NyLPC_TcMDnsServer_t* i_inst)\r
-{\r
-       NyLPC_TcStopwatch_t sw;\r
-       NyLPC_Assert((i_inst->_ctrlflag & CTRL_FLAG_STARTED)==0x0);\r
-       //開始ビットのセット\r
-       NyLPC_TUInt8_setBit(i_inst->_ctrlflag,CTRL_FLAG_STARTED);//開始状態にする。\r
-       sendAnnounse(i_inst);\r
-       NyLPC_cStopwatch_initialize(&sw);\r
-       NyLPC_cStopwatch_startExpire(&sw,NyLPC_TcMDns_TTL*5000/4);\r
-       while(!NyLPC_TUInt8_isBitOn(i_inst->_ctrlflag,CTRL_FLAG_STOP_REQUESTED)){\r
-               //受信処理\r
-               NyLPC_cThread_sleep(100);\r
-               if(NyLPC_cStopwatch_isExpired(&sw)){\r
-                       //アナウンス\r
-                       sendAnnounse(i_inst);\r
-                       NyLPC_cStopwatch_startExpire(&sw,NyLPC_TcMDns_TTL*5000/4);\r
-               }\r
-       }\r
-       //開始ビットのクリア\r
-       NyLPC_TUInt8_unsetBit(i_inst->_ctrlflag,CTRL_FLAG_STARTED);\r
-}\r
-\r
-void NyLPC_cMDnsServer_stop(NyLPC_TcMDnsServer_t* i_inst)\r
-{\r
-       //停止要求ビットのセット\r
-       NyLPC_TUInt8_setBit(i_inst->_ctrlflag,CTRL_FLAG_STOP_REQUESTED);\r
-       while(NyLPC_TUInt8_isBitOn(i_inst->_ctrlflag,CTRL_FLAG_STARTED)){\r
-               NyLPC_cThread_sleep(100);\r
-       }\r
-       //パケット処理終了待ち\r
-       while(NyLPC_TUInt8_isBitOn(i_inst->_ctrlflag,CTRL_FLAG_PROCESS_PACKET)){\r
-               NyLPC_cThread_sleep(100);\r
-       }\r
-\r
-       //停止要求ビットのクリア\r
-       NyLPC_TUInt8_unsetBit(i_inst->_ctrlflag,CTRL_FLAG_STOP_REQUESTED);\r
 \r
 \r
-}\r
-\r
index 9224a6b..491bd34 100644 (file)
@@ -69,13 +69,8 @@ struct NyLPC_TcMDnsServer
 {\r
        /** マルチキャストのUDPソケット*/\r
        NyLPC_TcUdpSocket_t _super;\r
-       /** 動作フラグ\r
-        *  7 - サービス起動中\r
-        *  6 - サービス停止要求\r
-        *  5-0 Reserved\r
-        */\r
-       volatile NyLPC_TUInt8 _ctrlflag;\r
-       /** 受信バッファ*/\r
+       /**周期実行タイマ*/\r
+       NyLPC_TcStopwatch_t _periodic_sw;\r
        /** DNSレコードの参照情報*/\r
        const struct NyLPC_TDnsRecord* _ref_record;\r
 };\r
index 211ca42..bd3058c 100644 (file)
@@ -189,6 +189,9 @@ static void cSocketTbl_callPeriodic(
                        //downcast!\r
                        NyLPC_cTcpSocket_periodic((NyLPC_TcTcpSocket_t*)(p[i]));\r
                        break;\r
+               case NyLPC_TcBaseSocket_TYPEID_UDP_SOCK:\r
+                       NyLPC_cUdpSocket_periodic((NyLPC_TcUdpSocket_t*)(p[i]));\r
+                       break;\r
                default:\r
                        continue;\r
                }\r
index b48fbdb..58f6c18 100644 (file)
@@ -76,7 +76,8 @@ NyLPC_TBool NyLPC_cUdpSocket_initialize(NyLPC_TcUdpSocket_t* i_inst,NyLPC_TUInt1
        i_inst->uip_udp_conn.lport=NyLPC_htons(i_port);\r
        i_inst->uip_udp_conn.mcastaddr=NyLPC_TIPv4Addr_ZERO;\r
        i_inst->uip_udp_conn.flags=0x00;\r
-       i_inst->_handler=NULL;\r
+       i_inst->as_handler.rx=NULL;\r
+       i_inst->as_handler.periodic=NULL;\r
 \r
        NyLPC_cFifoBuffer_initialize(&(i_inst->rxbuf),i_rbuf,i_rbuf_len);\r
        //管理リストへ登録。\r
@@ -134,8 +135,8 @@ NyLPC_TBool NyLPC_cUdpSocket_parseRx(
        dheader.peer_port=NyLPC_ntohs(o_ipp->payload.udp->srcport);\r
        dheader.ip=o_ipp->header->destipaddr;\r
        dheader.port=NyLPC_ntohs(o_ipp->payload.udp->destport);\r
-       if(i_inst->_handler!=NULL){\r
-               if(!i_inst->_handler(i_inst,o_ipp->payload.rawbuf+tmp16,&dheader)){\r
+       if(i_inst->as_handler.rx!=NULL){\r
+               if(!i_inst->as_handler.rx(i_inst,o_ipp->payload.rawbuf+tmp16,&dheader)){\r
                        return NyLPC_TBool_FALSE;//UDPはReturnパケットなし\r
                }\r
        }\r
index 8c6134c..005f24d 100644 (file)
@@ -44,10 +44,16 @@ struct uip_udp_conn{
 \r
 /**\r
  * 受信時に非同期にコールされるハンドラ\r
+ * UIPサービスタスクが実行する。\r
  * @return\r
  * TRUEならパケットを受信キューへ追加する。FALSEならパケットを受信キューへ追加しない。\r
  */\r
 typedef NyLPC_TBool (*NyLPC_TcUdpSocket_onRxHandler)(NyLPC_TcUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info);\r
+/**\r
+ * 非同期にコールされるハンドラ。\r
+ * UIPサービスタスクが実行する。\r
+ */\r
+typedef void (*NyLPC_TcUdpSocket_onPeriodic)(NyLPC_TcUdpSocket_t* i_inst);\r
 \r
 struct NyLPC_TcUdpSocket\r
 {\r
@@ -56,7 +62,12 @@ struct NyLPC_TcUdpSocket
        struct uip_udp_conn uip_udp_conn;\r
        NyLPC_TcFifoBuffer_t rxbuf;\r
        NyLPC_TcMutex_t* _smutex;\r
-       NyLPC_TcUdpSocket_onRxHandler _handler;\r
+       struct{\r
+               /** 受信ハンドラ。サービス実装に使用する。*/\r
+               NyLPC_TcUdpSocket_onRxHandler rx;\r
+               /** 定期実行ハンドラ。サービス実装に使用する。最低保障周期は1s*/\r
+               NyLPC_TcUdpSocket_onPeriodic periodic;\r
+       }as_handler;\r
 };\r
 \r
 \r
@@ -127,7 +138,12 @@ NyLPC_TInt32 NyLPC_cUdpSocket_send(NyLPC_TcUdpSocket_t* i_inst,const struct NyLP
 /**\r
  * 非同期パケットハンドラを設定する。\r
  */\r
-#define NyLPC_cUdpSocket_setOnRxHandler(i_inst,i_handler) (i_inst)->_handler=i_handler;\r
+#define NyLPC_cUdpSocket_setOnRxHandler(i_inst,i_handler) (i_inst)->as_handler.rx=i_handler;\r
+\r
+/**\r
+ * 非同期タイマ呼び出しハンドラを設定する。\r
+ */\r
+#define NyLPC_cUdpSocket_setOnPerriodicHandler(i_inst,i_handler) (i_inst)->as_handler.periodic=i_handler;\r
 \r
 \r
 #ifdef __cplusplus\r
index 4444b92..cb313d8 100644 (file)
@@ -39,6 +39,12 @@ void NyLPC_cUdpSocket_startService(NyLPC_TcUdpSocket_t* i_inst,const NyLPC_TcIPv
 void NyLPC_cUdpSocket_stopService(NyLPC_TcUdpSocket_t* i_inst);\r
 \r
 \r
+/**\r
+ * 定期的に実行する関数。最低でも1s単位で実行してください。\r
+ * uipサービスタスクが実行する関数です。\r
+ */\r
+#define NyLPC_cUdpSocket_periodic(i_inst) if((i_inst)->as_handler.periodic!=NULL){(i_inst)->as_handler.periodic(i_inst);}\r
+\r
 #ifdef __cplusplus\r
 }\r
 #endif /* __cplusplus */\r
index 69052f3..b8a8177 100644 (file)
@@ -405,7 +405,9 @@ static int uipTask(void *pvParameters)
                        NyLPC_cStopwatch_startExpire(&(inst->_arp_sw),ARP_TIMER);\r
                }\r
                if(NyLPC_cStopwatch_isExpired(&(inst->_periodic_sw))){\r
+                       NyLPC_cMutex_unlock(&(inst->_mutex));\r
                        NyLPC_cIPv4_periodec(&(inst->_tcpv4));\r
+                       NyLPC_cMutex_lock(&(inst->_mutex));\r
                        NyLPC_cStopwatch_startExpire(&(inst->_periodic_sw),PERIODIC_TIMER);\r
                }\r
                //リソースロックの解除\r
index fbdebda..283d43d 100644 (file)
@@ -141,8 +141,6 @@ void NyLPC_cUipService_sendArpRequest(const struct NyLPC_TIPv4Addr* i_addr);
 NyLPC_TBool NyLPC_cUipService_hasArpInfo(const struct NyLPC_TIPv4Addr* i_addr);\r
 \r
 \r
-void NyLPC_cTcpSocket_periodic(\r
-       NyLPC_TcTcpSocket_t* i_inst);\r
 \r
 \r
 \r
index 4b1a28c..b8f5c10 100644 (file)
@@ -56,6 +56,23 @@ NyLPC_TInt32 NyLPC_cFormatTextReader_readIpAddr(const NyLPC_TChar* buf,NyLPC_TUI
        return (p-buf);\r
 }\r
 /**\r
+ * 文字列から10進数の数値を読み出します。\r
+ * @return\r
+ * 読み出した文字数\r
+ */\r
+NyLPC_TInt32 NyLPC_cFormatTextReader_readUInt(const NyLPC_TChar* buf,NyLPC_TUInt32* v)\r
+{\r
+       NyLPC_TUInt32 t;\r
+    const NyLPC_TChar* p=buf;\r
+       t=0;\r
+       for(;isdigit(*p);p++){\r
+               t=t*10+NyLPC_ctoi(*p);\r
+       }\r
+       *v=t;\r
+       return (p-buf);\r
+}\r
+\r
+/**\r
  * 文字列からMACアドレスを取得します。\r
  * [:hex:]:[:hex:]:[:hex:]:[:hex:]\r
  */\r
index 54dd313..9de317f 100644 (file)
@@ -38,10 +38,15 @@ NyLPC_TInt32 NyLPC_cFormatTextReader_readMacAddr(const NyLPC_TChar* buf,NyLPC_TU
 \r
 /**\r
  * 連続するスペースを読み飛ばします。\r
+ */\r
+NyLPC_TInt32 NyLPC_cFormatTextReader_seekSpace(const NyLPC_TChar* s);\r
+\r
+/**\r
+ * 文字列から10進数の数値を読み出します。\r
  * @return\r
  * 読み飛ばしたスペース\r
  */\r
-NyLPC_TInt32 NyLPC_cFormatTextReader_seekSpace(const NyLPC_TChar* s);\r
+NyLPC_TInt32 NyLPC_cFormatTextReader_readUInt(const NyLPC_TChar* buf,NyLPC_TUInt32* v);\r
 \r
 #ifdef __cplusplus\r
 }\r
index a148e51..6b913fc 100644 (file)
@@ -42,7 +42,7 @@ void loop(void)
        NyLPC_cNetConfig_setIpAddr(&c2,192,168,128,39);\r
        NyLPC_cNetConfig_setGateway(&c2,192,168,128,254);\r
        NyLPC_cNet_start(&net,&c2);\r
-       NyLPC_cMDnsServer_start(&mdns);\r
+       for(;;);\r
 }\r
 \r
 \r