Ryo Iizuka / libMiMic

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

Revision:
20:3b0b444b4deb
Parent:
12:efe841863fc8
Child:
37:fc4b4fd6a649
--- a/core/uip/NyLPC_cTcpSocket.c	Sat Apr 27 13:31:57 2013 +0000
+++ b/core/uip/NyLPC_cTcpSocket.c	Sun Apr 28 08:54:44 2013 +0000
@@ -420,8 +420,6 @@
 }
 
 
-
-
 /**
  * 再送信処理をセットして、パケットを送信します。
  * この関数は「アンロック状態で」実行してください。
@@ -442,10 +440,18 @@
     NyLPC_TUInt16 s;
     void* buf;
     NyLPC_TUInt32 next_ack;
-
-
     //送信バッファを取得
-    buf=NyLPC_cUipService_allocTxBuf(i_len+(SIZE_OF_IPv4_TCPIP_HEADER),&s);
+    //@bug バッファが取れるまで通信がブロックするの。ここはなんとかしないと。
+    for(;;){
+        buf=NyLPC_cUipService_allocTxBuf(i_len+(SIZE_OF_IPv4_TCPIP_HEADER),&s);
+        if(buf!=NULL){
+            break;
+        }
+        //タイムアウト確認
+        if(NyLPC_cStopwatch_isExpired(i_timer)){
+            return -1;
+        }
+    };
     NyLPC_cMutex_lock(&(i_inst->_smutex));
     //ペイロードがある場合のみ、相手のwindowサイズが0以上になるのを待つ。
     if(i_len>0){
@@ -518,8 +524,10 @@
     NyLPC_cIPv4Payload_initialize(&ipv4);
 
     //IPヘッダ+10バイトくらい。
-    buf=NyLPC_cUipService_allocTxBuf((SIZE_OF_IPv4_TCPIP_HEADER)+5,&s);
-
+    //@bug バッファが取れるまで通信がブロックするの。ここはなんとかしないと。
+    do{
+        buf=NyLPC_cUipService_allocTxBuf((SIZE_OF_IPv4_TCPIP_HEADER)+5,&s);
+    }while(buf==NULL);
     NyLPC_cMutex_lock(&(i_inst->_smutex));
     NyLPC_cIPv4Payload_setTxBuf(&ipv4,buf);
     i_inst->uip_connr.snd_nxt32++;
@@ -683,7 +691,10 @@
     NyLPC_cIPv4Payload_initialize(&ipv4payload);
 
     //ACK送信バッファの取得
-    buf=NyLPC_cUipService_allocTxBuf((SIZE_OF_IPv4_TCPIP_HEADER)+5,&s);
+    //@bug バッファが取れるまで通信がブロックするの。ここはなんとかしないと。
+    do{
+        buf=NyLPC_cUipService_allocTxBuf((SIZE_OF_IPv4_TCPIP_HEADER)+5,&s);
+    }while(buf==NULL);
 
     //MUTEX LOCK
     NyLPC_cMutex_lock(&(i_inst->_smutex));
@@ -714,14 +725,26 @@
     NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec);
 
     //送信バッファを取得
-    buf=NyLPC_cUipService_allocTxBuf(i_hint+(SIZE_OF_IPv4_TCPIP_HEADER),&s);
+    //@bug バッファが取れるまで通信がブロックするの。ここはなんとかしないと。
+    for(;;){
+        //ESTABLISHED以外に非同期遷移 orタイムアウト確認
+        if(NyLPC_cStopwatch_isExpired(&sw)||(i_inst->tcpstateflags!=UIP_ESTABLISHED)){
+            return NULL;
+        }
+        buf=NyLPC_cUipService_allocTxBuf(i_hint+(SIZE_OF_IPv4_TCPIP_HEADER),&s);
+        if(buf!=NULL){
+            break;
+        }
+    }
+
 //ここ、要求サイズとpeerのwinのうち、小さいほうを割り当てたほうが良くない?
     NyLPC_cMutex_lock(&(i_inst->_smutex));
     //ペイロードがある場合のみ、相手のwindowサイズが0以上になるのを待つ。
     while(i_inst->uip_connr.peer_win==0){
         NyLPC_cMutex_unlock(&(i_inst->_smutex));
-        //時間切れならエラー。
-        if(NyLPC_cStopwatch_isExpired(&sw)){
+        //ESTABLISHED以外に非同期遷移 orタイムアウト確認
+        if(NyLPC_cStopwatch_isExpired(&sw)||(i_inst->tcpstateflags!=UIP_ESTABLISHED)){
+            NyLPC_cUipService_releaseTxBuf(buf);
             NyLPC_cStopwatch_finalize(&sw);
             return NULL;
         }
@@ -766,14 +789,14 @@
     struct NyLPC_TcTcpSocket_TxQItem* txq;
     void* buf;
     NyLPC_TcStopwatch_t sw;
-
     //ESTABLISHEDでなければエラー
     if(i_inst->tcpstateflags!=UIP_ESTABLISHED){
         //ESTABLISHEDでなければエラー
         return NyLPC_TBool_FALSE;
     }
-    //送信データ0ならエラー
+    //送信データ0なら何もしない。
     if(i_len<1){
+        NyLPC_cTcpSocket_releaseSendBuf(i_inst,i_buf_ptr);
         return NyLPC_TBool_TRUE;
     }
     NyLPC_cStopwatch_initialize(&sw);
@@ -819,26 +842,26 @@
 /**
  * See header file.
  */
-NyLPC_TInt16 NyLPC_cTcpSocket_send(NyLPC_TcTcpSocket_t* i_inst,const void* i_buf_ptr,int i_len,NyLPC_TUInt32 i_wait_in_msec)
+NyLPC_TInt32 NyLPC_cTcpSocket_send(NyLPC_TcTcpSocket_t* i_inst,const void* i_buf_ptr,NyLPC_TInt32 i_len,NyLPC_TUInt32 i_wait_in_msec)
 {
-    NyLPC_TUInt32 sq;
-    NyLPC_TInt32 r;
-    NyLPC_TcStopwatch_t sw;
-    //ESTABLISHEDでなければエラー
-    if(i_inst->tcpstateflags!=UIP_ESTABLISHED){
-        //ESTABLISHEDでなければエラー
-        return -1;
-    }
+    NyLPC_TInt16 hint;
+    NyLPC_TUInt16 s;
+    void* buf;
     if(i_len<1){
         return 0;
     }
-    NyLPC_cStopwatch_initialize(&sw);
-    NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec);
-    //PSHACKを送信する。
-    r=sendWithRetransmit(i_inst,TCP_PSH|TCP_ACK,i_buf_ptr,i_len,&sw,&sq);
-    NyLPC_cStopwatch_finalize(&sw);
-    //失敗時も何もしない?強制CLOSEしなくて平気?
-    return r;
+    hint=(i_len>32767)?32767:0;
+    buf=NyLPC_cTcpSocket_allocSendBuf(i_inst,hint,&s,i_wait_in_msec);
+    if(buf==NULL){
+        return -1;
+    }
+    //送信サイズの計算
+    s=((NyLPC_TInt32)s<i_len)?s:(NyLPC_TUInt16)i_len;
+    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 s;
 }
 
 
@@ -1186,3 +1209,8 @@
     return NyLPC_TBool_FALSE;
 }
 
+
+
+
+
+