OSDN Git Service

TCP_SENDバグ修正
authornyatla <nyatla@47198e57-cb75-475f-84c4-a814cd6f29e0>
Fri, 23 Aug 2013 14:52:48 +0000 (14:52 +0000)
committernyatla <nyatla@47198e57-cb75-475f-84c4-a814cd6f29e0>
Fri, 23 Aug 2013 14:52:48 +0000 (14:52 +0000)
NyLPC_cTcp_connectの追加
peer_mss上書き不具合修正

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

lib/src/uip/NyLPC_cBaseSocket.h
lib/src/uip/NyLPC_cIPv4.c
lib/src/uip/NyLPC_cIPv4.h
lib/src/uip/NyLPC_cTcpSocket.c
lib/src/uip/NyLPC_cTcpSocket.h
lib/src/uip/NyLPC_cUipService.c
lib/src/uip/NyLPC_uip.c
lib/src/uip/NyLPC_uip.h

index c80994b..01a3c90 100644 (file)
@@ -30,6 +30,7 @@ extern "C" {
 #endif /* __cplusplus */\r
 \r
 #include "NyLPC_stdlib.h"\r
+#include "NyLPC_cIPv4_typedef.h"\r
 \r
 /**\r
  * Base socket class\r
@@ -44,9 +45,13 @@ typedef struct NyLPC_TcBaseSocket NyLPC_TcBaseSocket_t;
 struct NyLPC_TcBaseSocket\r
 {\r
        /**タイプID 継承クラスのinitializerで設定。 */\r
-       NyLPC_TUInt32 _typeid;\r
+       NyLPC_TUInt8 _typeid;\r
+       NyLPC_TUInt8 _padding8;\r
+       NyLPC_TUInt16 _padding16;\r
+       /** 所属してるIPv4コンローラ*/\r
+       NyLPC_TcIPv4_t* _parent_ipv4;\r
 };\r
-#define NyLPC_cBaseSocket_initialize(i_inst,i_typeid) ((i_inst)->_typeid=i_typeid)\r
+void NyLPC_cBaseSocket_initialize(NyLPC_TcBaseSocket_t* i_inst,NyLPC_TUInt8 i_typeid);\r
 #define NyLPC_cBaseSocket_finalize(i_inst)\r
 \r
 \r
index dcb22a9..fd0f7c3 100644 (file)
@@ -170,7 +170,40 @@ static NyLPC_TcTcpListener_t* cSocketTbl_getListenerByPeerPort(NyLPC_TcPtrTbl_t*
        }\r
        return NULL;\r
 }\r
-\r
+/**\r
+ * 指定番号のTCPポートが未使用かを返す。\r
+ * @return\r
+ * i_lport番のポートが未使用であればTRUE\r
+ */\r
+static NyLPC_TBool cSocketTbl_isClosedTcpPort(\r
+       NyLPC_TcPtrTbl_t* i_inst,\r
+       NyLPC_TUInt16 i_lport)\r
+{\r
+       NyLPC_TcBaseSocket_t** p=(NyLPC_TcBaseSocket_t**)(i_inst->buf);\r
+       NyLPC_TcTcpSocket_t* tp;\r
+       int i;\r
+       //一致するポートを検索\r
+       for(i=i_inst->size-1;i>=0;i--){\r
+               if(p[i]==NULL){\r
+                       continue;\r
+               }\r
+               if(p[i]->_typeid!=NyLPC_TcBaseSocket_TYPEID_TCP_SOCK){\r
+                       tp=((NyLPC_TcTcpSocket_t*)p[i]);\r
+                       //TCPソケット && !クローズ  && ポート一致なら使用中\r
+                       if((tp->tcpstateflags!=UIP_CLOSED) && tp->uip_connr.lport==i_lport){\r
+                               return NyLPC_TBool_FALSE;\r
+                       }\r
+               }\r
+               if(p[i]->_typeid!=NyLPC_TcBaseSocket_TYPEID_TCP_LISTENER){\r
+                       //Listenerソケット  && ポート一致なら使用中\r
+                       if(((NyLPC_TcTcpListener_t*)p[i])->_port==i_lport){\r
+                               return NyLPC_TBool_FALSE;\r
+                       }\r
+               }\r
+       }\r
+       //未使用\r
+       return NyLPC_TBool_TRUE;\r
+}\r
 /**\r
  * テーブルにある有効なソケットのperiodicをすべて呼び出します。\r
  */\r
