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