This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088

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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers NyLPC_cMiMicIpTcpListener.c Source File

NyLPC_cMiMicIpTcpListener.c

00001 /*********************************************************************************
00002  * PROJECT: MiMic
00003  * --------------------------------------------------------------------------------
00004  *
00005  * This file is part of MiMic
00006  * Copyright (C)2011 Ryo Iizuka
00007  *
00008  * MiMic is free software: you can redistribute it and/or modify
00009  * it under the terms of the GNU Lesser General Public License as published
00010  * by the Free Software Foundation, either version 3 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public License
00019  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00020  *
00021  * For further information please contact.
00022  *  http://nyatla.jp/
00023  *  <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
00024  *
00025  *********************************************************************************/
00026 #include "NyLPC_cMiMicIpTcpListener_protected.h"
00027 #include "NyLPC_cMiMicIpTcpSocket_protected.h"
00028 #include "NyLPC_cMiMicIpNetIf_protected.h"
00029 #include "../NyLPC_iTcpListener.h"
00030 #include "NyLPC_cIPv4.h"
00031 #include "NyLPC_stdlib.h"
00032 
00033 /**
00034  * NyLPC_TTcpListenerListenQ
00035  */
00036 
00037 void NyLPC_TTcpListenerListenQ_init(struct NyLPC_TTcpListenerListenQ* i_struct)
00038 {
00039     i_struct->wp=0;
00040     int i;
00041     for(i=NyLPC_TcMiMicIpTcpListener_NUMBER_OF_Q-1;i>=0;i--){
00042         i_struct->item[i].rport=0;
00043     }
00044 }
00045 
00046 /**
00047  * ListenQへSYNパケットの情報を追加する。
00048  */
00049 void NyLPC_TTcpListenerListenQ_add(struct NyLPC_TTcpListenerListenQ* i_struct,const NyLPC_TcIPv4Payload_t* i_payload)
00050 {
00051     struct NyLPC_TTcpSocketSynParam* item=&i_struct->item[i_struct->wp];
00052     //未処理のものがあれば登録しない。
00053     if(item->rport!=0){
00054         return;
00055     }
00056 
00057     //SYNリングバッファにセット
00058     item->rport = i_payload->payload.tcp->srcport;
00059     item->srcaddr=i_payload->header->srcipaddr;
00060     item->rcv_nxt32=NyLPC_ntohl(i_payload->payload.tcp->seqno32)+1;
00061     //MSSの設定
00062     if(!NyLPC_TTcpHeader_getTcpMmsOpt(i_payload->payload.tcp,&item->mss)){
00063         item->mss=0;
00064     }
00065     //書込み位置の進行
00066     i_struct->wp=(i_struct->wp+1)%NyLPC_TcMiMicIpTcpListener_NUMBER_OF_Q;
00067 }
00068 
00069 /**
00070  * 最も古いSYNパケット情報のインデクスをキューから返す。
00071  * @return
00072  * 見つからない場合-1である。
00073  */
00074 int NyLPC_TTcpListenerListenQ_getLastIndex(struct NyLPC_TTcpListenerListenQ* i_struct)
00075 {
00076     int i,t;
00077     //古いものから順に返す
00078     for(i=1;i<=NyLPC_TcMiMicIpTcpListener_NUMBER_OF_Q;i++){
00079         t=(i_struct->wp+i)%NyLPC_TcMiMicIpTcpListener_NUMBER_OF_Q;
00080         //有効なデータ?
00081         if(i_struct->item[t].rport!=0){
00082             return t;
00083         }
00084     }
00085     return -1;
00086 }
00087 
00088 /**
00089  * ListenQのN番目を削除する。
00090  */
00091 void NyLPC_TTcpListenerListenQ_remove(struct NyLPC_TTcpListenerListenQ* i_struct,int i_idx)
00092 {
00093     i_struct->item[i_idx].rport=0;
00094     return;
00095 }
00096 
00097 
00098 
00099 
00100 
00101 
00102 //#define lockResource(i_inst) NyLPC_cMutex_lock(((i_inst)->_mutex))
00103 //#define unlockResource(i_inst) NyLPC_cMutex_unlock(((i_inst)->_mutex))
00104 #define lockResource(i_inst) NyLPC_cMutex_lock(NyLPC_cIPv4_getListenerMutex(((i_inst)->_parent_ipv4)))
00105 #define unlockResource(i_inst) NyLPC_cMutex_unlock(NyLPC_cIPv4_getListenerMutex(((i_inst)->_parent_ipv4)))
00106 
00107 
00108 static NyLPC_TBool listen(NyLPC_TiTcpListener_t* i_inst,NyLPC_TiTcpSocket_t* i_sock,NyLPC_TUInt32 i_wait_msec);
00109 static void finaize(NyLPC_TiTcpListener_t* i_inst);
00110 
00111 const static struct NyLPC_TiTcpListener_Interface interface=
00112 {
00113     listen,
00114     finaize
00115 };
00116 
00117 /**
00118  * uipサービスが稼働中にのみ機能します。
00119  */
00120 NyLPC_TBool NyLPC_cMiMicIpTcpListener_initialize(NyLPC_TcMiMicIpTcpListener_t* i_inst,NyLPC_TUInt16 i_port)
00121 {
00122     NyLPC_TcMiMicIpNetIf_t* srv=_NyLPC_TcMiMicIpNetIf_inst;
00123     i_inst->_super._interface=&interface;
00124     i_inst->_parent_ipv4=&srv->_tcpv4;
00125     NyLPC_TTcpListenerListenQ_init(&i_inst->_listen_q);
00126     //uipサービスは初期化済であること。
00127     NyLPC_Assert(NyLPC_cMiMicIpNetIf_isInitService());
00128     //初期化
00129 //  //  NyLPC_cMutex_initialize(&(i_inst->_mutex));
00130 //  i_inst->_mutex=NyLPC_cIPv4_getListenerMutex(&srv->_tcpv4);//    NyLPC_cMutex_initialize(&(i_inst->_mutex));
00131     i_inst->_port=NyLPC_htons(i_port);
00132     //管理リストへ登録。
00133     return NyLPC_TBool_TRUE;
00134 }
00135 
00136 
00137 
00138 static void finaize(NyLPC_TiTcpListener_t* i_inst)
00139 {
00140     NyLPC_Assert(NyLPC_cMiMicIpNetIf_isInitService());
00141     NyLPC_cMiMicIpNetIf_releaseTcpListenerMemory((NyLPC_TcMiMicIpTcpListener_t*)i_inst);
00142     return;
00143 }
00144 
00145 
00146 static NyLPC_TBool listen(NyLPC_TiTcpListener_t* i_inst,NyLPC_TiTcpSocket_t* i_sock,NyLPC_TUInt32 i_wait_msec)
00147 {
00148     int qi;
00149     NyLPC_TcMiMicIpTcpListener_t* inst=(NyLPC_TcMiMicIpTcpListener_t*)i_inst;
00150     NyLPC_TcStopwatch_t sw;
00151     NyLPC_TBool ret=NyLPC_TBool_FALSE;
00152     //サービスは稼働中であること。
00153     NyLPC_Assert(NyLPC_cMiMicIpNetIf_isRun());
00154 
00155     //入力ソケットはCLOSEDであること。
00156     if(((NyLPC_TcMiMicIpTcpSocket_t*)i_sock)->tcpstateflags!=UIP_CLOSED){
00157         return NyLPC_TBool_FALSE;
00158     }
00159 
00160     //ストップウォッチを起動
00161     NyLPC_cStopwatch_initialize(&sw);
00162     NyLPC_cStopwatch_setNow(&sw);
00163 
00164 
00165     //Listenerのリソースロック
00166     lockResource(inst);
00167 
00168     while(NyLPC_cStopwatch_elapseInMsec(&sw)<i_wait_msec){
00169         qi=NyLPC_TTcpListenerListenQ_getLastIndex(&inst->_listen_q);
00170         if(qi>=0){
00171             //SYN処理要求がある
00172             if(!NyLPC_cMiMicIpTcpSocket_listenSyn(((NyLPC_TcMiMicIpTcpSocket_t*)i_sock),&inst->_listen_q.item[qi],inst->_port)){
00173                 ret=NyLPC_TBool_FALSE;
00174             }else{
00175                 //成功
00176                 ret=NyLPC_TBool_TRUE;
00177             }
00178             //処理したSYNの削除
00179             NyLPC_TTcpListenerListenQ_remove(&inst->_listen_q,qi);
00180             break;
00181         }else{
00182             //SYN処理要求は無い(しばらくまつ)
00183             unlockResource(inst);
00184             NyLPC_cThread_yield();
00185             lockResource(inst);
00186         }
00187     }
00188     //タイムアウト
00189     unlockResource(inst);
00190     NyLPC_cStopwatch_finalize(&sw);
00191     return ret;
00192 }
00193 
00194 /**
00195  * この関数は、Uip受信タスクから実行します。
00196  */
00197 NyLPC_TBool NyLPC_cMiMicIpTcpListener_synPacket(NyLPC_TcMiMicIpTcpListener_t* i_inst,const NyLPC_TcIPv4Payload_t* i_payload)
00198 {
00199     //パケットチェック。SYN設定されてる?
00200     if(!(i_payload->payload.tcp->flags & TCP_SYN)){
00201         //SYNない
00202         return NyLPC_TBool_FALSE;
00203     }
00204     //peer port==0は受け取らない。
00205     if(i_payload->payload.tcp->srcport==0){
00206         return NyLPC_TBool_FALSE;
00207     }
00208     //Listenerのリソースロック
00209     lockResource(i_inst);
00210     //ListenQへ追加
00211     NyLPC_TTcpListenerListenQ_add(&(i_inst->_listen_q),i_payload);
00212     //Listenerのリソースアンロック
00213     unlockResource(i_inst);
00214     return NyLPC_TBool_TRUE;
00215 }
00216 
00217 
00218 
00219