@@ -273,6 +306,7 @@ void NyLPC_cIPv4_initialize(
        //instanceの初期化\r
        NyLPC_cMutex_initialize(&(i_inst->_sock_mutex));\r
        NyLPC_cMutex_initialize(&(i_inst->_listener_mutex));\r
+       i_inst->tcp_port_counter=0;\r
        i_inst->_ref_config=NULL;\r
        return;\r
 }\r
@@ -399,10 +433,24 @@ ERROR_DROP:
        return NyLPC_TBool_FALSE;\r
 }\r
 \r
+NyLPC_TUInt16 NyLPC_cIPv4_getNewPortNumber(NyLPC_TcIPv4_t* i_inst)\r
+{\r
+       NyLPC_TUInt16 i,n;\r
+       for(i=0;i<0x0fff;i--){\r
+               i_inst->tcp_port_counter=(i_inst->tcp_port_counter+1)%0x0fff;\r
+               n=i_inst->tcp_port_counter+49152;\r
+               if(cSocketTbl_isClosedTcpPort(&i_inst->_socket_tbl,n))\r
+               {\r
+                       return n;\r
+               }\r
+       }\r
+       return 0;\r
+}\r
+\r
 \r
 /**********************************************************************\r
  *\r
- * public function\r
+ * packet handler\r
  *\r
  **********************************************************************/\r
 \r
index 69cf245..b9d1b5a 100644 (file)
@@ -71,24 +71,14 @@ extern "C" {
 #endif /* __cplusplus */\r
 \r
 \r
-/**\r
- * クラス型を定義します。\r
- * NyLPC_cIPv4クラスは、NyLPC_cUipServiceクラスの一部として働きます。\r
- * 通常ユーザが操作することはありません。\r
- * IPv4における、ソケットクラス(NyLPC_cTcpSocketとNyLPC_cTcpListener)の管理を担当します。\r
- * クラスのインスタンスは、NyLPC_cUipServiceのインスタンスにより生成されます。\r
- * インスタンスは2つのポインタリストをもち、ここにこれらのインスタンスを登録します。\r
- * インスタンスは、NyLPC_cUipServiceから送られてきた受信パケットを、登録されているソケットクラスに\r
- * ディスパッチする機能を持ちます。\r
- */\r
-typedef struct NyLPC_TcIPv4 NyLPC_TcIPv4_t;\r
+\r
 \r
 /**********************************************************************\r
  *\r
  * class NyLPC_TcIPv4\r
  *\r
  **********************************************************************/\r
-\r
+#include "NyLPC_cIPv4_typedef.h"\r
 \r
 ///**\r
 // * 環境定数です。NyLPC_TcTcpListenerインスタンスリストの数を設定します。\r
@@ -119,6 +109,8 @@ struct NyLPC_TcIPv4
        NyLPC_TcPtrTbl_t _socket_tbl;\r
        /** _socket_tblが使用するメモリ領域です。*/\r
        NyLPC_TcBaseSocket_t* _socket_array_buf[NyLPC_cIPv4_MAX_SOCKET];\r
+       /** 0-0xfffまでを巡回するカウンタ*/\r
+       NyLPC_TUInt16 tcp_port_counter;\r
 };\r
 \r
 /**\r
@@ -225,6 +217,15 @@ void NyLPC_cIPv4_periodec(NyLPC_TcIPv4_t* i_inst);
  */\r
 #define NyLPC_cIPv4_getListenerMutex(i_inst) (&((i_inst)->_listener_mutex))\r
 \r
+/**\r
+ * ポート0で使用するポート番号を返します。\r
+ * @return\r
+ * 49152 - (49152+0x0ffff)番までのポートのうち、使用中でないポート番号を返します。\r
+ * エラー時は0です。\r
+ */\r
+NyLPC_TUInt16 NyLPC_cIPv4_getNewPortNumber(NyLPC_TcIPv4_t* i_inst);\r
+\r
+\r
 #ifdef __cplusplus\r
 }\r
 #endif /* __cplusplus */\r
index e849ac2..15c33a2 100644 (file)
 static NyLPC_TUInt32 iss32=3939;\r
 #define SIZE_OF_IPv4_TCPIP_HEADER 40\r
 \r
