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
core/uip/NyLPC_cTcpSocket.c@57:bc4330dfa62f, 2013-09-13 (annotated)
- Committer:
- nyatla
- Date:
- Fri Sep 13 06:38:16 2013 +0000
- Revision:
- 57:bc4330dfa62f
- Parent:
- 43:a182f2b5ff41
- Child:
- 58:03b89038b21a
update mimic core r329;
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| nyatla | 0:142ee8b12fef | 1 | /********************************************************************************* |
| nyatla | 0:142ee8b12fef | 2 | * PROJECT: MiMic |
| nyatla | 0:142ee8b12fef | 3 | * -------------------------------------------------------------------------------- |
| nyatla | 0:142ee8b12fef | 4 | * |
| nyatla | 0:142ee8b12fef | 5 | * This file is part of MiMic |
| nyatla | 0:142ee8b12fef | 6 | * Copyright (C)2011 Ryo Iizuka |
| nyatla | 0:142ee8b12fef | 7 | * |
| nyatla | 0:142ee8b12fef | 8 | * MiMic is free software: you can redistribute it and/or modify |
| nyatla | 0:142ee8b12fef | 9 | * it under the terms of the GNU Lesser General Public License as published |
| nyatla | 0:142ee8b12fef | 10 | * by the Free Software Foundation, either version 3 of the License, or |
| nyatla | 0:142ee8b12fef | 11 | * (at your option) any later version. |
| nyatla | 0:142ee8b12fef | 12 | * |
| nyatla | 0:142ee8b12fef | 13 | * This program is distributed in the hope that it will be useful, |
| nyatla | 0:142ee8b12fef | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| nyatla | 0:142ee8b12fef | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| nyatla | 0:142ee8b12fef | 16 | * GNU General Public License for more details. |
| nyatla | 0:142ee8b12fef | 17 | * |
| nyatla | 0:142ee8b12fef | 18 | * You should have received a copy of the GNU Lesser General Public License |
| nyatla | 0:142ee8b12fef | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| nyatla | 0:142ee8b12fef | 20 | * |
| nyatla | 0:142ee8b12fef | 21 | * For further information please contact. |
| nyatla | 0:142ee8b12fef | 22 | * http://nyatla.jp/ |
| nyatla | 0:142ee8b12fef | 23 | * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> |
| nyatla | 0:142ee8b12fef | 24 | * |
| nyatla | 0:142ee8b12fef | 25 | *********************************************************************************/ |
| nyatla | 0:142ee8b12fef | 26 | #include "NyLPC_cTcpSocket_protected.h" |
| nyatla | 0:142ee8b12fef | 27 | #include "NyLPC_stdlib.h" |
| nyatla | 0:142ee8b12fef | 28 | #include "NyLPC_cUipService_protected.h" |
| nyatla | 0:142ee8b12fef | 29 | |
| nyatla | 0:142ee8b12fef | 30 | |
| nyatla | 0:142ee8b12fef | 31 | static NyLPC_TUInt32 iss32=3939; |
| nyatla | 0:142ee8b12fef | 32 | #define SIZE_OF_IPv4_TCPIP_HEADER 40 |
| nyatla | 0:142ee8b12fef | 33 | |
| nyatla | 57:bc4330dfa62f | 34 | /** |
| nyatla | 57:bc4330dfa62f | 35 | * TCPのRTOの最大値。 |
| nyatla | 57:bc4330dfa62f | 36 | * ms単位である。 |
| nyatla | 57:bc4330dfa62f | 37 | * defaultは64SEC |
| nyatla | 57:bc4330dfa62f | 38 | */ |
| nyatla | 57:bc4330dfa62f | 39 | #define UIP_IP_RTO_MAX_RTO 64000 |
| nyatla | 57:bc4330dfa62f | 40 | /** |
| nyatla | 57:bc4330dfa62f | 41 | * TCPのRTOの初期値。 |
| nyatla | 57:bc4330dfa62f | 42 | * ms単位である。 |
| nyatla | 57:bc4330dfa62f | 43 | * 伝送路の特性に合わせて調整すること。 |
| nyatla | 57:bc4330dfa62f | 44 | */ |
| nyatla | 57:bc4330dfa62f | 45 | #define UIP_TCP_RTO_INITIAL 3000 |
| nyatla | 57:bc4330dfa62f | 46 | |
| nyatla | 57:bc4330dfa62f | 47 | /** |
| nyatla | 57:bc4330dfa62f | 48 | * CONNECTION時のRTO |
| nyatla | 57:bc4330dfa62f | 49 | */ |
| nyatla | 57:bc4330dfa62f | 50 | #define UIP_TCP_RTO_CONNECTION_INITIAL 200 |
| nyatla | 57:bc4330dfa62f | 51 | |
| nyatla | 57:bc4330dfa62f | 52 | /** |
| nyatla | 57:bc4330dfa62f | 53 | * 下限値 |
| nyatla | 57:bc4330dfa62f | 54 | */ |
| nyatla | 57:bc4330dfa62f | 55 | #define UIP_TCP_RTO_MINIMUM 100 |
| nyatla | 57:bc4330dfa62f | 56 | |
| nyatla | 0:142ee8b12fef | 57 | |
| nyatla | 0:142ee8b12fef | 58 | /** |
| nyatla | 0:142ee8b12fef | 59 | * for Debug |
| nyatla | 0:142ee8b12fef | 60 | * RTOの情報をログ領域に取る。 |
| nyatla | 0:142ee8b12fef | 61 | */ |
| nyatla | 0:142ee8b12fef | 62 | #ifdef RTO_LOG |
| nyatla | 0:142ee8b12fef | 63 | NyLPC_TUInt32 rto_log[256]; |
| nyatla | 0:142ee8b12fef | 64 | int rto_log_st=0; |
| nyatla | 0:142ee8b12fef | 65 | #define DEBUG_RTO_LOG(i_inst) if(rto_log_st<256){rto_log[rto_log_st++]=i_inst->uip_connr.current_rto32;}; |
| nyatla | 0:142ee8b12fef | 66 | #else |
| nyatla | 0:142ee8b12fef | 67 | #define DEBUG_RTO_LOG(i_inst) |
| nyatla | 0:142ee8b12fef | 68 | #endif |
| nyatla | 0:142ee8b12fef | 69 | |
| nyatla | 37:fc4b4fd6a649 | 70 | //#define lockResource(i_inst) NyLPC_cMutex_lock(&((i_inst)->_smutex)) |
| nyatla | 37:fc4b4fd6a649 | 71 | //#define unlockResource(i_inst) NyLPC_cMutex_unlock(&((i_inst)->_smutex)) |
| nyatla | 57:bc4330dfa62f | 72 | #define lockResource(i_inst) NyLPC_cMutex_lock(NyLPC_cIPv4_getSockMutex(((i_inst)->_super._parent_ipv4))) |
| nyatla | 57:bc4330dfa62f | 73 | #define unlockResource(i_inst) NyLPC_cMutex_unlock(NyLPC_cIPv4_getSockMutex(((i_inst)->_super._parent_ipv4))) |
| nyatla | 37:fc4b4fd6a649 | 74 | |
| nyatla | 0:142ee8b12fef | 75 | static void sendRst(NyLPC_TcTcpSocket_t* i_inst); |
| nyatla | 0:142ee8b12fef | 76 | |
| nyatla | 0:142ee8b12fef | 77 | |
| nyatla | 0:142ee8b12fef | 78 | /** |
| nyatla | 0:142ee8b12fef | 79 | * ソケットステータスを元に、IPパケットを構成します。 |
| nyatla | 0:142ee8b12fef | 80 | * この関数は、ロック状態でコールしてください。 |
| nyatla | 0:142ee8b12fef | 81 | */ |
| nyatla | 0:142ee8b12fef | 82 | static void setPacket(const NyLPC_TcTcpSocket_t* i_inst,NyLPC_TcIPv4Payload_t* i_payload,NyLPC_TUInt8 i_tcpf,const void* i_buf,NyLPC_TUInt16 i_len) |
| nyatla | 0:142ee8b12fef | 83 | { |
| nyatla | 0:142ee8b12fef | 84 | void* buf; |
| nyatla | 0:142ee8b12fef | 85 | switch(i_tcpf){ |
| nyatla | 0:142ee8b12fef | 86 | case TCP_PSH|TCP_ACK: |
| nyatla | 0:142ee8b12fef | 87 | buf=NyLPC_cIPv4Payload_initTcpTx(i_payload,0x05,((UIP_TCPH_LEN) / 4),i_len); |
| nyatla | 0:142ee8b12fef | 88 | NyLPC_cIPv4Payload_setTcpTxHeaderByConnection(i_payload,&(i_inst->uip_connr),TCP_ACK|TCP_PSH); |
| nyatla | 0:142ee8b12fef | 89 | //bufの書き込み |
| nyatla | 0:142ee8b12fef | 90 | memcpy(buf,i_buf,i_len); |
| nyatla | 0:142ee8b12fef | 91 | break; |
| nyatla | 0:142ee8b12fef | 92 | case TCP_ACK: |
| nyatla | 0:142ee8b12fef | 93 | case TCP_FIN|TCP_ACK: |
| nyatla | 0:142ee8b12fef | 94 | case TCP_RST|TCP_ACK: |
| nyatla | 0:142ee8b12fef | 95 | NyLPC_cIPv4Payload_initTcpTx(i_payload,0x05,((UIP_TCPH_LEN) / 4),0); |
| nyatla | 0:142ee8b12fef | 96 | NyLPC_cIPv4Payload_setTcpTxHeaderByConnection(i_payload,&(i_inst->uip_connr),i_tcpf); |
| nyatla | 0:142ee8b12fef | 97 | break; |
| nyatla | 0:142ee8b12fef | 98 | case TCP_SYN|TCP_ACK: |
| nyatla | 0:142ee8b12fef | 99 | NyLPC_cIPv4Payload_initTcpTx(i_payload,0x05,((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4),0); |
| nyatla | 0:142ee8b12fef | 100 | NyLPC_cIPv4Payload_setTcpTxHeaderByConnection(i_payload,&(i_inst->uip_connr),i_tcpf); |
| nyatla | 0:142ee8b12fef | 101 | //MSSの設定(OPTION領域のアドレス0) |
| nyatla | 0:142ee8b12fef | 102 | NyLPC_TTcpHeader_setMmsOpt((NyLPC_TUInt8*)(i_payload->payload.tcp+1),i_inst->uip_connr.default_mss); |
| nyatla | 0:142ee8b12fef | 103 | break; |
| nyatla | 0:142ee8b12fef | 104 | case TCP_SYN: |
| nyatla | 0:142ee8b12fef | 105 | NyLPC_cIPv4Payload_initTcpTx(i_payload,0x05,((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4),0); |
| nyatla | 0:142ee8b12fef | 106 | NyLPC_cIPv4Payload_setTcpTxHeaderByConnection(i_payload,&(i_inst->uip_connr),i_tcpf); |
| nyatla | 0:142ee8b12fef | 107 | //MSSの設定(OPTION領域のアドレス0) |
| nyatla | 0:142ee8b12fef | 108 | NyLPC_TTcpHeader_setMmsOpt((NyLPC_TUInt8*)(i_payload->payload.tcp+1),i_inst->uip_connr.default_mss); |
| nyatla | 0:142ee8b12fef | 109 | break; |
| nyatla | 0:142ee8b12fef | 110 | default: |
| nyatla | 0:142ee8b12fef | 111 | NyLPC_Abort(); |
| nyatla | 0:142ee8b12fef | 112 | } |
| nyatla | 0:142ee8b12fef | 113 | NyLPC_cIPv4Payload_setTcpWnd(i_payload,NyLPC_cFifoBuffer_getSpace(&(i_inst->rxbuf))); |
| nyatla | 0:142ee8b12fef | 114 | NyLPC_cIPv4Payload_closeTcpTxPacket(i_payload); |
| nyatla | 0:142ee8b12fef | 115 | return; |
| nyatla | 0:142ee8b12fef | 116 | } |
| nyatla | 0:142ee8b12fef | 117 | /** |
| nyatla | 0:142ee8b12fef | 118 | * 指定した送信パケットがACK済であるか調べる。 |
| nyatla | 0:142ee8b12fef | 119 | */ |
| nyatla | 0:142ee8b12fef | 120 | static NyLPC_TBool isPacketAcked(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_sq) |
| nyatla | 0:142ee8b12fef | 121 | { |
| nyatla | 0:142ee8b12fef | 122 | int rp; |
| nyatla | 0:142ee8b12fef | 123 | struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; |
| nyatla | 0:142ee8b12fef | 124 | rp=i_inst->txbuf.rp; |
| nyatla | 0:142ee8b12fef | 125 | while(rp!=i_inst->txbuf.wp){ |
| nyatla | 0:142ee8b12fef | 126 | if(q[rp].ackno==i_sq){ |
| nyatla | 0:142ee8b12fef | 127 | return NyLPC_TBool_FALSE; |
| nyatla | 0:142ee8b12fef | 128 | } |
| nyatla | 0:142ee8b12fef | 129 | rp=(rp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; |
| nyatla | 0:142ee8b12fef | 130 | } |
| nyatla | 0:142ee8b12fef | 131 | return NyLPC_TBool_TRUE; |
| nyatla | 0:142ee8b12fef | 132 | } |
| nyatla | 0:142ee8b12fef | 133 | /** |
| nyatla | 0:142ee8b12fef | 134 | * 送信キューからi_sq以前に送信したパケットを除外して、残り個数を返却する。 |
| nyatla | 0:142ee8b12fef | 135 | */ |
| nyatla | 0:142ee8b12fef | 136 | static int getNumOfSending(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_sq) |
| nyatla | 0:142ee8b12fef | 137 | { |
| nyatla | 0:142ee8b12fef | 138 | int rp,n; |
| nyatla | 0:142ee8b12fef | 139 | struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; |
| nyatla | 0:142ee8b12fef | 140 | rp=i_inst->txbuf.rp; |
| nyatla | 0:142ee8b12fef | 141 | n=0; |
| nyatla | 0:142ee8b12fef | 142 | while(rp!=i_inst->txbuf.wp){ |
| nyatla | 0:142ee8b12fef | 143 | if(q[rp].ackno==i_sq){ |
| nyatla | 0:142ee8b12fef | 144 | return n; |
| nyatla | 0:142ee8b12fef | 145 | } |
| nyatla | 0:142ee8b12fef | 146 | n++; |
| nyatla | 0:142ee8b12fef | 147 | rp=(rp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; |
| nyatla | 0:142ee8b12fef | 148 | } |
| nyatla | 0:142ee8b12fef | 149 | return n; |
| nyatla | 0:142ee8b12fef | 150 | } |
| nyatla | 0:142ee8b12fef | 151 | /** |
| nyatla | 0:142ee8b12fef | 152 | * この関数は、コネクションをリセットします。 |
| nyatla | 0:142ee8b12fef | 153 | * ロック状態でコールしてください。 |
| nyatla | 0:142ee8b12fef | 154 | * 関数は、現在バッファにある再送信待ちデータを開放します。 |
| nyatla | 0:142ee8b12fef | 155 | */ |
| nyatla | 0:142ee8b12fef | 156 | static void resetTxQWithUnlock(NyLPC_TcTcpSocket_t* i_inst) |
| nyatla | 0:142ee8b12fef | 157 | { |
| nyatla | 0:142ee8b12fef | 158 | int i,l; |
| nyatla | 0:142ee8b12fef | 159 | struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; |
| nyatla | 0:142ee8b12fef | 160 | void* dlist[NyLPC_TcTcpSocket_NUMBER_OF_TXQ]; |
| nyatla | 0:142ee8b12fef | 161 | |
| nyatla | 0:142ee8b12fef | 162 | l=0; |
| nyatla | 0:142ee8b12fef | 163 | while(i_inst->txbuf.rp!=i_inst->txbuf.wp){ |
| nyatla | 0:142ee8b12fef | 164 | dlist[l]=NyLPC_cIPv4Payload_detachBuf(&(q[i_inst->txbuf.rp].data)); |
| nyatla | 0:142ee8b12fef | 165 | l++; |
| nyatla | 0:142ee8b12fef | 166 | i_inst->txbuf.rp=(i_inst->txbuf.rp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; |
| nyatla | 0:142ee8b12fef | 167 | } |
| nyatla | 0:142ee8b12fef | 168 | i_inst->txbuf.rp=i_inst->txbuf.wp=0; |
| nyatla | 0:142ee8b12fef | 169 | //ロック解除 |
| nyatla | 37:fc4b4fd6a649 | 170 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 171 | //セーブしたバッファを開放 |
| nyatla | 0:142ee8b12fef | 172 | for(i=0;i<l;i++){ |
| nyatla | 0:142ee8b12fef | 173 | NyLPC_cUipService_releaseTxBuf(dlist[i]); |
| nyatla | 0:142ee8b12fef | 174 | } |
| nyatla | 0:142ee8b12fef | 175 | return; |
| nyatla | 0:142ee8b12fef | 176 | } |
| nyatla | 0:142ee8b12fef | 177 | /** |
| nyatla | 0:142ee8b12fef | 178 | * TXバッファの再送パケットのACK番号を更新します。 |
| nyatla | 0:142ee8b12fef | 179 | * ロックして実行してください。 |
| nyatla | 0:142ee8b12fef | 180 | * @param i_ackno |
| nyatla | 0:142ee8b12fef | 181 | * ネットワークオーダーのACK番号 |
| nyatla | 0:142ee8b12fef | 182 | */ |
| nyatla | 0:142ee8b12fef | 183 | static void updateTxAck(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_ackno) |
| nyatla | 0:142ee8b12fef | 184 | { |
| nyatla | 0:142ee8b12fef | 185 | NyLPC_TUInt8 rp; |
| nyatla | 0:142ee8b12fef | 186 | struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; |
| nyatla | 0:142ee8b12fef | 187 | NyLPC_ArgAssert(i_inst!=NULL); |
| nyatla | 0:142ee8b12fef | 188 | rp=i_inst->txbuf.rp; |
| nyatla | 0:142ee8b12fef | 189 | while(rp!=i_inst->txbuf.wp){ |
| nyatla | 0:142ee8b12fef | 190 | NyLPC_cIPv4Payload_updateAckNo(&(q[rp].data),i_ackno); |
| nyatla | 0:142ee8b12fef | 191 | rp=(rp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; |
| nyatla | 0:142ee8b12fef | 192 | } |
| nyatla | 0:142ee8b12fef | 193 | } |
| nyatla | 0:142ee8b12fef | 194 | |
| nyatla | 0:142ee8b12fef | 195 | /** |
| nyatla | 0:142ee8b12fef | 196 | * RTOの予測関数 |
| nyatla | 0:142ee8b12fef | 197 | */ |
| nyatla | 0:142ee8b12fef | 198 | static void estimateRTO(NyLPC_TcTcpSocket_t* i_inst,int s,int n) |
| nyatla | 0:142ee8b12fef | 199 | { |
| nyatla | 0:142ee8b12fef | 200 | NyLPC_TcStopwatch_t sw; |
| nyatla | 0:142ee8b12fef | 201 | NyLPC_TUInt32 cr_rtt_min,cr_rtt_max,sk_rto,new_rto,w; |
| nyatla | 0:142ee8b12fef | 202 | int i; |
| nyatla | 0:142ee8b12fef | 203 | struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; |
| nyatla | 0:142ee8b12fef | 204 | NyLPC_cStopwatch_initialize(&sw); |
| nyatla | 0:142ee8b12fef | 205 | |
| nyatla | 0:142ee8b12fef | 206 | sk_rto=i_inst->uip_connr.current_rto32; |
| nyatla | 0:142ee8b12fef | 207 | //ACKされたパケットの個数は? |
| nyatla | 0:142ee8b12fef | 208 | switch(n){ |
| nyatla | 0:142ee8b12fef | 209 | case 1: |
| nyatla | 0:142ee8b12fef | 210 | NyLPC_cStopwatch_set(&sw,q[s].tick_of_sent); |
| nyatla | 0:142ee8b12fef | 211 | cr_rtt_min=NyLPC_cStopwatch_elapseInMsec(&sw); |
| nyatla | 0:142ee8b12fef | 212 | if(sk_rto<cr_rtt_min){ |
| nyatla | 0:142ee8b12fef | 213 | //現在のRTOよりも大きい→再送があった。(再送の理由が回線遅延によるものかわからないので、基本RTOを25%増やす。) |
| nyatla | 0:142ee8b12fef | 214 | new_rto=sk_rto*10/8; |
| nyatla | 0:142ee8b12fef | 215 | }else if(sk_rto/4<cr_rtt_min){ |
| nyatla | 0:142ee8b12fef | 216 | //現在のRTOの1/4< n < 現在のRTO 想定内の変動。1/8 |
| nyatla | 0:142ee8b12fef | 217 | new_rto=(sk_rto+(cr_rtt_min*3*7))/8; |
| nyatla | 0:142ee8b12fef | 218 | }else{ |
| nyatla | 0:142ee8b12fef | 219 | //現在の1/4以下。RTOを再計算。 RTOが大きすぎるので再計算。(計測値を優先した現在値との平均値) |
| nyatla | 0:142ee8b12fef | 220 | new_rto=(sk_rto+(cr_rtt_min*3*3))/4; |
| nyatla | 0:142ee8b12fef | 221 | } |
| nyatla | 0:142ee8b12fef | 222 | break; |
| nyatla | 0:142ee8b12fef | 223 | default: |
| nyatla | 0:142ee8b12fef | 224 | //複数のパケットなら、最大と最小の時刻を得る。 |
| nyatla | 0:142ee8b12fef | 225 | NyLPC_cStopwatch_set(&sw,q[s].tick_of_sent); |
| nyatla | 0:142ee8b12fef | 226 | cr_rtt_min=cr_rtt_max=NyLPC_cStopwatch_elapseInMsec(&sw); |
| nyatla | 0:142ee8b12fef | 227 | for(i=1;i<n;i++){ |
| nyatla | 0:142ee8b12fef | 228 | NyLPC_cStopwatch_set(&sw,q[(s+i)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ].tick_of_sent); |
| nyatla | 0:142ee8b12fef | 229 | w=NyLPC_cStopwatch_elapseInMsec(&sw); |
| nyatla | 0:142ee8b12fef | 230 | if(cr_rtt_min>w){ |
| nyatla | 0:142ee8b12fef | 231 | cr_rtt_min=w; |
| nyatla | 0:142ee8b12fef | 232 | } |
| nyatla | 0:142ee8b12fef | 233 | if(cr_rtt_max<w){ |
| nyatla | 0:142ee8b12fef | 234 | cr_rtt_max=w; |
| nyatla | 0:142ee8b12fef | 235 | } |
| nyatla | 0:142ee8b12fef | 236 | } |
| nyatla | 0:142ee8b12fef | 237 | if(sk_rto<cr_rtt_min && sk_rto<cr_rtt_max){ |
| nyatla | 0:142ee8b12fef | 238 | //最大値,最小値とも現在のRTTより大きい→低速な回線を検出。 |
| nyatla | 0:142ee8b12fef | 239 | new_rto=cr_rtt_max*10/8;//最大経過時間の25%増しの時間を設定。 |
| nyatla | 0:142ee8b12fef | 240 | }else if(sk_rto/4<cr_rtt_min){ |
| nyatla | 0:142ee8b12fef | 241 | //現在のRTOの1/4< n < 現在のRTO 想定範囲内。1/8の加重平均で速度計算。 |
| nyatla | 0:142ee8b12fef | 242 | new_rto=(sk_rto+(cr_rtt_min*3*7))/8; |
| nyatla | 0:142ee8b12fef | 243 | }else{ |
| nyatla | 0:142ee8b12fef | 244 | //現在の1/4以下。RTOが大きすぎるので再計算。(計測値を優先した加重平均) |
| nyatla | 0:142ee8b12fef | 245 | new_rto=(sk_rto+(cr_rtt_min*3*3))/4; |
| nyatla | 0:142ee8b12fef | 246 | } |
| nyatla | 0:142ee8b12fef | 247 | break; |
| nyatla | 0:142ee8b12fef | 248 | } |
| nyatla | 0:142ee8b12fef | 249 | NyLPC_cStopwatch_finalize(&sw); |
| nyatla | 57:bc4330dfa62f | 250 | if(new_rto<UIP_TCP_RTO_MINIMUM){ |
| nyatla | 57:bc4330dfa62f | 251 | new_rto=UIP_TCP_RTO_MINIMUM; |
| nyatla | 0:142ee8b12fef | 252 | } |
| nyatla | 0:142ee8b12fef | 253 | i_inst->uip_connr.current_rto32=new_rto; |
| nyatla | 0:142ee8b12fef | 254 | } |
| nyatla | 0:142ee8b12fef | 255 | |
| nyatla | 0:142ee8b12fef | 256 | /** |
| nyatla | 0:142ee8b12fef | 257 | * TXキューから、入力されたシーケンス番号より前のパケットを除外します。 |
| nyatla | 0:142ee8b12fef | 258 | * リングバッファのrp->wp-1までをチェックして、sqに等しいi_sq以前のパケットバッファをo_dlistへ返します。 |
| nyatla | 0:142ee8b12fef | 259 | * |
| nyatla | 0:142ee8b12fef | 260 | */ |
| nyatla | 0:142ee8b12fef | 261 | static int updateTxQByIndex(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_sq,void* o_dlist[]) |
| nyatla | 0:142ee8b12fef | 262 | { |
| nyatla | 0:142ee8b12fef | 263 | int rp,n; |
| nyatla | 0:142ee8b12fef | 264 | struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; |
| nyatla | 0:142ee8b12fef | 265 | //ロック状態なう |
| nyatla | 0:142ee8b12fef | 266 | rp=i_inst->txbuf.rp; |
| nyatla | 0:142ee8b12fef | 267 | n=0; |
| nyatla | 0:142ee8b12fef | 268 | //This is debug |
| nyatla | 0:142ee8b12fef | 269 | DEBUG_RTO_LOG(i_inst); |
| nyatla | 0:142ee8b12fef | 270 | |
| nyatla | 0:142ee8b12fef | 271 | while(rp!=i_inst->txbuf.wp){ |
| nyatla | 0:142ee8b12fef | 272 | o_dlist[n]=NyLPC_cIPv4Payload_getBuf(&(q[rp].data)); |
| nyatla | 0:142ee8b12fef | 273 | if(q[rp].ackno==i_sq){ |
| nyatla | 0:142ee8b12fef | 274 | //i_inst->txbuf.rp->rpのパケットのRTOからbaseRTOの値を再計算。 |
| nyatla | 0:142ee8b12fef | 275 | estimateRTO(i_inst,i_inst->txbuf.rp,n+1); |
| nyatla | 0:142ee8b12fef | 276 | i_inst->txbuf.rp=(rp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; |
| nyatla | 0:142ee8b12fef | 277 | return n+1; |
| nyatla | 0:142ee8b12fef | 278 | } |
| nyatla | 0:142ee8b12fef | 279 | n++; |
| nyatla | 0:142ee8b12fef | 280 | rp=(rp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; |
| nyatla | 0:142ee8b12fef | 281 | } |
| nyatla | 0:142ee8b12fef | 282 | return 0; |
| nyatla | 0:142ee8b12fef | 283 | } |
| nyatla | 0:142ee8b12fef | 284 | |
| nyatla | 0:142ee8b12fef | 285 | |
| nyatla | 0:142ee8b12fef | 286 | |
| nyatla | 0:142ee8b12fef | 287 | /** |
| nyatla | 0:142ee8b12fef | 288 | * 空きキューを1個返します。 |
| nyatla | 0:142ee8b12fef | 289 | * 空きキューの |
| nyatla | 0:142ee8b12fef | 290 | */ |
| nyatla | 0:142ee8b12fef | 291 | static struct NyLPC_TcTcpSocket_TxQItem* getTxQ(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TcStopwatch_t* i_timer) |
| nyatla | 0:142ee8b12fef | 292 | { |
| nyatla | 0:142ee8b12fef | 293 | int i; |
| nyatla | 0:142ee8b12fef | 294 | struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; |
| nyatla | 0:142ee8b12fef | 295 | while(!NyLPC_cStopwatch_isExpired(i_timer)){ |
| nyatla | 0:142ee8b12fef | 296 | //クローズドに遷移してしまったら、エラーである。 |
| nyatla | 0:142ee8b12fef | 297 | if(i_inst->tcpstateflags==UIP_CLOSED){ |
| nyatla | 0:142ee8b12fef | 298 | return NULL; |
| nyatla | 0:142ee8b12fef | 299 | } |
| nyatla | 0:142ee8b12fef | 300 | //キューの空きをチェック。wp+1==rpなら、キューがいっぱい。rp==wpなら、キューが空。 |
| nyatla | 0:142ee8b12fef | 301 | if(((i_inst->txbuf.wp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ)==i_inst->txbuf.rp){ |
| nyatla | 0:142ee8b12fef | 302 | //一時的なアンロック |
| nyatla | 37:fc4b4fd6a649 | 303 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 304 | //タスクスイッチ |
| nyatla | 0:142ee8b12fef | 305 | NyLPC_cThread_yield(); |
| nyatla | 0:142ee8b12fef | 306 | //ロック |
| nyatla | 37:fc4b4fd6a649 | 307 | lockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 308 | continue; |
| nyatla | 0:142ee8b12fef | 309 | } |
| nyatla | 0:142ee8b12fef | 310 | i=i_inst->txbuf.wp; |
| nyatla | 0:142ee8b12fef | 311 | i_inst->txbuf.wp=(i+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; |
| nyatla | 0:142ee8b12fef | 312 | return &(q[i]); |
| nyatla | 0:142ee8b12fef | 313 | } |
| nyatla | 0:142ee8b12fef | 314 | //失敗。タイムアウト。 |
| nyatla | 0:142ee8b12fef | 315 | return NULL; |
| nyatla | 0:142ee8b12fef | 316 | } |
| nyatla | 0:142ee8b12fef | 317 | |
| nyatla | 0:142ee8b12fef | 318 | |
| nyatla | 0:142ee8b12fef | 319 | |
| nyatla | 0:142ee8b12fef | 320 | |
| nyatla | 0:142ee8b12fef | 321 | |
| nyatla | 0:142ee8b12fef | 322 | |
| nyatla | 0:142ee8b12fef | 323 | /********************************************************************** |
| nyatla | 0:142ee8b12fef | 324 | * public 関数 |
| nyatla | 0:142ee8b12fef | 325 | **********************************************************************/ |
| nyatla | 0:142ee8b12fef | 326 | |
| nyatla | 0:142ee8b12fef | 327 | NyLPC_TBool NyLPC_cTcpSocket_initialize(NyLPC_TcTcpSocket_t* i_inst,void* i_rbuf,NyLPC_TUInt16 i_rbuf_len) |
| nyatla | 0:142ee8b12fef | 328 | { |
| nyatla | 0:142ee8b12fef | 329 | int i; |
| nyatla | 0:142ee8b12fef | 330 | NyLPC_TcUipService_t* srv=_NyLPC_TcUipService_inst; |
| nyatla | 37:fc4b4fd6a649 | 331 | NyLPC_cBaseSocket_initialize(&(i_inst->_super),NyLPC_TcBaseSocket_TYPEID_TCP_SOCK); |
| nyatla | 0:142ee8b12fef | 332 | //uipサービスは初期化済であること。 |
| nyatla | 0:142ee8b12fef | 333 | NyLPC_Assert(NyLPC_TcUipService_isInitService()); |
| nyatla | 0:142ee8b12fef | 334 | |
| nyatla | 0:142ee8b12fef | 335 | NyLPC_cFifoBuffer_initialize(&(i_inst->rxbuf),i_rbuf,i_rbuf_len); |
| nyatla | 37:fc4b4fd6a649 | 336 | // NyLPC_AbortIfNot(NyLPC_cMutex_initialize(&(i_inst->_smutex)));//個別Mutex |
| nyatla | 57:bc4330dfa62f | 337 | // i_inst->_smutex=NyLPC_cIPv4_getSockMutex(&(srv->_tcpv4));//共有Mutex |
| nyatla | 0:142ee8b12fef | 338 | i_inst->tcpstateflags=UIP_CLOSED; |
| nyatla | 0:142ee8b12fef | 339 | i_inst->txbuf.rp=i_inst->txbuf.wp=0; |
| nyatla | 0:142ee8b12fef | 340 | for(i=0;i<NyLPC_TcTcpSocket_NUMBER_OF_TXQ;i++){ |
| nyatla | 0:142ee8b12fef | 341 | NyLPC_cIPv4Payload_initialize(&(i_inst->txbuf.txq[i].data)); |
| nyatla | 0:142ee8b12fef | 342 | } |
| nyatla | 0:142ee8b12fef | 343 | //管理リストへ登録。 |
| nyatla | 37:fc4b4fd6a649 | 344 | return NyLPC_cIPv4_addSocket(&(srv->_tcpv4),&(i_inst->_super)); |
| nyatla | 0:142ee8b12fef | 345 | } |
| nyatla | 2:b96c1e90d120 | 346 | void NyLPC_cTcpSocket_finalize(NyLPC_TcTcpSocket_t* i_inst) |
| nyatla | 0:142ee8b12fef | 347 | { |
| nyatla | 0:142ee8b12fef | 348 | int i; |
| nyatla | 0:142ee8b12fef | 349 | NyLPC_TcUipService_t* srv=_NyLPC_TcUipService_inst; |
| nyatla | 0:142ee8b12fef | 350 | NyLPC_Assert(NyLPC_TcUipService_isInitService()); |
| nyatla | 0:142ee8b12fef | 351 | //uipサービスは初期化済であること。 |
| nyatla | 37:fc4b4fd6a649 | 352 | if(!NyLPC_cIPv4_removeSocket(&(srv->_tcpv4),&(i_inst->_super))){ |
| nyatla | 0:142ee8b12fef | 353 | //削除失敗、それは死を意味する。 |
| nyatla | 0:142ee8b12fef | 354 | NyLPC_Abort(); |
| nyatla | 0:142ee8b12fef | 355 | } |
| nyatla | 0:142ee8b12fef | 356 | //開放漏れの保険 |
| nyatla | 0:142ee8b12fef | 357 | if(i_inst->txbuf.rp!=i_inst->txbuf.wp){ |
| nyatla | 37:fc4b4fd6a649 | 358 | lockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 359 | resetTxQWithUnlock(i_inst); |
| nyatla | 0:142ee8b12fef | 360 | } |
| nyatla | 0:142ee8b12fef | 361 | for(i=0;i<NyLPC_TcTcpSocket_NUMBER_OF_TXQ;i++){ |
| nyatla | 0:142ee8b12fef | 362 | NyLPC_cIPv4Payload_finalize(&(i_inst->txbuf.txq[i].data)); |
| nyatla | 0:142ee8b12fef | 363 | } |
| nyatla | 0:142ee8b12fef | 364 | NyLPC_cFifoBuffer_finalize(&(i_inst->rxbuf)); |
| nyatla | 37:fc4b4fd6a649 | 365 | // NyLPC_cMutex_finalize(&(i_inst->_smutex)); |
| nyatla | 37:fc4b4fd6a649 | 366 | NyLPC_cBaseSocket_finalize(&(i_inst->_super)); |
| nyatla | 0:142ee8b12fef | 367 | return; |
| nyatla | 0:142ee8b12fef | 368 | } |
| nyatla | 0:142ee8b12fef | 369 | |
| nyatla | 37:fc4b4fd6a649 | 370 | |
| nyatla | 43:a182f2b5ff41 | 371 | |
| nyatla | 43:a182f2b5ff41 | 372 | NyLPC_TBool NyLPC_cTcpSocket_listenSyn(NyLPC_TcTcpSocket_t* i_inst,const struct NyLPC_TTcpSocketSynParam* i_lq,NyLPC_TUInt16 i_lport) |
| nyatla | 0:142ee8b12fef | 373 | { |
| nyatla | 37:fc4b4fd6a649 | 374 | // NyLPC_Assert(NyLPC_cMutex_isLocked(i_inst->_smutex)); |
| nyatla | 37:fc4b4fd6a649 | 375 | lockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 376 | //ソケットが無効であること。 |
| nyatla | 0:142ee8b12fef | 377 | if(i_inst->tcpstateflags==UIP_CLOSED) |
| nyatla | 0:142ee8b12fef | 378 | { |
| nyatla | 37:fc4b4fd6a649 | 379 | //localipとdefault_mmsは別枠で設定 |
| nyatla | 0:142ee8b12fef | 380 | /* Fill in the necessary fields for the new connection. */ |
| nyatla | 57:bc4330dfa62f | 381 | i_inst->uip_connr.current_rto32 = UIP_TCP_RTO_INITIAL; |
| nyatla | 43:a182f2b5ff41 | 382 | i_inst->uip_connr.lport = i_lport; |
| nyatla | 43:a182f2b5ff41 | 383 | i_inst->uip_connr.rport = i_lq->rport; |
| nyatla | 43:a182f2b5ff41 | 384 | i_inst->uip_connr.ripaddr=i_lq->srcaddr; |
| nyatla | 0:142ee8b12fef | 385 | i_inst->uip_connr.snd_nxt32=iss32; |
| nyatla | 0:142ee8b12fef | 386 | /* rcv_nxt should be the seqno from the incoming packet + 1. */ |
| nyatla | 43:a182f2b5ff41 | 387 | i_inst->uip_connr.rcv_nxt32= i_lq->rcv_nxt32; |
| nyatla | 0:142ee8b12fef | 388 | //MSSの設定 |
| nyatla | 57:bc4330dfa62f | 389 | i_inst->uip_connr.peer_mss=(i_lq->mss!=0)?i_lq->mss:i_inst->uip_connr.default_mss; |
| nyatla | 0:142ee8b12fef | 390 | i_inst->uip_connr.peer_win=0; |
| nyatla | 0:142ee8b12fef | 391 | NyLPC_cFifoBuffer_clear(&(i_inst->rxbuf)); |
| nyatla | 57:bc4330dfa62f | 392 | //ここでステータスがかわる。 |
| nyatla | 57:bc4330dfa62f | 393 | i_inst->tcpstateflags = UIP_SYN_RCVD; |
| nyatla | 0:142ee8b12fef | 394 | //前回のデータが残っていた場合の保険 |
| nyatla | 0:142ee8b12fef | 395 | if(i_inst->txbuf.rp!=i_inst->txbuf.wp){ |
| nyatla | 0:142ee8b12fef | 396 | resetTxQWithUnlock(i_inst); |
| nyatla | 0:142ee8b12fef | 397 | }else{ |
| nyatla | 37:fc4b4fd6a649 | 398 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 399 | } |
| nyatla | 0:142ee8b12fef | 400 | return NyLPC_TBool_TRUE; |
| nyatla | 0:142ee8b12fef | 401 | } |
| nyatla | 37:fc4b4fd6a649 | 402 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 403 | return NyLPC_TBool_FALSE; |
| nyatla | 0:142ee8b12fef | 404 | } |
| nyatla | 43:a182f2b5ff41 | 405 | |
| nyatla | 43:a182f2b5ff41 | 406 | |
| nyatla | 0:142ee8b12fef | 407 | /** |
| nyatla | 0:142ee8b12fef | 408 | * sq番のTxがキューから消え去るのを待ちます。 |
| nyatla | 0:142ee8b12fef | 409 | * この関数は、アンロック状態でコールしてください。 |
| nyatla | 0:142ee8b12fef | 410 | * <div> |
| nyatla | 0:142ee8b12fef | 411 | * パケットがキューからなくなる条件は、以下の2つです。 |
| nyatla | 0:142ee8b12fef | 412 | * <ul> |
| nyatla | 0:142ee8b12fef | 413 | * <li>ACKを受信してパケットキューが更新された。</li> |
| nyatla | 0:142ee8b12fef | 414 | * <li>RSTを受信して(CLOSEDに遷移して)、キューがクリアされた。</li> |
| nyatla | 0:142ee8b12fef | 415 | * <li>送信タイムアウトで関数が(CLOSEDに遷移させて)キューをクリアした。</li> |
| nyatla | 0:142ee8b12fef | 416 | * </ul> |
| nyatla | 0:142ee8b12fef | 417 | * </div> |
| nyatla | 0:142ee8b12fef | 418 | * @param i_wait_msec |
| nyatla | 0:142ee8b12fef | 419 | * @return |
| nyatla | 0:142ee8b12fef | 420 | * 1番目の条件でパケットが消失したときのみ、TRUEを返します。 |
| nyatla | 0:142ee8b12fef | 421 | * 失敗した場合、TCPステータスがCLOSEDでなければ、RSTを送信してステータスをCLOSEDにします。 |
| nyatla | 0:142ee8b12fef | 422 | */ |
| nyatla | 0:142ee8b12fef | 423 | static NyLPC_TBool waitForTxRemove(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_sq,NyLPC_TcStopwatch_t* i_timer) |
| nyatla | 0:142ee8b12fef | 424 | { |
| nyatla | 0:142ee8b12fef | 425 | NyLPC_TUInt8 f; |
| nyatla | 37:fc4b4fd6a649 | 426 | lockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 427 | while(!NyLPC_cStopwatch_isExpired(i_timer)){ |
| nyatla | 0:142ee8b12fef | 428 | //パケットが送信中か調べる。 |
| nyatla | 0:142ee8b12fef | 429 | if(!isPacketAcked(i_inst,i_sq)){ |
| nyatla | 0:142ee8b12fef | 430 | //まだある場合は、タスクスイッチを繰り返して消失を待つ。 |
| nyatla | 37:fc4b4fd6a649 | 431 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 432 | NyLPC_cThread_yield(); |
| nyatla | 37:fc4b4fd6a649 | 433 | lockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 434 | continue; |
| nyatla | 0:142ee8b12fef | 435 | } |
| nyatla | 0:142ee8b12fef | 436 | //なくなった場合は、原因を調べる。 |
| nyatla | 0:142ee8b12fef | 437 | f=i_inst->tcpstateflags; |
| nyatla | 37:fc4b4fd6a649 | 438 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 439 | return (f==UIP_CLOSED)?NyLPC_TBool_FALSE:NyLPC_TBool_TRUE; |
| nyatla | 0:142ee8b12fef | 440 | } |
| nyatla | 37:fc4b4fd6a649 | 441 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 442 | return NyLPC_TBool_FALSE; |
| nyatla | 0:142ee8b12fef | 443 | } |
| nyatla | 0:142ee8b12fef | 444 | |
| nyatla | 0:142ee8b12fef | 445 | |
| nyatla | 0:142ee8b12fef | 446 | /** |
| nyatla | 0:142ee8b12fef | 447 | * 再送信処理をセットして、パケットを送信します。 |
| nyatla | 0:142ee8b12fef | 448 | * この関数は「アンロック状態で」実行してください。 |
| nyatla | 0:142ee8b12fef | 449 | * @param i_len |
| nyatla | 0:142ee8b12fef | 450 | * 送信データサイズを指定します。 |
| nyatla | 0:142ee8b12fef | 451 | * この番号は、シーケンス番号の加算値ではありませんので、注意をしてください。 |
| nyatla | 0:142ee8b12fef | 452 | * @return |
| nyatla | 0:142ee8b12fef | 453 | * <ul> |
| nyatla | 0:142ee8b12fef | 454 | * <li>n=-1:送信キューへの投入に失敗した。</li> |
| nyatla | 0:142ee8b12fef | 455 | * <li>n>=0:nバイトのデータを送信キューへの投入することに成功した。</li> |
| nyatla | 0:142ee8b12fef | 456 | * </ul> |
| nyatla | 0:142ee8b12fef | 457 | * 送信キューに失敗する理由は2つあります。1つは、TXバッファがフルでタイムアウト。もうひとつは、非同期なコネクリョンのリセットです。 |
| nyatla | 0:142ee8b12fef | 458 | * 失敗した場合、TCPステータスがCLOSEDでなければ、RSTを送信してステータスをCLOSEDにします。 |
| nyatla | 0:142ee8b12fef | 459 | */ |
| nyatla | 0:142ee8b12fef | 460 | static NyLPC_TInt32 sendWithRetransmit(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt8 i_tcpf,const void* i_buf,NyLPC_TUInt16 i_len,NyLPC_TcStopwatch_t* i_timer,NyLPC_TUInt32* o_ack) |
| nyatla | 0:142ee8b12fef | 461 | { |
| nyatla | 0:142ee8b12fef | 462 | struct NyLPC_TcTcpSocket_TxQItem* txq; |
| nyatla | 0:142ee8b12fef | 463 | NyLPC_TUInt16 s; |
| nyatla | 0:142ee8b12fef | 464 | void* buf; |
| nyatla | 0:142ee8b12fef | 465 | NyLPC_TUInt32 next_ack; |
| nyatla | 0:142ee8b12fef | 466 | //送信バッファを取得 |
| nyatla | 20:3b0b444b4deb | 467 | //@bug バッファが取れるまで通信がブロックするの。ここはなんとかしないと。 |
| nyatla | 20:3b0b444b4deb | 468 | for(;;){ |
| nyatla | 20:3b0b444b4deb | 469 | buf=NyLPC_cUipService_allocTxBuf(i_len+(SIZE_OF_IPv4_TCPIP_HEADER),&s); |
| nyatla | 20:3b0b444b4deb | 470 | if(buf!=NULL){ |
| nyatla | 20:3b0b444b4deb | 471 | break; |
| nyatla | 20:3b0b444b4deb | 472 | } |
| nyatla | 20:3b0b444b4deb | 473 | //タイムアウト確認 |
| nyatla | 20:3b0b444b4deb | 474 | if(NyLPC_cStopwatch_isExpired(i_timer)){ |
| nyatla | 20:3b0b444b4deb | 475 | return -1; |
| nyatla | 20:3b0b444b4deb | 476 | } |
| nyatla | 20:3b0b444b4deb | 477 | }; |
| nyatla | 37:fc4b4fd6a649 | 478 | lockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 479 | //ペイロードがある場合のみ、相手のwindowサイズが0以上になるのを待つ。 |
| nyatla | 0:142ee8b12fef | 480 | if(i_len>0){ |
| nyatla | 0:142ee8b12fef | 481 | while(i_inst->uip_connr.peer_win==0){ |
| nyatla | 37:fc4b4fd6a649 | 482 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 483 | //時間切れならエラー。 |
| nyatla | 0:142ee8b12fef | 484 | if(NyLPC_cStopwatch_isExpired(i_timer)){ |
| nyatla | 0:142ee8b12fef | 485 | return -1; |
| nyatla | 0:142ee8b12fef | 486 | } |
| nyatla | 0:142ee8b12fef | 487 | NyLPC_cThread_yield(); |
| nyatla | 37:fc4b4fd6a649 | 488 | lockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 489 | } |
| nyatla | 0:142ee8b12fef | 490 | } |
| nyatla | 0:142ee8b12fef | 491 | //送信キューの取得 |
| nyatla | 0:142ee8b12fef | 492 | txq=getTxQ(i_inst,i_timer); |
| nyatla | 0:142ee8b12fef | 493 | //送信キューが取れなかった。 |
| nyatla | 0:142ee8b12fef | 494 | if(txq==NULL){ |
| nyatla | 0:142ee8b12fef | 495 | //シーケンス番号をロールバックできないので、エラーとする。 |
| nyatla | 37:fc4b4fd6a649 | 496 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 497 | NyLPC_cUipService_releaseTxBuf(buf); |
| nyatla | 0:142ee8b12fef | 498 | return -1; |
| nyatla | 0:142ee8b12fef | 499 | } |
| nyatla | 0:142ee8b12fef | 500 | //IPv4ペイロードの書き込み |
| nyatla | 0:142ee8b12fef | 501 | NyLPC_cIPv4Payload_setTxBuf(&(txq->data),buf); |
| nyatla | 0:142ee8b12fef | 502 | |
| nyatla | 0:142ee8b12fef | 503 | //送信バッファを基準とした送信サイズを計算 |
| nyatla | 0:142ee8b12fef | 504 | s-=SIZE_OF_IPv4_TCPIP_HEADER; |
| nyatla | 0:142ee8b12fef | 505 | //送信サイズよりMMSが小さければ、送信サイズを修正 |
| nyatla | 0:142ee8b12fef | 506 | if(i_inst->uip_connr.peer_mss<s){ |
| nyatla | 0:142ee8b12fef | 507 | s=i_inst->uip_connr.peer_mss; |
| nyatla | 0:142ee8b12fef | 508 | } |
| nyatla | 0:142ee8b12fef | 509 | //送信サイズよりpeerのウインドウサイズが小さければ修正 |
| nyatla | 0:142ee8b12fef | 510 | if(i_inst->uip_connr.peer_win<s){ |
| nyatla | 0:142ee8b12fef | 511 | s=i_inst->uip_connr.peer_win; |
| nyatla | 0:142ee8b12fef | 512 | } |
| nyatla | 0:142ee8b12fef | 513 | //送信サイズより、データサイズが小さければ、送信サイズを修正 |
| nyatla | 0:142ee8b12fef | 514 | if(i_len<s){ |
| nyatla | 0:142ee8b12fef | 515 | s=i_len; |
| nyatla | 0:142ee8b12fef | 516 | } |
| nyatla | 0:142ee8b12fef | 517 | //ACK番号の計算 |
| nyatla | 57:bc4330dfa62f | 518 | next_ack=i_inst->uip_connr.snd_nxt32+s+(((i_tcpf&(TCP_FIN|TCP_SYN))!=0x00)?1:0); |
| nyatla | 0:142ee8b12fef | 519 | txq->rto32=i_inst->uip_connr.current_rto32; |
| nyatla | 0:142ee8b12fef | 520 | txq->tick_of_sent=NyLPC_cStopwatch_now(); |
| nyatla | 0:142ee8b12fef | 521 | |
| nyatla | 0:142ee8b12fef | 522 | //パケットの書き込み |
| nyatla | 0:142ee8b12fef | 523 | setPacket(i_inst,&(txq->data),i_tcpf,i_buf,s); |
| nyatla | 0:142ee8b12fef | 524 | //シーケンス番号の更新 |
| nyatla | 0:142ee8b12fef | 525 | i_inst->uip_connr.snd_nxt32=next_ack; |
| nyatla | 0:142ee8b12fef | 526 | //Peerのウインドウサイズを更新 |
| nyatla | 0:142ee8b12fef | 527 | i_inst->uip_connr.peer_win-=s; |
| nyatla | 0:142ee8b12fef | 528 | //ACK番号の返却 |
| nyatla | 0:142ee8b12fef | 529 | *o_ack=txq->ackno=NyLPC_HTONL(next_ack); |
| nyatla | 37:fc4b4fd6a649 | 530 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 531 | NyLPC_cUipService_sendIPv4Tx(buf); |
| nyatla | 0:142ee8b12fef | 532 | return s; |
| nyatla | 0:142ee8b12fef | 533 | } |
| nyatla | 0:142ee8b12fef | 534 | /** |
| nyatla | 0:142ee8b12fef | 535 | * RSTを1フレームだけ送信します。 |
| nyatla | 0:142ee8b12fef | 536 | * この関数は、クローズドステータスのソケットにしてからコールします。 |
| nyatla | 0:142ee8b12fef | 537 | * この関数は、アンロック状態でコールしてね。 |
| nyatla | 0:142ee8b12fef | 538 | */ |
| nyatla | 0:142ee8b12fef | 539 | static void sendRst(NyLPC_TcTcpSocket_t* i_inst) |
| nyatla | 0:142ee8b12fef | 540 | { |
| nyatla | 0:142ee8b12fef | 541 | NyLPC_TcIPv4Payload_t ipv4; |
| nyatla | 0:142ee8b12fef | 542 | NyLPC_TUInt16 s; |
| nyatla | 0:142ee8b12fef | 543 | void* buf; |
| nyatla | 0:142ee8b12fef | 544 | |
| nyatla | 0:142ee8b12fef | 545 | NyLPC_Assert(i_inst->tcpstateflags==UIP_CLOSED); |
| nyatla | 0:142ee8b12fef | 546 | //ペイロードライタの初期化 |
| nyatla | 0:142ee8b12fef | 547 | NyLPC_cIPv4Payload_initialize(&ipv4); |
| nyatla | 0:142ee8b12fef | 548 | |
| nyatla | 0:142ee8b12fef | 549 | //IPヘッダ+10バイトくらい。 |
| nyatla | 20:3b0b444b4deb | 550 | //@bug バッファが取れるまで通信がブロックするの。ここはなんとかしないと。 |
| nyatla | 20:3b0b444b4deb | 551 | do{ |
| nyatla | 20:3b0b444b4deb | 552 | buf=NyLPC_cUipService_allocTxBuf((SIZE_OF_IPv4_TCPIP_HEADER)+5,&s); |
| nyatla | 20:3b0b444b4deb | 553 | }while(buf==NULL); |
| nyatla | 37:fc4b4fd6a649 | 554 | lockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 555 | NyLPC_cIPv4Payload_setTxBuf(&ipv4,buf); |
| nyatla | 0:142ee8b12fef | 556 | i_inst->uip_connr.snd_nxt32++; |
| nyatla | 0:142ee8b12fef | 557 | setPacket(i_inst,&ipv4,TCP_RST|TCP_ACK,buf,0); |
| nyatla | 37:fc4b4fd6a649 | 558 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 559 | |
| nyatla | 0:142ee8b12fef | 560 | NyLPC_cUipService_sendIPv4Tx(buf); |
| nyatla | 0:142ee8b12fef | 561 | NyLPC_cUipService_releaseTxBuf(buf); |
| nyatla | 0:142ee8b12fef | 562 | NyLPC_cIPv4Payload_finalize(&ipv4); |
| nyatla | 0:142ee8b12fef | 563 | return; |
| nyatla | 0:142ee8b12fef | 564 | } |
| nyatla | 0:142ee8b12fef | 565 | |
| nyatla | 0:142ee8b12fef | 566 | |
| nyatla | 0:142ee8b12fef | 567 | |
| nyatla | 0:142ee8b12fef | 568 | /** |
| nyatla | 37:fc4b4fd6a649 | 569 | * 受信データをバッファに書き込む。 |
| nyatla | 0:142ee8b12fef | 570 | * 十分な空き領域がない場合、失敗する。 |
| nyatla | 0:142ee8b12fef | 571 | * この関数は、ロックして実行してください。 |
| nyatla | 0:142ee8b12fef | 572 | */ |
| nyatla | 0:142ee8b12fef | 573 | static NyLPC_TBool addRecvData(NyLPC_TcTcpSocket_t* i_inst,void* i_data,NyLPC_TUInt16 i_data_size) |
| nyatla | 0:142ee8b12fef | 574 | { |
| nyatla | 0:142ee8b12fef | 575 | //受信データサイズを確認 |
| nyatla | 0:142ee8b12fef | 576 | if(NyLPC_cFifoBuffer_getSpace(&(i_inst->rxbuf))>=i_data_size){ |
| nyatla | 0:142ee8b12fef | 577 | //バッファに格納可能なら、格納。 |
| nyatla | 0:142ee8b12fef | 578 | NyLPC_cFifoBuffer_push(&(i_inst->rxbuf),i_data,i_data_size); |
| nyatla | 0:142ee8b12fef | 579 | }else{ |
| nyatla | 0:142ee8b12fef | 580 | //エラー:ドロップする。 |
| nyatla | 0:142ee8b12fef | 581 | return NyLPC_TBool_FALSE; |
| nyatla | 0:142ee8b12fef | 582 | } |
| nyatla | 57:bc4330dfa62f | 583 | |
| nyatla | 0:142ee8b12fef | 584 | return NyLPC_TBool_TRUE; |
| nyatla | 0:142ee8b12fef | 585 | } |
| nyatla | 0:142ee8b12fef | 586 | |
| nyatla | 0:142ee8b12fef | 587 | |
| nyatla | 0:142ee8b12fef | 588 | |
| nyatla | 0:142ee8b12fef | 589 | |
| nyatla | 0:142ee8b12fef | 590 | /** |
| nyatla | 0:142ee8b12fef | 591 | * Public function |
| nyatla | 0:142ee8b12fef | 592 | */ |
| nyatla | 0:142ee8b12fef | 593 | |
| nyatla | 57:bc4330dfa62f | 594 | 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) |
| nyatla | 57:bc4330dfa62f | 595 | { |
| nyatla | 57:bc4330dfa62f | 596 | volatile NyLPC_TUInt8 f; |
| nyatla | 57:bc4330dfa62f | 597 | NyLPC_TUInt32 sq; |
| nyatla | 57:bc4330dfa62f | 598 | NyLPC_TcStopwatch_t sw; |
| nyatla | 57:bc4330dfa62f | 599 | NyLPC_TUInt16 lport; |
| nyatla | 57:bc4330dfa62f | 600 | lockResource(i_inst); |
| nyatla | 57:bc4330dfa62f | 601 | //ソケットが無効であること。 |
| nyatla | 57:bc4330dfa62f | 602 | if(i_inst->tcpstateflags!=UIP_CLOSED) |
| nyatla | 57:bc4330dfa62f | 603 | { |
| nyatla | 57:bc4330dfa62f | 604 | NyLPC_OnErrorGoto(Error); |
| nyatla | 57:bc4330dfa62f | 605 | } |
| nyatla | 57:bc4330dfa62f | 606 | //ポート番号の取得(lockResourceが他のソケットと共有なので、重複ポートの割当は起こりえない。でもちょっと注意して) |
| nyatla | 57:bc4330dfa62f | 607 | lport=NyLPC_htons(NyLPC_cIPv4_getNewPortNumber(i_inst->_super._parent_ipv4)); |
| nyatla | 57:bc4330dfa62f | 608 | if(lport==0){ |
| nyatla | 57:bc4330dfa62f | 609 | NyLPC_OnErrorGoto(Error); |
| nyatla | 57:bc4330dfa62f | 610 | } |
| nyatla | 57:bc4330dfa62f | 611 | //connectの為の準備 |
| nyatla | 57:bc4330dfa62f | 612 | |
| nyatla | 57:bc4330dfa62f | 613 | //localipとdefault_mmsは別枠で設定 |
| nyatla | 57:bc4330dfa62f | 614 | /* Fill in the necessary fields for the new connection. */ |
| nyatla | 57:bc4330dfa62f | 615 | i_inst->uip_connr.current_rto32 = UIP_TCP_RTO_CONNECTION_INITIAL;//RTOを短くしてARP発行時の再接続短縮を期待する。 |
| nyatla | 57:bc4330dfa62f | 616 | i_inst->uip_connr.lport = lport; |
| nyatla | 57:bc4330dfa62f | 617 | i_inst->uip_connr.rport = NyLPC_htons(i_peer_port); |
| nyatla | 57:bc4330dfa62f | 618 | i_inst->uip_connr.ripaddr=*i_addr; |
| nyatla | 57:bc4330dfa62f | 619 | i_inst->uip_connr.snd_nxt32=iss32;//should be random |
| nyatla | 57:bc4330dfa62f | 620 | /* rcv_nxt should be the seqno from the incoming packet + 1. */ |
| nyatla | 57:bc4330dfa62f | 621 | i_inst->uip_connr.rcv_nxt32=0; |
| nyatla | 57:bc4330dfa62f | 622 | //MSSの設定 |
| nyatla | 57:bc4330dfa62f | 623 | i_inst->uip_connr.peer_mss=i_inst->uip_connr.default_mss; |
| nyatla | 57:bc4330dfa62f | 624 | i_inst->uip_connr.peer_win=1;//periodicの再送信を期待するために相手のWindowサイズは1と仮定する。 |
| nyatla | 57:bc4330dfa62f | 625 | NyLPC_cFifoBuffer_clear(&(i_inst->rxbuf)); |
| nyatla | 57:bc4330dfa62f | 626 | //ここでステータスがかわる。 |
| nyatla | 57:bc4330dfa62f | 627 | i_inst->tcpstateflags = UIP_SYN_SENT; |
| nyatla | 57:bc4330dfa62f | 628 | //前回のデータが残っていた場合の保険 |
| nyatla | 57:bc4330dfa62f | 629 | if(i_inst->txbuf.rp!=i_inst->txbuf.wp){ |
| nyatla | 57:bc4330dfa62f | 630 | resetTxQWithUnlock(i_inst); |
| nyatla | 57:bc4330dfa62f | 631 | }else{ |
| nyatla | 57:bc4330dfa62f | 632 | unlockResource(i_inst); |
| nyatla | 57:bc4330dfa62f | 633 | } |
| nyatla | 57:bc4330dfa62f | 634 | |
| nyatla | 57:bc4330dfa62f | 635 | NyLPC_cStopwatch_initialize(&sw); |
| nyatla | 57:bc4330dfa62f | 636 | |
| nyatla | 57:bc4330dfa62f | 637 | NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec); |
| nyatla | 57:bc4330dfa62f | 638 | if(sendWithRetransmit(i_inst,TCP_SYN,NULL,0,&sw,&sq)==0){ |
| nyatla | 57:bc4330dfa62f | 639 | //ちょっと待つ。 |
| nyatla | 57:bc4330dfa62f | 640 | NyLPC_cThread_yield(); |
| nyatla | 57:bc4330dfa62f | 641 | //キューにあるTXが消えるのを待つ。 |
| nyatla | 57:bc4330dfa62f | 642 | if(waitForTxRemove(i_inst,sq,&sw)){ |
| nyatla | 57:bc4330dfa62f | 643 | //ACK受信に成功して、TXが消失 |
| nyatla | 57:bc4330dfa62f | 644 | NyLPC_cStopwatch_finalize(&sw); |
| nyatla | 57:bc4330dfa62f | 645 | return NyLPC_TBool_TRUE; |
| nyatla | 57:bc4330dfa62f | 646 | } |
| nyatla | 57:bc4330dfa62f | 647 | } |
| nyatla | 57:bc4330dfa62f | 648 | //ロックして、強制的なステータス遷移 |
| nyatla | 57:bc4330dfa62f | 649 | lockResource(i_inst); |
| nyatla | 57:bc4330dfa62f | 650 | f=i_inst->tcpstateflags; |
| nyatla | 57:bc4330dfa62f | 651 | if(f!=UIP_CLOSED){ |
| nyatla | 57:bc4330dfa62f | 652 | //もし、強制CLOSE遷移であれば、RSTも送信。 |
| nyatla | 57:bc4330dfa62f | 653 | i_inst->tcpstateflags=UIP_CLOSED; |
| nyatla | 57:bc4330dfa62f | 654 | unlockResource(i_inst); |
| nyatla | 57:bc4330dfa62f | 655 | sendRst(i_inst); |
| nyatla | 57:bc4330dfa62f | 656 | }else{ |
| nyatla | 57:bc4330dfa62f | 657 | unlockResource(i_inst); |
| nyatla | 57:bc4330dfa62f | 658 | } |
| nyatla | 57:bc4330dfa62f | 659 | return NyLPC_TBool_FALSE; |
| nyatla | 57:bc4330dfa62f | 660 | Error: |
| nyatla | 57:bc4330dfa62f | 661 | unlockResource(i_inst); |
| nyatla | 57:bc4330dfa62f | 662 | return NyLPC_TBool_FALSE; |
| nyatla | 57:bc4330dfa62f | 663 | } |
| nyatla | 57:bc4330dfa62f | 664 | |
| nyatla | 0:142ee8b12fef | 665 | /** |
| nyatla | 0:142ee8b12fef | 666 | * この関数は、UIP_SYN_RCVDステータスのソケットを、ESTABLISHEDへ遷移させます。 |
| nyatla | 0:142ee8b12fef | 667 | * cTcpListener_listen関数を通過したインスタンスに実行してください。 |
| nyatla | 0:142ee8b12fef | 668 | * この関数は、アプリケーションが呼び出します。 |
| nyatla | 0:142ee8b12fef | 669 | * @return |
| nyatla | 0:142ee8b12fef | 670 | * |
| nyatla | 0:142ee8b12fef | 671 | */ |
| nyatla | 0:142ee8b12fef | 672 | NyLPC_TBool NyLPC_cTcpSocket_accept(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_wait_in_msec) |
| nyatla | 0:142ee8b12fef | 673 | { |
| nyatla | 0:142ee8b12fef | 674 | volatile NyLPC_TUInt8 f; |
| nyatla | 0:142ee8b12fef | 675 | NyLPC_TUInt32 sq; |
| nyatla | 0:142ee8b12fef | 676 | NyLPC_TcStopwatch_t sw; |
| nyatla | 0:142ee8b12fef | 677 | |
| nyatla | 0:142ee8b12fef | 678 | NyLPC_cStopwatch_initialize(&sw); |
| nyatla | 0:142ee8b12fef | 679 | //ステータスチェック |
| nyatla | 0:142ee8b12fef | 680 | f=i_inst->tcpstateflags; |
| nyatla | 0:142ee8b12fef | 681 | switch(f) |
| nyatla | 0:142ee8b12fef | 682 | { |
| nyatla | 0:142ee8b12fef | 683 | case UIP_ESTABLISHED: |
| nyatla | 0:142ee8b12fef | 684 | return NyLPC_TBool_TRUE; |
| nyatla | 0:142ee8b12fef | 685 | case UIP_SYN_RCVD: |
| nyatla | 0:142ee8b12fef | 686 | //処理対象 |
| nyatla | 0:142ee8b12fef | 687 | break; |
| nyatla | 0:142ee8b12fef | 688 | default: |
| nyatla | 0:142ee8b12fef | 689 | return NyLPC_TBool_FALSE; |
| nyatla | 0:142ee8b12fef | 690 | } |
| nyatla | 0:142ee8b12fef | 691 | NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec); |
| nyatla | 0:142ee8b12fef | 692 | if(sendWithRetransmit(i_inst,TCP_SYN|TCP_ACK,NULL,0,&sw,&sq)==0){ |
| nyatla | 0:142ee8b12fef | 693 | //ちょっと待つ。 |
| nyatla | 0:142ee8b12fef | 694 | NyLPC_cThread_yield(); |
| nyatla | 0:142ee8b12fef | 695 | //キューにあるTXが消えるのを待つ。 |
| nyatla | 0:142ee8b12fef | 696 | if(waitForTxRemove(i_inst,sq,&sw)){ |
| nyatla | 0:142ee8b12fef | 697 | //ACK受信に成功して、TXが消失 |
| nyatla | 0:142ee8b12fef | 698 | NyLPC_cStopwatch_finalize(&sw); |
| nyatla | 0:142ee8b12fef | 699 | return NyLPC_TBool_TRUE; |
| nyatla | 0:142ee8b12fef | 700 | } |
| nyatla | 0:142ee8b12fef | 701 | } |
| nyatla | 0:142ee8b12fef | 702 | //ロックして、強制的なステータス遷移 |
| nyatla | 37:fc4b4fd6a649 | 703 | lockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 704 | f=i_inst->tcpstateflags; |
| nyatla | 0:142ee8b12fef | 705 | if(f!=UIP_CLOSED){ |
| nyatla | 57:bc4330dfa62f | 706 | //もし、強制CLOSE遷移であれば、RSTも送信。 |
| nyatla | 0:142ee8b12fef | 707 | i_inst->tcpstateflags=UIP_CLOSED; |
| nyatla | 57:bc4330dfa62f | 708 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 709 | sendRst(i_inst); |
| nyatla | 57:bc4330dfa62f | 710 | }else{ |
| nyatla | 57:bc4330dfa62f | 711 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 712 | } |
| nyatla | 0:142ee8b12fef | 713 | return NyLPC_TBool_FALSE; |
| nyatla | 0:142ee8b12fef | 714 | } |
| nyatla | 0:142ee8b12fef | 715 | |
| nyatla | 0:142ee8b12fef | 716 | |
| nyatla | 0:142ee8b12fef | 717 | /** |
| nyatla | 0:142ee8b12fef | 718 | * この関数は、ソケットの受信バッファの読み取り位置と、読み出せるデータサイズを返却します。 |
| nyatla | 0:142ee8b12fef | 719 | * 関数はポインターを返却するだけで、バッファの読み取り位置をシークしません。 |
| nyatla | 0:142ee8b12fef | 720 | * シークするにはNyLPC_cTcpSocket_pseekを使います。 |
| nyatla | 0:142ee8b12fef | 721 | */ |
| nyatla | 0:142ee8b12fef | 722 | NyLPC_TInt32 NyLPC_cTcpSocket_precv(NyLPC_TcTcpSocket_t* i_inst,const void** o_buf_ptr,NyLPC_TUInt32 i_wait_msec) |
| nyatla | 0:142ee8b12fef | 723 | { |
| nyatla | 0:142ee8b12fef | 724 | volatile NyLPC_TUInt8 st; |
| nyatla | 0:142ee8b12fef | 725 | NyLPC_TUInt16 rlen; |
| nyatla | 0:142ee8b12fef | 726 | //タイマを生成 |
| nyatla | 0:142ee8b12fef | 727 | NyLPC_TcStopwatch_t sw; |
| nyatla | 0:142ee8b12fef | 728 | NyLPC_cStopwatch_initialize(&sw); |
| nyatla | 0:142ee8b12fef | 729 | |
| nyatla | 0:142ee8b12fef | 730 | //ESTABLISHED以外の場合は、エラー。 |
| nyatla | 0:142ee8b12fef | 731 | NyLPC_cStopwatch_setNow(&sw); |
| nyatla | 0:142ee8b12fef | 732 | while(NyLPC_cStopwatch_elapseInMsec(&sw)<i_wait_msec) |
| nyatla | 0:142ee8b12fef | 733 | { |
| nyatla | 0:142ee8b12fef | 734 | //読み出しバッファ情報のコピー |
| nyatla | 0:142ee8b12fef | 735 | |
| nyatla | 0:142ee8b12fef | 736 | //MUTEX LOCK |
| nyatla | 37:fc4b4fd6a649 | 737 | lockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 738 | st=i_inst->tcpstateflags; |
| nyatla | 0:142ee8b12fef | 739 | rlen=NyLPC_cFifoBuffer_getLength(&(i_inst->rxbuf)); |
| nyatla | 0:142ee8b12fef | 740 | *o_buf_ptr=NyLPC_cFifoBuffer_getPtr(&(i_inst->rxbuf)); |
| nyatla | 0:142ee8b12fef | 741 | //MUTEX UNLOCK |
| nyatla | 37:fc4b4fd6a649 | 742 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 743 | |
| nyatla | 0:142ee8b12fef | 744 | //バッファが空の場合は、ステータスチェック。ESTABLISHEDでなければ、エラー(PASVCLOSE等の場合) |
| nyatla | 0:142ee8b12fef | 745 | switch(st){ |
| nyatla | 0:142ee8b12fef | 746 | case UIP_ESTABLISHED: |
| nyatla | 0:142ee8b12fef | 747 | if(rlen>0){ |
| nyatla | 0:142ee8b12fef | 748 | //バッファにパケットがあれば返却 |
| nyatla | 0:142ee8b12fef | 749 | NyLPC_cStopwatch_finalize(&sw); |
| nyatla | 0:142ee8b12fef | 750 | return rlen; |
| nyatla | 0:142ee8b12fef | 751 | } |
| nyatla | 0:142ee8b12fef | 752 | break; |
| nyatla | 0:142ee8b12fef | 753 | case UIP_CLOSE_WAIT: |
| nyatla | 0:142ee8b12fef | 754 | if(rlen>0){ |
| nyatla | 0:142ee8b12fef | 755 | //バッファにパケットがあれば返却 |
| nyatla | 0:142ee8b12fef | 756 | NyLPC_cStopwatch_finalize(&sw); |
| nyatla | 0:142ee8b12fef | 757 | return rlen; |
| nyatla | 0:142ee8b12fef | 758 | } |
| nyatla | 0:142ee8b12fef | 759 | //引き続きエラー処理 |
| nyatla | 0:142ee8b12fef | 760 | default: |
| nyatla | 0:142ee8b12fef | 761 | //他の場合はエラー |
| nyatla | 0:142ee8b12fef | 762 | NyLPC_cStopwatch_finalize(&sw); |
| nyatla | 0:142ee8b12fef | 763 | return -1; |
| nyatla | 0:142ee8b12fef | 764 | } |
| nyatla | 0:142ee8b12fef | 765 | //タスクスイッチ |
| nyatla | 0:142ee8b12fef | 766 | NyLPC_cThread_yield(); |
| nyatla | 0:142ee8b12fef | 767 | }; |
| nyatla | 0:142ee8b12fef | 768 | //規定時間内に受信が成功しなかった。 |
| nyatla | 0:142ee8b12fef | 769 | NyLPC_cStopwatch_finalize(&sw); |
| nyatla | 0:142ee8b12fef | 770 | return 0; |
| nyatla | 0:142ee8b12fef | 771 | } |
| nyatla | 0:142ee8b12fef | 772 | /** |
| nyatla | 0:142ee8b12fef | 773 | * 受信バッファをシークします。 |
| nyatla | 0:142ee8b12fef | 774 | * シーク後に、遅延ACKを送出します。 |
| nyatla | 0:142ee8b12fef | 775 | */ |
| nyatla | 0:142ee8b12fef | 776 | void NyLPC_cTcpSocket_pseek(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt16 i_seek) |
| nyatla | 0:142ee8b12fef | 777 | { |
| nyatla | 0:142ee8b12fef | 778 | NyLPC_TcIPv4Payload_t ipv4payload; |
| nyatla | 0:142ee8b12fef | 779 | void* buf; |
| nyatla | 0:142ee8b12fef | 780 | NyLPC_TUInt16 s; |
| nyatla | 0:142ee8b12fef | 781 | NyLPC_ArgAssert(i_seek<=NyLPC_cFifoBuffer_getLength(&(i_inst->rxbuf))); |
| nyatla | 0:142ee8b12fef | 782 | if(i_seek==0){ |
| nyatla | 0:142ee8b12fef | 783 | return; |
| nyatla | 0:142ee8b12fef | 784 | } |
| nyatla | 0:142ee8b12fef | 785 | //ペイロードライタの初期化 |
| nyatla | 0:142ee8b12fef | 786 | NyLPC_cIPv4Payload_initialize(&ipv4payload); |
| nyatla | 0:142ee8b12fef | 787 | |
| nyatla | 0:142ee8b12fef | 788 | //ACK送信バッファの取得 |
| nyatla | 20:3b0b444b4deb | 789 | //@bug バッファが取れるまで通信がブロックするの。ここはなんとかしないと。 |
| nyatla | 20:3b0b444b4deb | 790 | do{ |
| nyatla | 20:3b0b444b4deb | 791 | buf=NyLPC_cUipService_allocTxBuf((SIZE_OF_IPv4_TCPIP_HEADER)+5,&s); |
| nyatla | 20:3b0b444b4deb | 792 | }while(buf==NULL); |
| nyatla | 0:142ee8b12fef | 793 | |
| nyatla | 0:142ee8b12fef | 794 | //MUTEX LOCK |
| nyatla | 37:fc4b4fd6a649 | 795 | lockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 796 | |
| nyatla | 0:142ee8b12fef | 797 | //受信バッファを読み出しシーク |
| nyatla | 0:142ee8b12fef | 798 | NyLPC_cFifoBuffer_pop(&(i_inst->rxbuf),i_seek); |
| nyatla | 0:142ee8b12fef | 799 | //ACKパケットの生成 |
| nyatla | 0:142ee8b12fef | 800 | NyLPC_cIPv4Payload_setTxBuf(&ipv4payload,buf); |
| nyatla | 0:142ee8b12fef | 801 | setPacket(i_inst,&ipv4payload,TCP_ACK,buf,0); |
| nyatla | 37:fc4b4fd6a649 | 802 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 803 | //ACK送信 |
| nyatla | 0:142ee8b12fef | 804 | NyLPC_cUipService_sendIPv4Tx(buf); |
| nyatla | 0:142ee8b12fef | 805 | NyLPC_cUipService_releaseTxBuf(buf); |
| nyatla | 0:142ee8b12fef | 806 | //ペイロードライタの破棄 |
| nyatla | 0:142ee8b12fef | 807 | NyLPC_cIPv4Payload_finalize(&ipv4payload); |
| nyatla | 0:142ee8b12fef | 808 | } |
| nyatla | 0:142ee8b12fef | 809 | |
| nyatla | 0:142ee8b12fef | 810 | /** |
| nyatla | 0:142ee8b12fef | 811 | * See header file. |
| nyatla | 0:142ee8b12fef | 812 | */ |
| nyatla | 0:142ee8b12fef | 813 | void* NyLPC_cTcpSocket_allocSendBuf(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_buf_size,NyLPC_TUInt32 i_wait_in_msec) |
| nyatla | 0:142ee8b12fef | 814 | { |
| nyatla | 0:142ee8b12fef | 815 | NyLPC_TUInt16 s; |
| nyatla | 0:142ee8b12fef | 816 | void* buf; |
| nyatla | 0:142ee8b12fef | 817 | NyLPC_TcStopwatch_t sw; |
| nyatla | 0:142ee8b12fef | 818 | |
| nyatla | 0:142ee8b12fef | 819 | NyLPC_cStopwatch_initialize(&sw); |
| nyatla | 0:142ee8b12fef | 820 | NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec); |
| nyatla | 0:142ee8b12fef | 821 | |
| nyatla | 0:142ee8b12fef | 822 | //送信バッファを取得 |
| nyatla | 20:3b0b444b4deb | 823 | //@bug バッファが取れるまで通信がブロックするの。ここはなんとかしないと。 |
| nyatla | 20:3b0b444b4deb | 824 | for(;;){ |
| nyatla | 37:fc4b4fd6a649 | 825 | //ESTABLISHED以外に非同期遷移 |
| nyatla | 37:fc4b4fd6a649 | 826 | if(i_inst->tcpstateflags!=UIP_ESTABLISHED){ |
| nyatla | 37:fc4b4fd6a649 | 827 | NyLPC_cStopwatch_finalize(&sw); |
| nyatla | 20:3b0b444b4deb | 828 | return NULL; |
| nyatla | 20:3b0b444b4deb | 829 | } |
| nyatla | 20:3b0b444b4deb | 830 | buf=NyLPC_cUipService_allocTxBuf(i_hint+(SIZE_OF_IPv4_TCPIP_HEADER),&s); |
| nyatla | 20:3b0b444b4deb | 831 | if(buf!=NULL){ |
| nyatla | 20:3b0b444b4deb | 832 | break; |
| nyatla | 20:3b0b444b4deb | 833 | } |
| nyatla | 37:fc4b4fd6a649 | 834 | //タイムアウト時もエラー |
| nyatla | 37:fc4b4fd6a649 | 835 | if(NyLPC_cStopwatch_isExpired(&sw)){ |
| nyatla | 37:fc4b4fd6a649 | 836 | NyLPC_cStopwatch_finalize(&sw); |
| nyatla | 37:fc4b4fd6a649 | 837 | return NULL; |
| nyatla | 37:fc4b4fd6a649 | 838 | } |
| nyatla | 20:3b0b444b4deb | 839 | } |
| nyatla | 20:3b0b444b4deb | 840 | |
| nyatla | 37:fc4b4fd6a649 | 841 | //@todo 前段処理と順番を入れ替えて、要求サイズとpeerのwinのうち、小さいほうを割り当てたほうが良くない? |
| nyatla | 37:fc4b4fd6a649 | 842 | //ここで相手のwin待ちをする理由は、相手に確実に受け取れるサイズを決定する為。 |
| nyatla | 37:fc4b4fd6a649 | 843 | lockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 844 | //ペイロードがある場合のみ、相手のwindowサイズが0以上になるのを待つ。 |
| nyatla | 0:142ee8b12fef | 845 | while(i_inst->uip_connr.peer_win==0){ |
| nyatla | 37:fc4b4fd6a649 | 846 | unlockResource(i_inst); |
| nyatla | 20:3b0b444b4deb | 847 | //ESTABLISHED以外に非同期遷移 orタイムアウト確認 |
| nyatla | 20:3b0b444b4deb | 848 | if(NyLPC_cStopwatch_isExpired(&sw)||(i_inst->tcpstateflags!=UIP_ESTABLISHED)){ |
| nyatla | 20:3b0b444b4deb | 849 | NyLPC_cUipService_releaseTxBuf(buf); |
| nyatla | 0:142ee8b12fef | 850 | NyLPC_cStopwatch_finalize(&sw); |
| nyatla | 0:142ee8b12fef | 851 | return NULL; |
| nyatla | 0:142ee8b12fef | 852 | } |
| nyatla | 0:142ee8b12fef | 853 | NyLPC_cThread_yield(); |
| nyatla | 37:fc4b4fd6a649 | 854 | lockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 855 | } |
| nyatla | 0:142ee8b12fef | 856 | //送信バッファを基準とした送信サイズを計算 |
| nyatla | 0:142ee8b12fef | 857 | s-=SIZE_OF_IPv4_TCPIP_HEADER; |
| nyatla | 0:142ee8b12fef | 858 | //送信サイズよりMMSが小さければ、送信サイズを修正 |
| nyatla | 0:142ee8b12fef | 859 | if(i_inst->uip_connr.peer_mss<s){ |
| nyatla | 0:142ee8b12fef | 860 | s=i_inst->uip_connr.peer_mss; |
| nyatla | 0:142ee8b12fef | 861 | } |
| nyatla | 0:142ee8b12fef | 862 | //送信サイズよりpeerのウインドウサイズが小さければ修正 |
| nyatla | 0:142ee8b12fef | 863 | if(i_inst->uip_connr.peer_win<s){ |
| nyatla | 0:142ee8b12fef | 864 | s=i_inst->uip_connr.peer_win; |
| nyatla | 0:142ee8b12fef | 865 | } |
| nyatla | 37:fc4b4fd6a649 | 866 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 867 | //バッファサイズ確定。 |
| nyatla | 0:142ee8b12fef | 868 | *o_buf_size=s; |
| nyatla | 0:142ee8b12fef | 869 | NyLPC_cStopwatch_finalize(&sw); |
| nyatla | 0:142ee8b12fef | 870 | return (NyLPC_TUInt8*)buf+SIZE_OF_IPv4_TCPIP_HEADER; |
| nyatla | 0:142ee8b12fef | 871 | } |
| nyatla | 0:142ee8b12fef | 872 | /** |
| nyatla | 0:142ee8b12fef | 873 | * See Header file. |
| nyatla | 0:142ee8b12fef | 874 | */ |
| nyatla | 0:142ee8b12fef | 875 | void NyLPC_cTcpSocket_releaseSendBuf(NyLPC_TcTcpSocket_t* i_inst,void* i_buf_ptr) |
| nyatla | 0:142ee8b12fef | 876 | { |
| nyatla | 0:142ee8b12fef | 877 | NyLPC_cUipService_releaseTxBuf((NyLPC_TUInt8*)i_buf_ptr-SIZE_OF_IPv4_TCPIP_HEADER); |
| nyatla | 0:142ee8b12fef | 878 | } |
| nyatla | 0:142ee8b12fef | 879 | |
| nyatla | 0:142ee8b12fef | 880 | |
| nyatla | 0:142ee8b12fef | 881 | /** |
| nyatla | 0:142ee8b12fef | 882 | * 事前にAllocしたTxパケットを送信します。 |
| nyatla | 0:142ee8b12fef | 883 | * このAPIはゼロコピー送信をサポートするためのものです。 |
| nyatla | 0:142ee8b12fef | 884 | * @param i_buf_ptr |
| nyatla | 0:142ee8b12fef | 885 | * allocSendBufで取得したメモリを指定します。 |
| nyatla | 0:142ee8b12fef | 886 | * @return |
| nyatla | 0:142ee8b12fef | 887 | * 関数が失敗した場合、i_buf_ptrは「開放されません。」 |
| nyatla | 0:142ee8b12fef | 888 | */ |
| nyatla | 0:142ee8b12fef | 889 | NyLPC_TBool NyLPC_cTcpSocket_psend(NyLPC_TcTcpSocket_t* i_inst,void* i_buf_ptr,int i_len,NyLPC_TUInt32 i_wait_in_msec) |
| nyatla | 0:142ee8b12fef | 890 | { |
| nyatla | 0:142ee8b12fef | 891 | struct NyLPC_TcTcpSocket_TxQItem* txq; |
| nyatla | 0:142ee8b12fef | 892 | void* buf; |
| nyatla | 0:142ee8b12fef | 893 | NyLPC_TcStopwatch_t sw; |
| nyatla | 0:142ee8b12fef | 894 | //ESTABLISHEDでなければエラー |
| nyatla | 0:142ee8b12fef | 895 | if(i_inst->tcpstateflags!=UIP_ESTABLISHED){ |
| nyatla | 0:142ee8b12fef | 896 | //ESTABLISHEDでなければエラー |
| nyatla | 0:142ee8b12fef | 897 | return NyLPC_TBool_FALSE; |
| nyatla | 0:142ee8b12fef | 898 | } |
| nyatla | 20:3b0b444b4deb | 899 | //送信データ0なら何もしない。 |
| nyatla | 0:142ee8b12fef | 900 | if(i_len<1){ |
| nyatla | 20:3b0b444b4deb | 901 | NyLPC_cTcpSocket_releaseSendBuf(i_inst,i_buf_ptr); |
| nyatla | 0:142ee8b12fef | 902 | return NyLPC_TBool_TRUE; |
| nyatla | 0:142ee8b12fef | 903 | } |
| nyatla | 0:142ee8b12fef | 904 | NyLPC_cStopwatch_initialize(&sw); |
| nyatla | 0:142ee8b12fef | 905 | NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec); |
| nyatla | 0:142ee8b12fef | 906 | |
| nyatla | 0:142ee8b12fef | 907 | //先頭ポインタは、i_buf-sizeof(SIZE_OF_IPv4_TCPIP_HEADER)固定 |
| nyatla | 0:142ee8b12fef | 908 | buf=(NyLPC_TUInt8*)i_buf_ptr-SIZE_OF_IPv4_TCPIP_HEADER; |
| nyatla | 37:fc4b4fd6a649 | 909 | lockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 910 | //送信キューの取得 |
| nyatla | 0:142ee8b12fef | 911 | txq=getTxQ(i_inst,&sw); |
| nyatla | 0:142ee8b12fef | 912 | //送信キューが取れなかった。 |
| nyatla | 0:142ee8b12fef | 913 | if(txq==NULL){ |
| nyatla | 0:142ee8b12fef | 914 | //シーケンス番号をロールバックできないので、エラーとする。 |
| nyatla | 37:fc4b4fd6a649 | 915 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 916 | NyLPC_cStopwatch_finalize(&sw); |
| nyatla | 0:142ee8b12fef | 917 | return NyLPC_TBool_FALSE; |
| nyatla | 0:142ee8b12fef | 918 | } |
| nyatla | 0:142ee8b12fef | 919 | //ここから先はi_bufの所有権はインスタンスになってる。 |
| nyatla | 0:142ee8b12fef | 920 | |
| nyatla | 0:142ee8b12fef | 921 | //IPv4ペイロードの書き込み |
| nyatla | 0:142ee8b12fef | 922 | NyLPC_cIPv4Payload_setTxBuf(&(txq->data),buf); |
| nyatla | 0:142ee8b12fef | 923 | //allocをした時点でwin,mssは考慮されているので、そのままそうしんしる。 |
| nyatla | 0:142ee8b12fef | 924 | //ACK番号の計算 |
| nyatla | 0:142ee8b12fef | 925 | txq->rto32=i_inst->uip_connr.current_rto32; |
| nyatla | 0:142ee8b12fef | 926 | txq->tick_of_sent=NyLPC_cStopwatch_now(); |
| nyatla | 0:142ee8b12fef | 927 | //パケットヘッダの生成 |
| nyatla | 0:142ee8b12fef | 928 | NyLPC_cIPv4Payload_initTcpTx(&(txq->data),0x05,((UIP_TCPH_LEN) / 4),i_len); |
| nyatla | 0:142ee8b12fef | 929 | NyLPC_cIPv4Payload_setTcpTxHeaderByConnection(&(txq->data),&(i_inst->uip_connr),TCP_ACK|TCP_PSH); |
| nyatla | 0:142ee8b12fef | 930 | NyLPC_cIPv4Payload_setTcpWnd(&(txq->data),NyLPC_cFifoBuffer_getSpace(&(i_inst->rxbuf))); |
| nyatla | 0:142ee8b12fef | 931 | NyLPC_cIPv4Payload_closeTcpTxPacket(&(txq->data)); |
| nyatla | 0:142ee8b12fef | 932 | //シーケンス番号の更新 |
| nyatla | 0:142ee8b12fef | 933 | i_inst->uip_connr.snd_nxt32=i_inst->uip_connr.snd_nxt32+i_len; |
| nyatla | 0:142ee8b12fef | 934 | //Peerのウインドウサイズを更新 |
| nyatla | 0:142ee8b12fef | 935 | i_inst->uip_connr.peer_win-=i_len; |
| nyatla | 0:142ee8b12fef | 936 | //ACK番号の返却 |
| nyatla | 0:142ee8b12fef | 937 | txq->ackno=NyLPC_HTONL(i_inst->uip_connr.snd_nxt32); |
| nyatla | 37:fc4b4fd6a649 | 938 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 939 | NyLPC_cUipService_sendIPv4Tx(buf); |
| nyatla | 0:142ee8b12fef | 940 | NyLPC_cStopwatch_finalize(&sw); |
| nyatla | 0:142ee8b12fef | 941 | return NyLPC_TBool_TRUE; |
| nyatla | 0:142ee8b12fef | 942 | } |
| nyatla | 0:142ee8b12fef | 943 | |
| nyatla | 0:142ee8b12fef | 944 | /** |
| nyatla | 0:142ee8b12fef | 945 | * See header file. |
| nyatla | 0:142ee8b12fef | 946 | */ |
| nyatla | 20:3b0b444b4deb | 947 | 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) |
| nyatla | 0:142ee8b12fef | 948 | { |
| nyatla | 20:3b0b444b4deb | 949 | NyLPC_TInt16 hint; |
| nyatla | 20:3b0b444b4deb | 950 | NyLPC_TUInt16 s; |
| nyatla | 20:3b0b444b4deb | 951 | void* buf; |
| nyatla | 0:142ee8b12fef | 952 | if(i_len<1){ |
| nyatla | 0:142ee8b12fef | 953 | return 0; |
| nyatla | 0:142ee8b12fef | 954 | } |
| nyatla | 57:bc4330dfa62f | 955 | hint=(i_len>32767)?32767:i_len; |
| nyatla | 20:3b0b444b4deb | 956 | buf=NyLPC_cTcpSocket_allocSendBuf(i_inst,hint,&s,i_wait_in_msec); |
| nyatla | 20:3b0b444b4deb | 957 | if(buf==NULL){ |
| nyatla | 20:3b0b444b4deb | 958 | return -1; |
| nyatla | 20:3b0b444b4deb | 959 | } |
| nyatla | 20:3b0b444b4deb | 960 | //送信サイズの計算 |
| nyatla | 20:3b0b444b4deb | 961 | s=((NyLPC_TInt32)s<i_len)?s:(NyLPC_TUInt16)i_len; |
| nyatla | 20:3b0b444b4deb | 962 | memcpy(buf,i_buf_ptr,s); |
| nyatla | 20:3b0b444b4deb | 963 | if(!NyLPC_cTcpSocket_psend(i_inst,buf,s,i_wait_in_msec)){ |
| nyatla | 20:3b0b444b4deb | 964 | NyLPC_cTcpSocket_releaseSendBuf(i_inst,buf); |
| nyatla | 37:fc4b4fd6a649 | 965 | return -1;//error |
| nyatla | 20:3b0b444b4deb | 966 | } |
| nyatla | 20:3b0b444b4deb | 967 | return s; |
| nyatla | 0:142ee8b12fef | 968 | } |
| nyatla | 0:142ee8b12fef | 969 | |
| nyatla | 0:142ee8b12fef | 970 | |
| nyatla | 0:142ee8b12fef | 971 | void NyLPC_cTcpSocket_close(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_wait_in_msec) |
| nyatla | 0:142ee8b12fef | 972 | { |
| nyatla | 0:142ee8b12fef | 973 | NyLPC_TcStopwatch_t sw; |
| nyatla | 0:142ee8b12fef | 974 | volatile NyLPC_TUInt8 f; |
| nyatla | 0:142ee8b12fef | 975 | NyLPC_TUInt32 sq; |
| nyatla | 0:142ee8b12fef | 976 | NyLPC_cStopwatch_initialize(&sw); |
| nyatla | 0:142ee8b12fef | 977 | NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec); |
| nyatla | 37:fc4b4fd6a649 | 978 | lockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 979 | |
| nyatla | 0:142ee8b12fef | 980 | f=i_inst->tcpstateflags; |
| nyatla | 0:142ee8b12fef | 981 | //ステータスチェック |
| nyatla | 0:142ee8b12fef | 982 | switch(f) |
| nyatla | 0:142ee8b12fef | 983 | { |
| nyatla | 0:142ee8b12fef | 984 | case UIP_CLOSED: |
| nyatla | 0:142ee8b12fef | 985 | //閉じている。 |
| nyatla | 0:142ee8b12fef | 986 | goto ReturnWithUnlock; |
| nyatla | 0:142ee8b12fef | 987 | case UIP_ESTABLISHED: |
| nyatla | 0:142ee8b12fef | 988 | //アクティブクローズ。 |
| nyatla | 0:142ee8b12fef | 989 | i_inst->tcpstateflags=UIP_FIN_WAIT_1; |
| nyatla | 0:142ee8b12fef | 990 | //送信のために一旦解除 |
| nyatla | 37:fc4b4fd6a649 | 991 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 992 | //FINの送信 |
| nyatla | 0:142ee8b12fef | 993 | if(sendWithRetransmit(i_inst,TCP_FIN|TCP_ACK,NULL,0,&sw,&sq)==0){ |
| nyatla | 0:142ee8b12fef | 994 | //ちょっと待つ。 |
| nyatla | 0:142ee8b12fef | 995 | NyLPC_cThread_yield(); |
| nyatla | 0:142ee8b12fef | 996 | //TXの消去待ち |
| nyatla | 0:142ee8b12fef | 997 | if(waitForTxRemove(i_inst,sq,&sw)){ |
| nyatla | 0:142ee8b12fef | 998 | //再ロック |
| nyatla | 37:fc4b4fd6a649 | 999 | lockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 1000 | //タイムアウトするか、UIP_CLOSED、もしくはTIME_WAITに遷移するのを待つ。(遷移はRxprocで自動的に実行。) |
| nyatla | 0:142ee8b12fef | 1001 | while(!NyLPC_cStopwatch_isExpired(&sw)){ |
| nyatla | 0:142ee8b12fef | 1002 | switch(i_inst->tcpstateflags) |
| nyatla | 0:142ee8b12fef | 1003 | { |
| nyatla | 0:142ee8b12fef | 1004 | case UIP_TIME_WAIT: |
| nyatla | 0:142ee8b12fef | 1005 | i_inst->tcpstateflags=UIP_CLOSED; |
| nyatla | 0:142ee8b12fef | 1006 | case UIP_CLOSED: |
| nyatla | 0:142ee8b12fef | 1007 | NyLPC_Assert(i_inst->txbuf.rp==i_inst->txbuf.wp); |
| nyatla | 0:142ee8b12fef | 1008 | //成功。 |
| nyatla | 0:142ee8b12fef | 1009 | goto ReturnWithUnlock; |
| nyatla | 0:142ee8b12fef | 1010 | case UIP_FIN_WAIT_1: |
| nyatla | 0:142ee8b12fef | 1011 | case UIP_FIN_WAIT_2: |
| nyatla | 0:142ee8b12fef | 1012 | case UIP_CLOSING: |
| nyatla | 0:142ee8b12fef | 1013 | //一時的なアンロック |
| nyatla | 37:fc4b4fd6a649 | 1014 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 1015 | NyLPC_cThread_yield(); |
| nyatla | 37:fc4b4fd6a649 | 1016 | lockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 1017 | default: |
| nyatla | 0:142ee8b12fef | 1018 | break; |
| nyatla | 0:142ee8b12fef | 1019 | } |
| nyatla | 0:142ee8b12fef | 1020 | } |
| nyatla | 37:fc4b4fd6a649 | 1021 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 1022 | } |
| nyatla | 0:142ee8b12fef | 1023 | } |
| nyatla | 0:142ee8b12fef | 1024 | break; |
| nyatla | 0:142ee8b12fef | 1025 | case UIP_CLOSE_WAIT: |
| nyatla | 0:142ee8b12fef | 1026 | //LAST_ACKへ遷移 |
| nyatla | 0:142ee8b12fef | 1027 | i_inst->tcpstateflags=UIP_LAST_ACK; |
| nyatla | 0:142ee8b12fef | 1028 | //送信のために一旦解除 |
| nyatla | 37:fc4b4fd6a649 | 1029 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 1030 | if(sendWithRetransmit(i_inst,TCP_FIN|TCP_ACK,NULL,0,&sw,&sq)==0){ |
| nyatla | 0:142ee8b12fef | 1031 | //ちょっと待つ。 |
| nyatla | 0:142ee8b12fef | 1032 | NyLPC_cThread_yield(); |
| nyatla | 0:142ee8b12fef | 1033 | //TXの消去待ち |
| nyatla | 0:142ee8b12fef | 1034 | if(waitForTxRemove(i_inst,sq,&sw)){ |
| nyatla | 0:142ee8b12fef | 1035 | //再ロック |
| nyatla | 37:fc4b4fd6a649 | 1036 | lockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 1037 | //TX消去後にCLOSEDに遷移していればOK |
| nyatla | 0:142ee8b12fef | 1038 | if(i_inst->tcpstateflags==UIP_CLOSED) |
| nyatla | 0:142ee8b12fef | 1039 | { |
| nyatla | 0:142ee8b12fef | 1040 | NyLPC_Assert(i_inst->txbuf.rp==i_inst->txbuf.wp); |
| nyatla | 0:142ee8b12fef | 1041 | goto ReturnWithUnlock; |
| nyatla | 0:142ee8b12fef | 1042 | } |
| nyatla | 37:fc4b4fd6a649 | 1043 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 1044 | } |
| nyatla | 0:142ee8b12fef | 1045 | } |
| nyatla | 0:142ee8b12fef | 1046 | //エラー。RSTで切断。 |
| nyatla | 0:142ee8b12fef | 1047 | break; |
| nyatla | 0:142ee8b12fef | 1048 | default: |
| nyatla | 37:fc4b4fd6a649 | 1049 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 1050 | NyLPC_Warning(); |
| nyatla | 0:142ee8b12fef | 1051 | break; |
| nyatla | 0:142ee8b12fef | 1052 | } |
| nyatla | 37:fc4b4fd6a649 | 1053 | // if(i_inst->_smutex._lock_count>0){ |
| nyatla | 37:fc4b4fd6a649 | 1054 | // NyLPC_Warning(); |
| nyatla | 37:fc4b4fd6a649 | 1055 | // } |
| nyatla | 0:142ee8b12fef | 1056 | //このパスに到達するのは、FIN送信/ACKに成功したにも拘らず、規定時間内にCLOSEDに遷移しなかった場合。 |
| nyatla | 0:142ee8b12fef | 1057 | //コネクションを強制遷移して、RST |
| nyatla | 37:fc4b4fd6a649 | 1058 | lockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 1059 | f=i_inst->tcpstateflags; |
| nyatla | 0:142ee8b12fef | 1060 | if(f!=UIP_CLOSED){ |
| nyatla | 57:bc4330dfa62f | 1061 | //もし、強制CLOSE遷移であれば、RSTも送信。 |
| nyatla | 0:142ee8b12fef | 1062 | i_inst->tcpstateflags=UIP_CLOSED; |
| nyatla | 57:bc4330dfa62f | 1063 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 1064 | sendRst(i_inst); |
| nyatla | 57:bc4330dfa62f | 1065 | }else{ |
| nyatla | 57:bc4330dfa62f | 1066 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 1067 | } |
| nyatla | 0:142ee8b12fef | 1068 | NyLPC_cStopwatch_finalize(&sw); |
| nyatla | 0:142ee8b12fef | 1069 | return; |
| nyatla | 0:142ee8b12fef | 1070 | ReturnWithUnlock: |
| nyatla | 37:fc4b4fd6a649 | 1071 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 1072 | NyLPC_cStopwatch_finalize(&sw); |
| nyatla | 0:142ee8b12fef | 1073 | return; |
| nyatla | 0:142ee8b12fef | 1074 | } |
| nyatla | 0:142ee8b12fef | 1075 | |
| nyatla | 0:142ee8b12fef | 1076 | /** |
| nyatla | 37:fc4b4fd6a649 | 1077 | * uipサービスタスクが実行する関数です。 |
| nyatla | 0:142ee8b12fef | 1078 | * 定期的に実行する関数。最低でも1s単位で実行してください。 |
| nyatla | 0:142ee8b12fef | 1079 | */ |
| nyatla | 0:142ee8b12fef | 1080 | void NyLPC_cTcpSocket_periodic( |
| nyatla | 0:142ee8b12fef | 1081 | NyLPC_TcTcpSocket_t* i_inst) |
| nyatla | 0:142ee8b12fef | 1082 | { |
| nyatla | 0:142ee8b12fef | 1083 | int i; |
| nyatla | 0:142ee8b12fef | 1084 | struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; |
| nyatla | 0:142ee8b12fef | 1085 | NyLPC_TcStopwatch_t sw; |
| nyatla | 0:142ee8b12fef | 1086 | NyLPC_TUInt32 now; |
| nyatla | 0:142ee8b12fef | 1087 | int rp; |
| nyatla | 0:142ee8b12fef | 1088 | NyLPC_cStopwatch_initialize(&sw); |
| nyatla | 0:142ee8b12fef | 1089 | now=NyLPC_cStopwatch_now(); |
| nyatla | 0:142ee8b12fef | 1090 | //MUTEX LOCK |
| nyatla | 37:fc4b4fd6a649 | 1091 | lockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 1092 | if(i_inst->tcpstateflags==UIP_CLOSED) |
| nyatla | 0:142ee8b12fef | 1093 | { |
| nyatla | 0:142ee8b12fef | 1094 | //CLOSEDなら、バッファ開放。 |
| nyatla | 0:142ee8b12fef | 1095 | resetTxQWithUnlock(i_inst); |
| nyatla | 0:142ee8b12fef | 1096 | }else if(i_inst->txbuf.rp==i_inst->txbuf.wp){ |
| nyatla | 0:142ee8b12fef | 1097 | //再送信パケットがなければ何もしないよ。 |
| nyatla | 37:fc4b4fd6a649 | 1098 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 1099 | }else if(i_inst->uip_connr.peer_win==0){ |
| nyatla | 0:142ee8b12fef | 1100 | //peer_winが0の場合は何もしない。 |
| nyatla | 37:fc4b4fd6a649 | 1101 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 1102 | }else{ |
| nyatla | 0:142ee8b12fef | 1103 | //再送信処理 |
| nyatla | 0:142ee8b12fef | 1104 | rp=i_inst->txbuf.rp; |
| nyatla | 0:142ee8b12fef | 1105 | NyLPC_cStopwatch_set(&sw,q[rp].tick_of_sent); |
| nyatla | 0:142ee8b12fef | 1106 | if(NyLPC_cStopwatch_elapseInMsec(&sw)>q[rp].rto32){ |
| nyatla | 0:142ee8b12fef | 1107 | //最古のパケットの送信時間をチェックして、タイムアウトが発生したら、再送時間と送信時刻をセット |
| nyatla | 0:142ee8b12fef | 1108 | //最古パケットRTOを2倍。 |
| nyatla | 0:142ee8b12fef | 1109 | q[rp].rto32*=2; |
| nyatla | 0:142ee8b12fef | 1110 | for(i=rp;i!=i_inst->txbuf.wp;i=(i+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ){ |
| nyatla | 0:142ee8b12fef | 1111 | q[i].tick_of_sent=now; |
| nyatla | 0:142ee8b12fef | 1112 | } |
| nyatla | 0:142ee8b12fef | 1113 | if(q[rp].rto32>UIP_IP_RTO_MAX_RTO){ |
| nyatla | 0:142ee8b12fef | 1114 | //最古のRTOが64秒を超えたら、CLOSED |
| nyatla | 0:142ee8b12fef | 1115 | i_inst->tcpstateflags =UIP_CLOSED; |
| nyatla | 0:142ee8b12fef | 1116 | resetTxQWithUnlock(i_inst); |
| nyatla | 0:142ee8b12fef | 1117 | sendRst(i_inst); |
| nyatla | 0:142ee8b12fef | 1118 | }else{ |
| nyatla | 0:142ee8b12fef | 1119 | //規定時間内なら、再送処理 |
| nyatla | 0:142ee8b12fef | 1120 | for(i=rp;i!=i_inst->txbuf.wp;i=(i+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ){ |
| nyatla | 0:142ee8b12fef | 1121 | NyLPC_cUipService_sendIPv4Tx(NyLPC_cIPv4Payload_getBuf(&(q[i].data))); |
| nyatla | 0:142ee8b12fef | 1122 | } |
| nyatla | 37:fc4b4fd6a649 | 1123 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 1124 | } |
| nyatla | 0:142ee8b12fef | 1125 | }else{ |
| nyatla | 37:fc4b4fd6a649 | 1126 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 1127 | } |
| nyatla | 0:142ee8b12fef | 1128 | } |
| nyatla | 0:142ee8b12fef | 1129 | NyLPC_cStopwatch_finalize(&sw); |
| nyatla | 0:142ee8b12fef | 1130 | return; |
| nyatla | 0:142ee8b12fef | 1131 | } |
| nyatla | 37:fc4b4fd6a649 | 1132 | /** |
| nyatla | 37:fc4b4fd6a649 | 1133 | * uipサービスタスクが実行する関数です。 |
| nyatla | 37:fc4b4fd6a649 | 1134 | * サービスの開始を通知します。 |
| nyatla | 37:fc4b4fd6a649 | 1135 | */ |
| nyatla | 37:fc4b4fd6a649 | 1136 | void NyLPC_cTcpSocket_startService(NyLPC_TcTcpSocket_t* i_inst,const NyLPC_TcIPv4Config_t* i_config) |
| nyatla | 37:fc4b4fd6a649 | 1137 | { |
| nyatla | 37:fc4b4fd6a649 | 1138 | NyLPC_Assert(i_inst->tcpstateflags==UIP_CLOSED);//閉じてなければおかしい。 |
| nyatla | 43:a182f2b5ff41 | 1139 | i_inst->uip_connr.lipaddr=&(i_config->ip_addr); |
| nyatla | 37:fc4b4fd6a649 | 1140 | i_inst->uip_connr.default_mss=i_config->default_mss; |
| nyatla | 37:fc4b4fd6a649 | 1141 | //NyLPC_cTcpSocket_setSynPayload関数でも実行するけど、IFのリセット時なのでここでもやる。 |
| nyatla | 37:fc4b4fd6a649 | 1142 | NyLPC_cFifoBuffer_clear(&(i_inst->rxbuf)); |
| nyatla | 37:fc4b4fd6a649 | 1143 | return; |
| nyatla | 37:fc4b4fd6a649 | 1144 | } |
| nyatla | 37:fc4b4fd6a649 | 1145 | /** |
| nyatla | 37:fc4b4fd6a649 | 1146 | * uipサービスタスクが実行する関数です。 |
| nyatla | 37:fc4b4fd6a649 | 1147 | * サービスの停止を通知します。 |
| nyatla | 37:fc4b4fd6a649 | 1148 | */ |
| nyatla | 37:fc4b4fd6a649 | 1149 | void NyLPC_cTcpSocket_stopService(NyLPC_TcTcpSocket_t* i_inst) |
| nyatla | 37:fc4b4fd6a649 | 1150 | { |
| nyatla | 37:fc4b4fd6a649 | 1151 | lockResource(i_inst); |
| nyatla | 37:fc4b4fd6a649 | 1152 | if(i_inst->tcpstateflags==UIP_CLOSED) |
| nyatla | 37:fc4b4fd6a649 | 1153 | { |
| nyatla | 37:fc4b4fd6a649 | 1154 | unlockResource(i_inst); |
| nyatla | 37:fc4b4fd6a649 | 1155 | }else{ |
| nyatla | 37:fc4b4fd6a649 | 1156 | i_inst->tcpstateflags=UIP_CLOSED; |
| nyatla | 37:fc4b4fd6a649 | 1157 | resetTxQWithUnlock(i_inst); |
| nyatla | 37:fc4b4fd6a649 | 1158 | sendRst(i_inst); |
| nyatla | 37:fc4b4fd6a649 | 1159 | } |
| nyatla | 37:fc4b4fd6a649 | 1160 | return; |
| nyatla | 37:fc4b4fd6a649 | 1161 | } |
| nyatla | 0:142ee8b12fef | 1162 | |
| nyatla | 0:142ee8b12fef | 1163 | /** |
| nyatla | 0:142ee8b12fef | 1164 | * この関数は、rxパケットを処理して、ソケットの状態を更新します。 |
| nyatla | 0:142ee8b12fef | 1165 | * uipサービスタスクが実行する関数です。 |
| nyatla | 0:142ee8b12fef | 1166 | * o_ippのペイロードに、応答ペイロードを設定することがあります。 |
| nyatla | 0:142ee8b12fef | 1167 | * この関数はNyLPC_cTcpSocket_periodicと排他実行すること。 |
| nyatla | 0:142ee8b12fef | 1168 | */ |
| nyatla | 0:142ee8b12fef | 1169 | NyLPC_TBool NyLPC_cTcpSocket_parseRx( |
| nyatla | 0:142ee8b12fef | 1170 | NyLPC_TcTcpSocket_t* i_inst, |
| nyatla | 0:142ee8b12fef | 1171 | NyLPC_TcIPv4Payload_t* o_ipp) |
| nyatla | 0:142ee8b12fef | 1172 | { |
| nyatla | 0:142ee8b12fef | 1173 | int i,s; |
| nyatla | 0:142ee8b12fef | 1174 | NyLPC_TUInt16 tmp16; |
| nyatla | 0:142ee8b12fef | 1175 | NyLPC_TUInt16 data_size; |
| nyatla | 0:142ee8b12fef | 1176 | NyLPC_TUInt8 in_tcpflag=o_ipp->payload.tcp->flags; |
| nyatla | 0:142ee8b12fef | 1177 | void* tcp_data_offset; |
| nyatla | 0:142ee8b12fef | 1178 | NyLPC_TBool is_new_packet; |
| nyatla | 0:142ee8b12fef | 1179 | int num_of_noack; |
| nyatla | 0:142ee8b12fef | 1180 | void* dlist[NyLPC_TcTcpSocket_NUMBER_OF_TXQ]; |
| nyatla | 0:142ee8b12fef | 1181 | NyLPC_TBool ret; |
| nyatla | 0:142ee8b12fef | 1182 | |
| nyatla | 0:142ee8b12fef | 1183 | //パラメータの計算 |
| nyatla | 0:142ee8b12fef | 1184 | |
| nyatla | 0:142ee8b12fef | 1185 | tmp16=NyLPC_TTcpHeader_getHeaderLength(o_ipp->payload.tcp); |
| nyatla | 0:142ee8b12fef | 1186 | //TCPペイロードの長さは、IPパケットの長さ-(IPヘッダ+TCPヘッダ) |
| nyatla | 0:142ee8b12fef | 1187 | data_size=NyLPC_TIPv4Header_getPacketLength(o_ipp->header)-NyLPC_TIPv4Header_getHeaderLength(o_ipp->header)-tmp16; |
| nyatla | 0:142ee8b12fef | 1188 | //TCPデータオフセット |
| nyatla | 0:142ee8b12fef | 1189 | tcp_data_offset=o_ipp->payload.rawbuf+tmp16; |
| nyatla | 0:142ee8b12fef | 1190 | |
| nyatla | 0:142ee8b12fef | 1191 | //インスタンスをロックする。 |
| nyatla | 37:fc4b4fd6a649 | 1192 | lockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 1193 | |
| nyatla | 0:142ee8b12fef | 1194 | //RSTのチェック。RST受信時は、状態にかかわらず、CLOSEDステータスに移行する。 |
| nyatla | 0:142ee8b12fef | 1195 | if (in_tcpflag & TCP_RST) |
| nyatla | 0:142ee8b12fef | 1196 | { |
| nyatla | 0:142ee8b12fef | 1197 | i_inst->tcpstateflags =UIP_CLOSED; |
| nyatla | 0:142ee8b12fef | 1198 | goto DROP; |
| nyatla | 0:142ee8b12fef | 1199 | } |
| nyatla | 0:142ee8b12fef | 1200 | |
| nyatla | 0:142ee8b12fef | 1201 | |
| nyatla | 0:142ee8b12fef | 1202 | is_new_packet=NyLPC_ntohl(o_ipp->payload.tcp->seqno32)==i_inst->uip_connr.rcv_nxt32; |
| nyatla | 0:142ee8b12fef | 1203 | |
| nyatla | 0:142ee8b12fef | 1204 | |
| nyatla | 0:142ee8b12fef | 1205 | //OPTIONの反映 |
| nyatla | 0:142ee8b12fef | 1206 | |
| nyatla | 0:142ee8b12fef | 1207 | //MSSの取得 |
| nyatla | 0:142ee8b12fef | 1208 | if(NyLPC_TTcpHeader_getTcpMmsOpt(o_ipp->payload.tcp,&tmp16)){ |
| nyatla | 0:142ee8b12fef | 1209 | //取得で着たら更新 |
| nyatla | 0:142ee8b12fef | 1210 | i_inst->uip_connr.peer_mss=tmp16; |
| nyatla | 0:142ee8b12fef | 1211 | } |
| nyatla | 0:142ee8b12fef | 1212 | //受信パケットを元に、未ACKパケットの数を計算 |
| nyatla | 0:142ee8b12fef | 1213 | num_of_noack=getNumOfSending(i_inst,o_ipp->payload.tcp->ackno32);//i_inst->txbuf.num_of_txq; |
| nyatla | 0:142ee8b12fef | 1214 | |
| nyatla | 0:142ee8b12fef | 1215 | //ステータス毎のACK応答 |
| nyatla | 0:142ee8b12fef | 1216 | switch(i_inst->tcpstateflags) |
| nyatla | 0:142ee8b12fef | 1217 | { |
| nyatla | 0:142ee8b12fef | 1218 | case UIP_SYN_RCVD: |
| nyatla | 0:142ee8b12fef | 1219 | //ACKを受信したら、ESTABLISHEDへ。 |
| nyatla | 0:142ee8b12fef | 1220 | //すべてのパケットをACKしたかで判定。() |
| nyatla | 0:142ee8b12fef | 1221 | if(num_of_noack==0){ |
| nyatla | 0:142ee8b12fef | 1222 | i_inst->tcpstateflags=UIP_ESTABLISHED; |
| nyatla | 0:142ee8b12fef | 1223 | }else{ |
| nyatla | 0:142ee8b12fef | 1224 | //それ以外のパケットはドロップする。 |
| nyatla | 0:142ee8b12fef | 1225 | break;//goto DROP; |
| nyatla | 0:142ee8b12fef | 1226 | } |
| nyatla | 0:142ee8b12fef | 1227 | //新しいパケットがなければ、無応答 |
| nyatla | 0:142ee8b12fef | 1228 | if(!is_new_packet){ |
| nyatla | 0:142ee8b12fef | 1229 | break;//goto DROP; |
| nyatla | 0:142ee8b12fef | 1230 | } |
| nyatla | 0:142ee8b12fef | 1231 | //引き続き、ESTABLISHEDの処理へ。 |
| nyatla | 0:142ee8b12fef | 1232 | case UIP_ESTABLISHED: |
| nyatla | 0:142ee8b12fef | 1233 | if(data_size>0){ |
| nyatla | 0:142ee8b12fef | 1234 | if(is_new_packet){ |
| nyatla | 0:142ee8b12fef | 1235 | if(addRecvData(i_inst,tcp_data_offset,data_size)){ |
| nyatla | 0:142ee8b12fef | 1236 | //通常のACK返却 |
| nyatla | 0:142ee8b12fef | 1237 | i_inst->uip_connr.rcv_nxt32+=data_size; |
| nyatla | 0:142ee8b12fef | 1238 | }else{ |
| nyatla | 0:142ee8b12fef | 1239 | //失敗したときは必要に応じて単純ACK |
| nyatla | 0:142ee8b12fef | 1240 | } |
| nyatla | 0:142ee8b12fef | 1241 | } |
| nyatla | 0:142ee8b12fef | 1242 | } |
| nyatla | 57:bc4330dfa62f | 1243 | // //MSSとWNDの更新 |
| nyatla | 57:bc4330dfa62f | 1244 | // i_inst->uip_connr.peer_mss = i_inst->uip_connr.default_mss;//@bug じゃないのこれ。peer_mss勝手に上書きしたらダメだろ |
| nyatla | 0:142ee8b12fef | 1245 | //どちらにしろ、ACK送信 |
| nyatla | 0:142ee8b12fef | 1246 | if(is_new_packet && (in_tcpflag & TCP_FIN)){ |
| nyatla | 0:142ee8b12fef | 1247 | //FINがあるときは、ステータスをCLOSE_WAITへセットして、ACKを返す。 |
| nyatla | 0:142ee8b12fef | 1248 | i_inst->tcpstateflags = UIP_CLOSE_WAIT; |
| nyatla | 0:142ee8b12fef | 1249 | i_inst->uip_connr.rcv_nxt32++; |
| nyatla | 0:142ee8b12fef | 1250 | } |
| nyatla | 0:142ee8b12fef | 1251 | break; |
| nyatla | 0:142ee8b12fef | 1252 | case UIP_CLOSE_WAIT: |
| nyatla | 0:142ee8b12fef | 1253 | //必要に応じたACK応答 |
| nyatla | 0:142ee8b12fef | 1254 | break; |
| nyatla | 0:142ee8b12fef | 1255 | case UIP_LAST_ACK: |
| nyatla | 0:142ee8b12fef | 1256 | //ACK(by FIN)が得られたなら、CLOSEDへ。 |
| nyatla | 0:142ee8b12fef | 1257 | if(num_of_noack==0){ |
| nyatla | 0:142ee8b12fef | 1258 | i_inst->tcpstateflags=UIP_CLOSED; |
| nyatla | 0:142ee8b12fef | 1259 | } |
| nyatla | 0:142ee8b12fef | 1260 | //必要に応じたACK応答 |
| nyatla | 0:142ee8b12fef | 1261 | break; |
| nyatla | 0:142ee8b12fef | 1262 | case UIP_FIN_WAIT_1: |
| nyatla | 0:142ee8b12fef | 1263 | //FIN受信->CLOSINGへ |
| nyatla | 0:142ee8b12fef | 1264 | if(is_new_packet && (in_tcpflag & TCP_FIN)){ |
| nyatla | 0:142ee8b12fef | 1265 | i_inst->uip_connr.rcv_nxt32++; |
| nyatla | 0:142ee8b12fef | 1266 | if(num_of_noack==0){ |
| nyatla | 0:142ee8b12fef | 1267 | //FINとACKを受信 |
| nyatla | 0:142ee8b12fef | 1268 | i_inst->tcpstateflags=UIP_TIME_WAIT; |
| nyatla | 0:142ee8b12fef | 1269 | }else{ |
| nyatla | 0:142ee8b12fef | 1270 | //FINのみ |
| nyatla | 0:142ee8b12fef | 1271 | i_inst->tcpstateflags=UIP_CLOSING; |
| nyatla | 0:142ee8b12fef | 1272 | } |
| nyatla | 0:142ee8b12fef | 1273 | }else if(num_of_noack==0){ |
| nyatla | 0:142ee8b12fef | 1274 | //ACKのみ |
| nyatla | 0:142ee8b12fef | 1275 | i_inst->tcpstateflags=UIP_FIN_WAIT_2; |
| nyatla | 0:142ee8b12fef | 1276 | } |
| nyatla | 0:142ee8b12fef | 1277 | //必要に応じたACK応答 |
| nyatla | 0:142ee8b12fef | 1278 | break; |
| nyatla | 0:142ee8b12fef | 1279 | case UIP_FIN_WAIT_2: |
| nyatla | 0:142ee8b12fef | 1280 | //FIN受信->TIME_WAITへ(pureACK) |
| nyatla | 0:142ee8b12fef | 1281 | if(is_new_packet && (in_tcpflag & TCP_FIN)){ |
| nyatla | 0:142ee8b12fef | 1282 | i_inst->uip_connr.rcv_nxt32++; |
| nyatla | 0:142ee8b12fef | 1283 | i_inst->tcpstateflags=UIP_TIME_WAIT; |
| nyatla | 0:142ee8b12fef | 1284 | } |
| nyatla | 0:142ee8b12fef | 1285 | break; |
| nyatla | 0:142ee8b12fef | 1286 | case UIP_CLOSING: |
| nyatla | 0:142ee8b12fef | 1287 | //ACK受信したら、TIME_WAITへ |
| nyatla | 0:142ee8b12fef | 1288 | if(num_of_noack==0){ |
| nyatla | 0:142ee8b12fef | 1289 | i_inst->tcpstateflags=UIP_TIME_WAIT; |
| nyatla | 0:142ee8b12fef | 1290 | } |
| nyatla | 0:142ee8b12fef | 1291 | break; |
| nyatla | 0:142ee8b12fef | 1292 | case UIP_CLOSED: |
| nyatla | 0:142ee8b12fef | 1293 | //何もできない。何もしない。 |
| nyatla | 57:bc4330dfa62f | 1294 | break; |
| nyatla | 0:142ee8b12fef | 1295 | case UIP_TIME_WAIT: |
| nyatla | 0:142ee8b12fef | 1296 | //最終ACKを送り続ける。 |
| nyatla | 0:142ee8b12fef | 1297 | break; |
| nyatla | 57:bc4330dfa62f | 1298 | case UIP_SYN_SENT: |
| nyatla | 57:bc4330dfa62f | 1299 | //connect関数実行中しか起動しないステータス |
| nyatla | 57:bc4330dfa62f | 1300 | if(num_of_noack==0){ |
| nyatla | 57:bc4330dfa62f | 1301 | i_inst->tcpstateflags=UIP_ESTABLISHED; |
| nyatla | 57:bc4330dfa62f | 1302 | i_inst->uip_connr.rcv_nxt32=NyLPC_ntohl(o_ipp->payload.tcp->seqno32)+1; |
| nyatla | 57:bc4330dfa62f | 1303 | }else{ |
| nyatla | 57:bc4330dfa62f | 1304 | //それ以外のパケットはドロップする。 |
| nyatla | 57:bc4330dfa62f | 1305 | break;//goto DROP; |
| nyatla | 57:bc4330dfa62f | 1306 | } |
| nyatla | 57:bc4330dfa62f | 1307 | //ACKを送る。 |
| nyatla | 57:bc4330dfa62f | 1308 | break; |
| nyatla | 0:142ee8b12fef | 1309 | default: |
| nyatla | 0:142ee8b12fef | 1310 | goto DROP; |
| nyatla | 0:142ee8b12fef | 1311 | } |
| nyatla | 0:142ee8b12fef | 1312 | //ウインドウサイズを更新 |
| nyatla | 0:142ee8b12fef | 1313 | i_inst->uip_connr.peer_win=NyLPC_ntohs(o_ipp->payload.tcp->wnd16); |
| nyatla | 0:142ee8b12fef | 1314 | |
| nyatla | 0:142ee8b12fef | 1315 | //送信キューから、Peerが受信したデータを削除する。 |
| nyatla | 0:142ee8b12fef | 1316 | if(in_tcpflag & TCP_ACK){ |
| nyatla | 0:142ee8b12fef | 1317 | //再送パケットキューから送信済みのデータを回収(後で開放) |
| nyatla | 0:142ee8b12fef | 1318 | NyLPC_Trace(); |
| nyatla | 0:142ee8b12fef | 1319 | s=updateTxQByIndex(i_inst,o_ipp->payload.tcp->ackno32,dlist); |
| nyatla | 0:142ee8b12fef | 1320 | NyLPC_Trace(); |
| nyatla | 0:142ee8b12fef | 1321 | }else{ |
| nyatla | 0:142ee8b12fef | 1322 | s=0; |
| nyatla | 0:142ee8b12fef | 1323 | } |
| nyatla | 0:142ee8b12fef | 1324 | //新しいパケットがきた場合は、再送キューのACKを更新する。 |
| nyatla | 0:142ee8b12fef | 1325 | if(is_new_packet){ |
| nyatla | 0:142ee8b12fef | 1326 | //再送キューのACKを更新 |
| nyatla | 0:142ee8b12fef | 1327 | updateTxAck(i_inst,NyLPC_htonl(i_inst->uip_connr.rcv_nxt32)); |
| nyatla | 0:142ee8b12fef | 1328 | } |
| nyatla | 0:142ee8b12fef | 1329 | |
| nyatla | 0:142ee8b12fef | 1330 | //送信キューのない |
| nyatla | 0:142ee8b12fef | 1331 | ret=NyLPC_TBool_FALSE; |
| nyatla | 0:142ee8b12fef | 1332 | if(((in_tcpflag&(TCP_FIN|TCP_SYN))!=0x00) || |
| nyatla | 0:142ee8b12fef | 1333 | ((!is_new_packet) && (data_size>0))) |
| nyatla | 0:142ee8b12fef | 1334 | { |
| nyatla | 0:142ee8b12fef | 1335 | setPacket(i_inst,o_ipp,TCP_ACK,NULL,0); |
| nyatla | 0:142ee8b12fef | 1336 | ret=NyLPC_TBool_TRUE; |
| nyatla | 0:142ee8b12fef | 1337 | }else{ |
| nyatla | 0:142ee8b12fef | 1338 | ret=NyLPC_TBool_FALSE; |
| nyatla | 0:142ee8b12fef | 1339 | } |
| nyatla | 37:fc4b4fd6a649 | 1340 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 1341 | //取り外したTXメモリの開放 |
| nyatla | 0:142ee8b12fef | 1342 | for(i=0;i<s;i++){ |
| nyatla | 0:142ee8b12fef | 1343 | //取り外したTXメモリを開放 |
| nyatla | 0:142ee8b12fef | 1344 | NyLPC_cUipService_releaseTxBuf(dlist[i]); |
| nyatla | 0:142ee8b12fef | 1345 | } |
| nyatla | 0:142ee8b12fef | 1346 | NyLPC_Trace(); |
| nyatla | 0:142ee8b12fef | 1347 | return ret; |
| nyatla | 0:142ee8b12fef | 1348 | DROP: |
| nyatla | 0:142ee8b12fef | 1349 | //ACKしたパケットを送信キューから削除 |
| nyatla | 37:fc4b4fd6a649 | 1350 | unlockResource(i_inst); |
| nyatla | 0:142ee8b12fef | 1351 | NyLPC_Trace(); |
| nyatla | 0:142ee8b12fef | 1352 | return NyLPC_TBool_FALSE; |
| nyatla | 0:142ee8b12fef | 1353 | } |
| nyatla | 0:142ee8b12fef | 1354 | |
| nyatla | 20:3b0b444b4deb | 1355 | |
| nyatla | 20:3b0b444b4deb | 1356 | |
| nyatla | 20:3b0b444b4deb | 1357 | |
| nyatla | 20:3b0b444b4deb | 1358 | |
| nyatla | 20:3b0b444b4deb | 1359 | |
| nyatla | 37:fc4b4fd6a649 | 1360 | |
| nyatla | 37:fc4b4fd6a649 | 1361 |
MiMic Webservice library