Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more
Diff: core/uip/NyLPC_cTcpSocket.c
- Revision:
- 57:bc4330dfa62f
- Parent:
- 43:a182f2b5ff41
- Child:
- 58:03b89038b21a
--- a/core/uip/NyLPC_cTcpSocket.c Sat Aug 10 02:52:22 2013 +0000
+++ b/core/uip/NyLPC_cTcpSocket.c Fri Sep 13 06:38:16 2013 +0000
@@ -31,6 +31,29 @@
static NyLPC_TUInt32 iss32=3939;
#define SIZE_OF_IPv4_TCPIP_HEADER 40
+/**
+ * TCPのRTOの最大値。
+ * ms単位である。
+ * defaultは64SEC
+ */
+#define UIP_IP_RTO_MAX_RTO 64000
+/**
+ * TCPのRTOの初期値。
+ * ms単位である。
+ * 伝送路の特性に合わせて調整すること。
+ */
+#define UIP_TCP_RTO_INITIAL 3000
+
+/**
+ * CONNECTION時のRTO
+ */
+#define UIP_TCP_RTO_CONNECTION_INITIAL 200
+
+/**
+ * 下限値
+ */
+#define UIP_TCP_RTO_MINIMUM 100
+
/**
* for Debug
@@ -44,11 +67,10 @@
#define DEBUG_RTO_LOG(i_inst)
#endif
-
//#define lockResource(i_inst) NyLPC_cMutex_lock(&((i_inst)->_smutex))
//#define unlockResource(i_inst) NyLPC_cMutex_unlock(&((i_inst)->_smutex))
-#define lockResource(i_inst) NyLPC_cMutex_lock(((i_inst)->_smutex))
-#define unlockResource(i_inst) NyLPC_cMutex_unlock(((i_inst)->_smutex))
+#define lockResource(i_inst) NyLPC_cMutex_lock(NyLPC_cIPv4_getSockMutex(((i_inst)->_super._parent_ipv4)))
+#define unlockResource(i_inst) NyLPC_cMutex_unlock(NyLPC_cIPv4_getSockMutex(((i_inst)->_super._parent_ipv4)))
static void sendRst(NyLPC_TcTcpSocket_t* i_inst);
@@ -225,8 +247,8 @@
break;
}
NyLPC_cStopwatch_finalize(&sw);
- if(new_rto<UIP_IP_RTO_MINIMUM){
- new_rto=UIP_IP_RTO_MINIMUM;
+ if(new_rto<UIP_TCP_RTO_MINIMUM){
+ new_rto=UIP_TCP_RTO_MINIMUM;
}
i_inst->uip_connr.current_rto32=new_rto;
}
@@ -312,7 +334,7 @@
NyLPC_cFifoBuffer_initialize(&(i_inst->rxbuf),i_rbuf,i_rbuf_len);
// NyLPC_AbortIfNot(NyLPC_cMutex_initialize(&(i_inst->_smutex)));//個別Mutex
- i_inst->_smutex=NyLPC_cIPv4_getSockMutex(&(srv->_tcpv4));//共有Mutex
+// i_inst->_smutex=NyLPC_cIPv4_getSockMutex(&(srv->_tcpv4));//共有Mutex
i_inst->tcpstateflags=UIP_CLOSED;
i_inst->txbuf.rp=i_inst->txbuf.wp=0;
for(i=0;i<NyLPC_TcTcpSocket_NUMBER_OF_TXQ;i++){
@@ -356,7 +378,7 @@
{
//localipとdefault_mmsは別枠で設定
/* Fill in the necessary fields for the new connection. */
- i_inst->uip_connr.current_rto32 = UIP_IP_RTOP_INITIAL;
+ i_inst->uip_connr.current_rto32 = UIP_TCP_RTO_INITIAL;
i_inst->uip_connr.lport = i_lport;
i_inst->uip_connr.rport = i_lq->rport;
i_inst->uip_connr.ripaddr=i_lq->srcaddr;
@@ -364,20 +386,17 @@
/* rcv_nxt should be the seqno from the incoming packet + 1. */
i_inst->uip_connr.rcv_nxt32= i_lq->rcv_nxt32;
//MSSの設定
- i_inst->uip_connr.peer_mss=i_inst->uip_connr.default_mss;
- if(i_lq->mss!=0){
- i_inst->uip_connr.peer_mss=i_lq->mss;
- }
+ i_inst->uip_connr.peer_mss=(i_lq->mss!=0)?i_lq->mss:i_inst->uip_connr.default_mss;
i_inst->uip_connr.peer_win=0;
NyLPC_cFifoBuffer_clear(&(i_inst->rxbuf));
+ //ここでステータスがかわる。
+ i_inst->tcpstateflags = UIP_SYN_RCVD;
//前回のデータが残っていた場合の保険
if(i_inst->txbuf.rp!=i_inst->txbuf.wp){
resetTxQWithUnlock(i_inst);
}else{
unlockResource(i_inst);
}
- //ここでステータスがかわる。
- i_inst->tcpstateflags = UIP_SYN_RCVD;
return NyLPC_TBool_TRUE;
}
unlockResource(i_inst);
@@ -496,7 +515,7 @@
s=i_len;
}
//ACK番号の計算
- next_ack=i_inst->uip_connr.snd_nxt32+s+((i_tcpf&(TCP_FIN|TCP_SYN))!=0x00?1:0);
+ next_ack=i_inst->uip_connr.snd_nxt32+s+(((i_tcpf&(TCP_FIN|TCP_SYN))!=0x00)?1:0);
txq->rto32=i_inst->uip_connr.current_rto32;
txq->tick_of_sent=NyLPC_cStopwatch_now();
@@ -561,6 +580,7 @@
//エラー:ドロップする。
return NyLPC_TBool_FALSE;
}
+
return NyLPC_TBool_TRUE;
}
@@ -571,6 +591,77 @@
* Public function
*/
+NyLPC_TBool NyLPC_cTcpSocket_connect(NyLPC_TcTcpSocket_t* i_inst,struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_peer_port,NyLPC_TUInt32 i_wait_in_msec)
+{
+ volatile NyLPC_TUInt8 f;
+ NyLPC_TUInt32 sq;
+ NyLPC_TcStopwatch_t sw;
+ NyLPC_TUInt16 lport;
+ lockResource(i_inst);
+ //ソケットが無効であること。
+ if(i_inst->tcpstateflags!=UIP_CLOSED)
+ {
+ NyLPC_OnErrorGoto(Error);
+ }
+ //ポート番号の取得(lockResourceが他のソケットと共有なので、重複ポートの割当は起こりえない。でもちょっと注意して)
+ lport=NyLPC_htons(NyLPC_cIPv4_getNewPortNumber(i_inst->_super._parent_ipv4));
+ if(lport==0){
+ NyLPC_OnErrorGoto(Error);
+ }
+ //connectの為の準備
+
+ //localipとdefault_mmsは別枠で設定
+ /* Fill in the necessary fields for the new connection. */
+ i_inst->uip_connr.current_rto32 = UIP_TCP_RTO_CONNECTION_INITIAL;//RTOを短くしてARP発行時の再接続短縮を期待する。
+ i_inst->uip_connr.lport = lport;
+ i_inst->uip_connr.rport = NyLPC_htons(i_peer_port);
+ i_inst->uip_connr.ripaddr=*i_addr;
+ i_inst->uip_connr.snd_nxt32=iss32;//should be random
+ /* rcv_nxt should be the seqno from the incoming packet + 1. */
+ i_inst->uip_connr.rcv_nxt32=0;
+ //MSSの設定
+ i_inst->uip_connr.peer_mss=i_inst->uip_connr.default_mss;
+ i_inst->uip_connr.peer_win=1;//periodicの再送信を期待するために相手のWindowサイズは1と仮定する。
+ NyLPC_cFifoBuffer_clear(&(i_inst->rxbuf));
+ //ここでステータスがかわる。
+ i_inst->tcpstateflags = UIP_SYN_SENT;
+ //前回のデータが残っていた場合の保険
+ if(i_inst->txbuf.rp!=i_inst->txbuf.wp){
+ resetTxQWithUnlock(i_inst);
+ }else{
+ unlockResource(i_inst);
+ }
+
+ NyLPC_cStopwatch_initialize(&sw);
+
+ NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec);
+ if(sendWithRetransmit(i_inst,TCP_SYN,NULL,0,&sw,&sq)==0){
+ //ちょっと待つ。
+ NyLPC_cThread_yield();
+ //キューにあるTXが消えるのを待つ。
+ if(waitForTxRemove(i_inst,sq,&sw)){
+ //ACK受信に成功して、TXが消失
+ NyLPC_cStopwatch_finalize(&sw);
+ return NyLPC_TBool_TRUE;
+ }
+ }
+ //ロックして、強制的なステータス遷移
+ lockResource(i_inst);
+ f=i_inst->tcpstateflags;
+ if(f!=UIP_CLOSED){
+ //もし、強制CLOSE遷移であれば、RSTも送信。
+ i_inst->tcpstateflags=UIP_CLOSED;
+ unlockResource(i_inst);
+ sendRst(i_inst);
+ }else{
+ unlockResource(i_inst);
+ }
+ return NyLPC_TBool_FALSE;
+Error:
+ unlockResource(i_inst);
+ return NyLPC_TBool_FALSE;
+}
+
/**
* この関数は、UIP_SYN_RCVDステータスのソケットを、ESTABLISHEDへ遷移させます。
* cTcpListener_listen関数を通過したインスタンスに実行してください。
@@ -612,12 +703,12 @@
lockResource(i_inst);
f=i_inst->tcpstateflags;
if(f!=UIP_CLOSED){
+ //もし、強制CLOSE遷移であれば、RSTも送信。
i_inst->tcpstateflags=UIP_CLOSED;
- }
- unlockResource(i_inst);
- //もし、強制CLOSE遷移であれば、RSTも送信。
- if(f!=UIP_CLOSED){
+ unlockResource(i_inst);
sendRst(i_inst);
+ }else{
+ unlockResource(i_inst);
}
return NyLPC_TBool_FALSE;
}
@@ -861,7 +952,7 @@
if(i_len<1){
return 0;
}
- hint=(i_len>32767)?32767:0;
+ hint=(i_len>32767)?32767:i_len;
buf=NyLPC_cTcpSocket_allocSendBuf(i_inst,hint,&s,i_wait_in_msec);
if(buf==NULL){
return -1;
@@ -967,12 +1058,12 @@
lockResource(i_inst);
f=i_inst->tcpstateflags;
if(f!=UIP_CLOSED){
+ //もし、強制CLOSE遷移であれば、RSTも送信。
i_inst->tcpstateflags=UIP_CLOSED;
- }
- unlockResource(i_inst);
- //もし、強制CLOSE遷移であれば、RSTも送信。
- if(f!=UIP_CLOSED){
+ unlockResource(i_inst);
sendRst(i_inst);
+ }else{
+ unlockResource(i_inst);
}
NyLPC_cStopwatch_finalize(&sw);
return;
@@ -1149,8 +1240,8 @@
}
}
}
- //MSSとWNDの更新
- i_inst->uip_connr.peer_mss = i_inst->uip_connr.default_mss;
+// //MSSとWNDの更新
+// i_inst->uip_connr.peer_mss = i_inst->uip_connr.default_mss;//@bug じゃないのこれ。peer_mss勝手に上書きしたらダメだろ
//どちらにしろ、ACK送信
if(is_new_packet && (in_tcpflag & TCP_FIN)){
//FINがあるときは、ステータスをCLOSE_WAITへセットして、ACKを返す。
@@ -1200,10 +1291,21 @@
break;
case UIP_CLOSED:
//何もできない。何もしない。
- break;//goto DROP;
+ break;
case UIP_TIME_WAIT:
//最終ACKを送り続ける。
break;
+ case UIP_SYN_SENT:
+ //connect関数実行中しか起動しないステータス
+ if(num_of_noack==0){
+ i_inst->tcpstateflags=UIP_ESTABLISHED;
+ i_inst->uip_connr.rcv_nxt32=NyLPC_ntohl(o_ipp->payload.tcp->seqno32)+1;
+ }else{
+ //それ以外のパケットはドロップする。
+ break;//goto DROP;
+ }
+ //ACKを送る。
+ break;
default:
goto DROP;
}
MiMic Webservice library