+/**\r
+ * TCPのRTOの最大値。\r
+ * ms単位である。\r
+ * defaultは64SEC\r
+ */\r
+#define UIP_IP_RTO_MAX_RTO 64000\r
+/**\r
+ * TCPのRTOの初期値。\r
+ * ms単位である。\r
+ * 伝送路の特性に合わせて調整すること。\r
+ */\r
+#define UIP_TCP_RTO_INITIAL 3000\r
+\r
+/**\r
+ * CONNECTION時のRTO\r
+ */\r
+#define UIP_TCP_RTO_CONNECTION_INITIAL 200\r
+\r
+/**\r
+ * 下限値\r
+ */\r
+#define UIP_TCP_RTO_MINIMUM 100\r
+\r
 \r
 /**\r
  * for Debug\r
@@ -225,8 +248,8 @@ static void estimateRTO(NyLPC_TcTcpSocket_t* i_inst,int s,int n)
                break;\r
        }\r
        NyLPC_cStopwatch_finalize(&sw);\r
-       if(new_rto<UIP_IP_RTO_MINIMUM){\r
-               new_rto=UIP_IP_RTO_MINIMUM;\r
+       if(new_rto<UIP_TCP_RTO_MINIMUM){\r
+               new_rto=UIP_TCP_RTO_MINIMUM;\r
        }\r
        i_inst->uip_connr.current_rto32=new_rto;\r
 }\r
@@ -356,7 +379,7 @@ NyLPC_TBool NyLPC_cTcpSocket_listenSyn(NyLPC_TcTcpSocket_t* i_inst,const struct
        {\r
                //localipとdefault_mmsは別枠で設定\r
                /* Fill in the necessary fields for the new connection. */\r
-               i_inst->uip_connr.current_rto32 = UIP_IP_RTOP_INITIAL;\r
+               i_inst->uip_connr.current_rto32 = UIP_TCP_RTO_INITIAL;\r
                i_inst->uip_connr.lport = i_lport;\r
                i_inst->uip_connr.rport = i_lq->rport;\r
                i_inst->uip_connr.ripaddr=i_lq->srcaddr;\r
@@ -364,20 +387,17 @@ NyLPC_TBool NyLPC_cTcpSocket_listenSyn(NyLPC_TcTcpSocket_t* i_inst,const struct
                /* rcv_nxt should be the seqno from the incoming packet + 1. */\r
                i_inst->uip_connr.rcv_nxt32= i_lq->rcv_nxt32;\r
                //MSSの設定\r
-               i_inst->uip_connr.peer_mss=i_inst->uip_connr.default_mss;\r
-               if(i_lq->mss!=0){\r
-                       i_inst->uip_connr.peer_mss=i_lq->mss;\r
-               }\r
+               i_inst->uip_connr.peer_mss=(i_lq->mss!=0)?i_lq->mss:i_inst->uip_connr.default_mss;\r
                i_inst->uip_connr.peer_win=0;\r
                NyLPC_cFifoBuffer_clear(&(i_inst->rxbuf));\r
+               //ここでステータスがかわる。\r
+               i_inst->tcpstateflags = UIP_SYN_RCVD;\r
                //前回のデータが残っていた場合の保険\r
                if(i_inst->txbuf.rp!=i_inst->txbuf.wp){\r
                        resetTxQWithUnlock(i_inst);\r
                }else{\r
                        unlockResource(i_inst);\r
                }\r
-               //ここでステータスがかわる。\r
-               i_inst->tcpstateflags = UIP_SYN_RCVD;\r
                return NyLPC_TBool_TRUE;\r
        }\r
        unlockResource(i_inst);\r
@@ -561,6 +581,7 @@ static NyLPC_TBool addRecvData(NyLPC_TcTcpSocket_t* i_inst,void* i_data,NyLPC_TU
                //エラー:ドロップする。\r
                return NyLPC_TBool_FALSE;\r
        }\r
+\r
        return NyLPC_TBool_TRUE;\r
 }\r
 \r
@@ -571,6 +592,77 @@ static NyLPC_TBool addRecvData(NyLPC_TcTcpSocket_t* i_inst,void* i_data,NyLPC_TU
  * Public function\r
  */\r
 \r
+NyLPC_TBool NyLPC_cTcpSocket_connect(NyLPC_TcTcpSocket_t* i_inst,struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_peer_port,NyLPC_TUInt32 i_wait_in_msec)\r
+{\r
+       volatile NyLPC_TUInt8 f;\r
+       NyLPC_TUInt32 sq;\r
+       NyLPC_TcStopwatch_t sw;\r
+       NyLPC_TUInt16 lport;\r
+       lockResource(i_inst);\r
+       //ソケットが無効であること。\r
+       if(i_inst->tcpstateflags!=UIP_CLOSED)\r
+       {\r
+               NyLPC_OnErrorGoto(Error);\r
+       }\r
+       //ポート番号の取得(lockResourceが他のソケットと共有なので、重複ポートの割当は起こりえない。でもちょっと注意して)\r
+       lport=NyLPC_htons(NyLPC_cIPv4_getNewPortNumber(i_inst->_super._parent_ipv4));\r
+       if(lport==0){\r
+               NyLPC_OnErrorGoto(Error);\r
+       }\r
+       //connectの為の準備\r
+\r
+       //localipとdefault_mmsは別枠で設定\r
+       /* Fill in the necessary fields for the new connection. */\r
+       i_inst->uip_connr.current_rto32 = UIP_TCP_RTO_CONNECTION_INITIAL;//RTOを短くしてARP発行時の再接続短縮を期待する。\r
+       i_inst->uip_connr.lport = lport;\r
+       i_inst->uip_connr.rport = NyLPC_htons(i_peer_port);\r
+       i_inst->uip_connr.ripaddr=*i_addr;\r
+       i_inst->uip_connr.snd_nxt32=iss32;//should be random\r
+       /* rcv_nxt should be the seqno from the incoming packet + 1. */\r
+       i_inst->uip_connr.rcv_nxt32=0;\r
+       //MSSの設定\r
+       i_inst->uip_connr.peer_mss=i_inst->uip_connr.default_mss;\r
+       i_inst->uip_connr.peer_win=1;//periodicの再送信を期待するために相手のWindowサイズは1と仮定する。\r
+       NyLPC_cFifoBuffer_clear(&(i_inst->rxbuf));\r
+       //ここでステータスがかわる。\r
+       i_inst->tcpstateflags = UIP_SYN_SENT;\r
+       //前回のデータが残っていた場合の保険\r
+       if(i_inst->txbuf.rp!=i_inst->txbuf.wp){\r
+               resetTxQWithUnlock(i_inst);\r
+       }else{\r
+               unlockResource(i_inst);\r
+       }\r
+\r
+       NyLPC_cStopwatch_initialize(&sw);\r
+\r
+       NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec);\r
+       if(sendWithRetransmit(i_inst,TCP_SYN,NULL,0,&sw,&sq)==0){\r
+               //ちょっと待つ。\r
+               NyLPC_cThread_yield();\r
+               //キューにあるTXが消えるのを待つ。\r
+               if(waitForTxRemove(i_inst,sq,&sw)){\r
+                       //ACK受信に成功して、TXが消失\r
+                       NyLPC_cStopwatch_finalize(&sw);\r
+                       return NyLPC_TBool_TRUE;\r
+               }\r
+       }\r
+       //ロックして、強制的なステータス遷移\r
+       lockResource(i_inst);\r
+       f=i_inst->tcpstateflags;\r
+       if(f!=UIP_CLOSED){\r
+               //もし、強制CLOSE遷移であれば、RSTも送信。\r
+               i_inst->tcpstateflags=UIP_CLOSED;\r
+               unlockResource(i_inst);\r
+               sendRst(i_inst);\r
+       }else{\r
+               unlockResource(i_inst);\r
+       }\r
+       return NyLPC_TBool_FALSE;\r
+Error:\r
+       unlockResource(i_inst);\r
+       return NyLPC_TBool_FALSE;\r
+}\r
+\r
 /**\r
  * この関数は、UIP_SYN_RCVDステータスのソケットを、ESTABLISHEDへ遷移させます。\r
  * cTcpListener_listen関数を通過したインスタンスに実行してください。\r
@@ -612,12 +704,12 @@ NyLPC_TBool NyLPC_cTcpSocket_accept(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_
        lockResource(i_inst);\r
        f=i_inst->tcpstateflags;\r
        if(f!=UIP_CLOSED){\r
+               //もし、強制CLOSE遷移であれば、RSTも送信。\r
                i_inst->tcpstateflags=UIP_CLOSED;\r
-       }\r
-       unlockResource(i_inst);\r
-       //もし、強制CLOSE遷移であれば、RSTも送信。\r
-       if(f!=UIP_CLOSED){\r
+               unlockResource(i_inst);\r
                sendRst(i_inst);\r
+       }else{\r
+               unlockResource(i_inst);\r
        }\r
        return NyLPC_TBool_FALSE;\r
 }\r
@@ -861,7 +953,7 @@ NyLPC_TInt32 NyLPC_cTcpSocket_send(NyLPC_TcTcpSocket_t* i_inst,const void* i_buf
        if(i_len<1){\r
                return 0;\r
        }\r
-       hint=(i_len>32767)?32767:0;\r
+       hint=(i_len>32767)?32767:i_len;\r
        buf=NyLPC_cTcpSocket_allocSendBuf(i_inst,hint,&s,i_wait_in_msec);\r
        if(buf==NULL){\r
                return -1;\r
@@ -967,12 +1059,12 @@ void NyLPC_cTcpSocket_close(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_wait_in_
        lockResource(i_inst);\r
        f=i_inst->tcpstateflags;\r
        if(f!=UIP_CLOSED){\r
+               //もし、強制CLOSE遷移であれば、RSTも送信。\r
                i_inst->tcpstateflags=UIP_CLOSED;\r
-       }\r
-       unlockResource(i_inst);\r
-       //もし、強制CLOSE遷移であれば、RSTも送信。\r
-       if(f!=UIP_CLOSED){\r
+               unlockResource(i_inst);\r
                sendRst(i_inst);\r
+       }else{\r
+               unlockResource(i_inst);\r
        }\r
        NyLPC_cStopwatch_finalize(&sw);\r
        return;\r
@@ -1149,8 +1241,8 @@ NyLPC_TBool NyLPC_cTcpSocket_parseRx(
                                }\r
                        }\r
                }\r
-               //MSSとWNDの更新\r
-               i_inst->uip_connr.peer_mss = i_inst->uip_connr.default_mss;\r
+//             //MSSとWNDの更新\r
+//             i_inst->uip_connr.peer_mss = i_inst->uip_connr.default_mss;//@bug じゃないのこれ。peer_mss勝手に上書きしたらダメだろ\r
                //どちらにしろ、ACK送信\r
                if(is_new_packet && (in_tcpflag & TCP_FIN)){\r
                        //FINがあるときは、ステータスをCLOSE_WAITへセットして、ACKを返す。\r
@@ -1200,10 +1292,21 @@ NyLPC_TBool NyLPC_cTcpSocket_parseRx(
                break;\r
        case UIP_CLOSED:\r
                //何もできない。何もしない。\r
-               break;//goto DROP;\r
+               break;\r
        case UIP_TIME_WAIT:\r
                //最終ACKを送り続ける。\r
                break;\r
+       case UIP_SYN_SENT:\r
+               //connect関数実行中しか起動しないステータス\r
+               if(num_of_noack==0){\r
+                       i_inst->tcpstateflags=UIP_ESTABLISHED;\r
+                       i_inst->uip_connr.rcv_nxt32=NyLPC_ntohl(o_ipp->payload.tcp->seqno32)+1;\r
+               }else{\r
+                       //それ以外のパケットはドロップする。\r
+                       break;//goto DROP;\r
+               }\r
+               //ACKを送る。\r
+               break;\r
        default:\r
                goto DROP;\r
        }\r
index e133df7..33e1a58 100644 (file)
@@ -206,6 +206,9 @@ void NyLPC_cTcpSocket_releaseSendBuf(NyLPC_TcTcpSocket_t* i_inst,void* i_buf_ptr
 NyLPC_TBool NyLPC_cTcpSocket_psend(NyLPC_TcTcpSocket_t* i_inst,void* i_buf_ptr,int i_len,NyLPC_TUInt32 i_wait_in_msec);\r
 \r
 \r
+NyLPC_TBool NyLPC_cTcpSocket_connect(NyLPC_TcTcpSocket_t* i_inst,struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_peer_port,NyLPC_TUInt32 i_wait_in_msec);\r
+\r
+\r
 #ifdef __cplusplus\r
 }\r
 #endif /* __cplusplus */\r
index 8f7a76f..0b47369 100644 (file)
@@ -95,7 +95,7 @@ struct TEthPacket
                struct NyLPC_TArpHeader arp;\r
                struct NyLPC_TIPv4Header ipv4;\r
        }data;\r
-};\r
+}PACK_STRUCT_END;\r
 \r
 \r
 \r
@@ -122,7 +122,7 @@ static int uipTask(void *pvParameters);
 \r
 static NyLPC_TBool sendIPv4Tx(struct NyLPC_TTxBufferHeader* i_eth_buf);\r
 static void copyAndSendIPv4Tx(const struct TEthPacket* i_buf);\r
-static void sendArpReqest(const struct TEthPacket* i_eth_packet);\r
+//static void sendArpReqest(const struct TEthPacket* i_eth_packet);\r
 static void sendRawEthFrame(void* i_buf,NyLPC_TUInt16 i_len);\r
 static void emacIsrHandler(unsigned long i_status);\r
 \r
@@ -395,10 +395,31 @@ static int uipTask(void *pvParameters)
 }\r
 \r
 \r
+/**\r
+ * IPv4パケットのpeerIPを問い合わせるARPパケットを送信します。\r
+ */\r
+static void sendArpReqest(const struct NyLPC_TIPv4Addr* i_addr)\r
+{\r
+       NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;\r
+       NyLPC_TUInt16 tx_len;\r
+       struct TEthPacket* ethbuf;\r
+       //ACK送信用の自己バッファが空くまで待つ\r
+       while(inst->stx.h.is_lock){\r
+               inst->_ethif->processTx();\r
+       }\r
+       //ARPパケットを作る。\r
+       ethbuf=(struct TEthPacket*)(inst->stx.buf);\r
+       NyLPC_TArpHeader_setArpRequest(&(ethbuf->data.arp),inst->_ref_config->ip_addr,&(inst->_ref_config->eth_mac),i_addr);\r
+       tx_len=NyLPC_TEthernetIIHeader_setArpTx(&(ethbuf->header),&(inst->_ref_config->eth_mac));\r
+       //送信\r
+       inst->_ethif->sendTxEthFrame(&(inst->stx.h),tx_len);\r
+}\r
+\r
+\r
 \r
 \r
 /**\r
- * allocTxBufで取得したメモリを"IPパケットとして"送信します。\r
+ * allocTxBufã\81§å\8f\96å¾\97ã\81\97ã\81\9fã\83\9aã\82¤ã\83­ã\83¼ã\83\89ã\83¡ã\83¢ã\83ªã\82\92"IPã\83\91ã\82±ã\83\83ã\83\88ã\81¨ã\81\97ã\81¦"é\80\81ä¿¡ã\81\97ã\81¾ã\81\99ã\80\82\r
  * @param i_eth_payload\r
  * [NyLPC_TTxBufferHeader][NyLPC_TEthernetIIHeader][payload]メモリの、[payload]のアドレスを指定します。\r
  * 通常は、NyLPC_cUipService_allocTxBufの返却したメモリを指定します。\r
@@ -407,33 +428,29 @@ static int uipTask(void *pvParameters)
 void NyLPC_cUipService_sendIPv4Tx(void* i_eth_payload)\r
 {\r
        NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;\r
+       struct NyLPC_TTxBufferHeader* p=((struct NyLPC_TTxBufferHeader*)(((struct NyLPC_TEthernetIIHeader*)i_eth_payload)-1))-1;\r
        NyLPC_cMutex_lock(&(inst->_mutex));\r
+\r
        //IPパケットの送信を試行\r
-       if(!sendIPv4Tx(((struct NyLPC_TTxBufferHeader*)(((struct NyLPC_TEthernetIIHeader*)i_eth_payload)-1))-1)){\r
+       if(!sendIPv4Tx(p)){\r
                //ARPリクエストを代わりに送信\r
-               sendArpReqest(((struct TEthPacket*)i_eth_payload)-1);\r
+               sendArpReqest(&((struct NyLPC_TIPv4Header*)i_eth_payload)->destipaddr);\r
        }\r
        NyLPC_cMutex_unlock(&(inst->_mutex));\r
        return;\r
 }\r
+\r
+\r
+\r
 /**\r
  * 指定したIPアドレスに対してARPRequestを送信します。\r
  */\r
 void NyLPC_cUipService_sendArpRequest(const struct NyLPC_TIPv4Addr* i_addr)\r
 {\r
        NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;\r
-       NyLPC_TUInt16 tx_len;\r
-       struct TEthPacket* ethbuf;\r
-       //ACK送信用の自己バッファが空くまで待つ\r
-       while(inst->stx.h.is_lock){\r
-               inst->_ethif->processTx();\r
-       }\r
-       //ARPパケットを作る。\r
-       ethbuf=(struct TEthPacket*)(inst->stx.buf);\r
-       NyLPC_TArpHeader_setArpRequest(&(ethbuf->data.arp),inst->_ref_config->ip_addr,&(inst->_ref_config->eth_mac),*i_addr);\r
-       tx_len=NyLPC_TEthernetIIHeader_setArpTx(&(ethbuf->header),&(inst->_ref_config->eth_mac));\r
-       //送信\r
-       inst->_ethif->sendTxEthFrame(&(inst->stx.h),tx_len);\r
+       NyLPC_cMutex_lock(&(inst->_mutex));\r
+       sendArpReqest(i_addr);\r
+       NyLPC_cMutex_unlock(&(inst->_mutex));\r
        return;\r
 }\r
 \r
@@ -447,6 +464,8 @@ NyLPC_TBool NyLPC_cUipService_hasArpInfo(const struct NyLPC_TIPv4Addr* i_addr)
 }\r
 \r
 \r
+\r
+\r
 /**\r
  * 送信ペイロードメモリを返します。\r
  * この関数は、リエントラントを許容します。\r
@@ -500,7 +519,7 @@ void* NyLPC_cUipService_releaseTxBuf(void* i_buf)
  */\r
 \r
 /**\r
- * 新たにメモリを確保して、"IPv4パケットを格納した"イーサフレームを送信します。\r
+ * "IPv4パケットを格納した"イーサフレームを送信します。\r
  * コール前に、必ずロックしてから呼び出してください。\r
  */\r
 static void copyAndSendIPv4Tx(const struct TEthPacket* i_buf)\r
@@ -516,29 +535,13 @@ static void copyAndSendIPv4Tx(const struct TEthPacket* i_buf)
        memcpy(inst->stx.buf,i_buf,s);\r
        if(!sendIPv4Tx(&(inst->stx.h))){\r
                //失敗した場合はARPリクエストに変換して再送\r
-               sendArpReqest(i_buf);\r
+//@todo unchecked PASS!\r
+               sendArpReqest(&i_buf->data.ipv4.destipaddr);\r
        }\r
        return;\r
 }\r
-/**\r
- * IPv4パケットのpeerIPを問い合わせるARPパケットを送信します。\r
- */\r
-static void sendArpReqest(const struct TEthPacket* i_eth_packet)\r
-{\r
-       NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;\r
-       NyLPC_TUInt16 tx_len;\r
-       struct TEthPacket* ethbuf;\r
-       //ACK送信用の自己バッファが空くまで待つ\r
-       while(inst->stx.h.is_lock){\r
-               inst->_ethif->processTx();\r
-       }\r
-       //ARPパケットを作る。\r
-       ethbuf=(struct TEthPacket*)(inst->stx.buf);\r
-       NyLPC_TArpHeader_setArpRequest(&(ethbuf->data.arp),inst->_ref_config->ip_addr,&(inst->_ref_config->eth_mac),i_eth_packet->data.ipv4.destipaddr);\r
-       tx_len=NyLPC_TEthernetIIHeader_setArpTx(&(ethbuf->header),&(inst->_ref_config->eth_mac));\r
-       //送信\r
-       inst->_ethif->sendTxEthFrame(&(inst->stx.h),tx_len);\r
-}\r
+\r
+\r
 \r
 /**\r
  * uipタスクが所有するTXバッファを使用してデータを送信します。\r
@@ -622,36 +625,4 @@ static NyLPC_TBool sendIPv4Tx(struct NyLPC_TTxBufferHeader* i_eth_buf)
 \r
 \r
 \r
-//static void startEther()\r
-//{\r
-//     NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;\r
-//\r
-//     //Ethernetの起動待ち\r
-//     while(lEMACInit(_NyLPC_TcUipService_inst->_emac_semapho,&(inst->_ref_config->eth_mac))!= pdPASS )\r
-//    {\r
-//        vTaskDelay( 100 / portTICK_RATE_MS );\r
-//    }\r
-//     //Ethernetの割込み開始設定\r
-//     portENTER_CRITICAL();\r
-//     {\r
-//             LPC_EMAC->IntEnable = ( INT_RX_DONE | INT_TX_DONE );\r
-//             /* Set the interrupt priority to the max permissible to cause some\r
-//             interrupt nesting. */\r
-//             NVIC_SetPriority( ENET_IRQn, configEMAC_INTERRUPT_PRIORITY );\r
-//\r
-//             /* Enable the interrupt. */\r
-//             NVIC_EnableIRQ( ENET_IRQn );\r
-//     }\r
-//     portEXIT_CRITICAL();\r
-//}\r
-//\r
-//static void stopEther()\r
-//{\r
-//     portENTER_CRITICAL();\r
-//     {\r
-//             LPC_EMAC->IntEnable = (~(INT_RX_DONE|INT_TX_DONE))&LPC_EMAC->IntEnable;\r
-//             NVIC_DisableIRQ( ENET_IRQn );\r
-//     }\r
-//     portEXIT_CRITICAL();\r
-//}\r
 \r
index f60d126..5772b79 100644 (file)
@@ -356,17 +356,17 @@ NyLPC_TUInt16 NyLPC_TTcpHeader_getHeaderLength(const struct NyLPC_TTcpHeader* ip
  *\r
  *------------------------------------------------------------------------------*/\r
 /**\r
- * 指定したIPアドレスに対する、ARP REQUESTをセットする\r
+ * i_req_addrを問い合わせるARP_REQUESTを生成します\r
  */\r
 void NyLPC_TArpHeader_setArpRequest(\r
        struct NyLPC_TArpHeader* i_struct,\r
        const struct NyLPC_TIPv4Addr i_saddr,\r
        const struct NyLPC_TEthAddr* i_srceth,\r
-       const struct NyLPC_TIPv4Addr i_daddr)\r
+       const struct NyLPC_TIPv4Addr* i_req_addr)\r
 {\r
        memset(i_struct->dhwaddr.addr, 0x00, 6);\r
        memcpy(i_struct->shwaddr.addr, i_srceth, 6);\r
-       i_struct->dipaddr=i_daddr;\r
+       i_struct->dipaddr=*i_req_addr;\r
        i_struct->sipaddr=i_saddr;\r
        i_struct->opcode = NyLPC_HTONS(ARP_REQUEST); /* ARP request. */\r
        i_struct->hwtype = NyLPC_HTONS(ARP_HWTYPE_ETH);\r
index 3779ed7..9a6110f 100644 (file)
@@ -139,19 +139,6 @@ NyLPC_TUInt16 NyLPC_uip_chksum(NyLPC_TUInt16 sum, const NyLPC_TUInt8 *data, NyLP
  */\r
 #define UIP_DEFAULT_IP_TTL 64\r
 \r
-/**\r
- * RTOの最大値。ms単位である。\r
- * 64sが標準値である。\r
- */\r
-#define UIP_IP_RTO_MAX_RTO 64000\r
-\r
-/**\r
- * RTOの初期値。ms単位である。\r
- * 伝送路の特性に合わせて調整すること。\r
- */\r
-#define UIP_IP_RTOP_INITIAL 3000\r
-\r
-#define UIP_IP_RTO_MINIMUM 100\r
 \r
 \r
 /**\r
@@ -429,11 +416,14 @@ struct NyLPC_TArpHeader
 } PACK_STRUCT_END;\r
 \r
 \r
+/**\r
+ * i_req_addrを問い合わせるARP_REQUESTを生成します。\r
+ */\r
 void NyLPC_TArpHeader_setArpRequest(\r
        struct NyLPC_TArpHeader* i_struct,\r
        const struct NyLPC_TIPv4Addr i_saddr,\r
        const struct NyLPC_TEthAddr* i_srceth,\r
-       const struct NyLPC_TIPv4Addr i_daddr);\r
+       const struct NyLPC_TIPv4Addr* i_req_addr);\r
 \r
 \r
 typedef struct NyLPC_TcEthernetIIPayload NyLPC_TcEthernetIIPayload_t;\r