This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088
Fork of libMiMic by
Revision 109:18f12ac01097, committed 2014-11-19
- Comitter:
- nyatla
- Date:
- Wed Nov 19 14:45:17 2014 +0000
- Parent:
- 108:8dae2a2682e7
- Child:
- 110:257739f9b31e
- Commit message:
- new MiMicIP API;
Changed in this revision
--- a/core/NyLPC_cMiMicEnv.c Thu Nov 13 14:06:19 2014 +0000 +++ b/core/NyLPC_cMiMicEnv.c Wed Nov 19 14:45:17 2014 +0000 @@ -1,7 +1,7 @@ #include "NyLPC_cMiMicEnv.h" -#include "../uip/NyLPC_cUipService_protected.h" +#include "NyLPC_netif.h" -const static char* VERSION="MiMic/1.6.6"; +const static char* VERSION="MiMic/1.7.0"; #if NyLPC_MCU==NyLPC_MCU_LPC4088 const static char* MCU="LPC4088"; @@ -31,7 +31,7 @@ #if NyLPC_MCU==NyLPC_MCU_K64F return PNAME_FRDM; #else - switch(*(NyLPC_cUipService_refDeviceName())){ + switch(*(NyLPC_cNetIf_getInterfaceInfo()->device_name)){ case 'L': return PNAME_LPCXPRESSO; case 'D': @@ -41,7 +41,7 @@ } #endif case NyLPC_cMiMicEnv_ETHERNET_PHY: - return NyLPC_cUipService_refDeviceName(); + return NyLPC_cNetIf_getInterfaceInfo()->device_name; case NyLPC_cMiMicEnv_MCU_NAME: return MCU; default:
--- a/core/driver/ethernet/NyLPC_IEthernetDevice.h Thu Nov 13 14:06:19 2014 +0000 +++ b/core/driver/ethernet/NyLPC_IEthernetDevice.h Wed Nov 19 14:45:17 2014 +0000 @@ -7,7 +7,8 @@ #ifndef NyLPC_IEthernetDevice_h #define NyLPC_IEthernetDevice_h #include "NyLPC_stdlib.h" -#include "NyLPC_uipService.h" +#include "../../../netif/NyLPC_NetIf_ip_types.h" + #ifdef __cplusplus extern "C" {
--- a/core/http/NyLPC_cHttpBasicBodyParser.c Thu Nov 13 14:06:19 2014 +0000 +++ b/core/http/NyLPC_cHttpBasicBodyParser.c Wed Nov 19 14:45:17 2014 +0000 @@ -85,7 +85,7 @@ break; // HEX case NyLPC_TcHttpBasicBodyParser_ST_CHUNK_HEADER_START: - if(isxdigit(c)){ + if(isxdigit((int)c)){ i_inst->_data.chunked.recv_len=i_inst->_data.chunked.recv_len*16+NyLPC_ctox(c); //一応最大チャンクサイズは決めておこうか。 if(i_inst->_data.chunked.recv_len>0x0fffffff){
--- a/core/http/NyLPC_cHttpHeaderWriter.h Thu Nov 13 14:06:19 2014 +0000 +++ b/core/http/NyLPC_cHttpHeaderWriter.h Wed Nov 19 14:45:17 2014 +0000 @@ -27,7 +27,7 @@ #define NYLPC_CHTTPHEADERWRITER_H_ #include "NyLPC_stdlib.h" -#include "NyLPC_uipService.h" +#include "NyLPC_netif.h" #include "NyLPC_cHttpStream.h" #include "NyLPC_cHttpBasicHeaderParser.h" #include "NyLPC_cHttpdConfig.h"
--- a/core/http/NyLPC_cHttpStream.c Thu Nov 13 14:06:19 2014 +0000 +++ b/core/http/NyLPC_cHttpStream.c Wed Nov 19 14:45:17 2014 +0000 @@ -32,35 +32,35 @@ char _wbuf[1024]; const char* _rbuf; int _rbuf_len; -void NyLPC_cTcpSocket_initialized(void* inst,const char* rb,int l) +void NyLPC_iTcpSocket_initialized(void* inst,const char* rb,int l) { _rbuf=rb; _rbuf_len=l; } -void* NyLPC_cTcpSocket_allocSendBuf(void* inst,NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_len,NyLPC_TUInt32 i_to) +void* NyLPC_iIpTcpSocket_allocSendBuf(void* inst,NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_len,NyLPC_TUInt32 i_to) { *o_len=30; return _wbuf; } -NyLPC_TBool NyLPC_cTcpSocket_psend(void* inst,void* i_buf,NyLPC_TUInt16 i_len,NyLPC_TUInt32 i_to) +NyLPC_TBool NyLPC_iTcpSocket_psend(void* inst,void* i_buf,NyLPC_TUInt16 i_len,NyLPC_TUInt32 i_to) { printf("%.*s",i_len,i_buf); return NyLPC_TBool_TRUE; } -NyLPC_TInt32 NyLPC_cTcpSocket_precv(void* i_inst,const void** o_buf_ptr,NyLPC_TUInt32 i_wait_msec) +NyLPC_TInt32 NyLPC_iTcpSocket_precv(void* i_inst,const void** o_buf_ptr,NyLPC_TUInt32 i_wait_msec) { int l=(_rbuf_len>100)?100:_rbuf_len; *o_buf_ptr=_rbuf; return l; } -void NyLPC_cTcpSocket_pseek(void* i_inst,NyLPC_TUInt16 i_seek) +void NyLPC_iTcpSocket_pseek(void* i_inst,NyLPC_TUInt16 i_seek) { _rbuf+=i_seek; _rbuf_len-=i_seek; } -void* NyLPC_cTcpSocket_releaseSendBuf(NyLPC_TcTcpSocket_t* i_inst,void* i_buf_ptr) +void* NyLPC_iTcpSocket_releaseSendBuf(NyLPC_TiTcpSocket_t* i_inst,void* i_buf_ptr) { return NULL; } @@ -106,7 +106,7 @@ /** * 接続済のソケットをストリームに抽象化します。 */ -NyLPC_TBool NyLPC_cHttpStream_initialize(NyLPC_TcHttpStream_t* i_inst,NyLPC_TcTcpSocket_t* i_ref_sock) +NyLPC_TBool NyLPC_cHttpStream_initialize(NyLPC_TcHttpStream_t* i_inst,NyLPC_TiTcpSocket_t* i_ref_sock) { i_inst->super.absfunc=&_interface; i_inst->_ref_sock=i_ref_sock; @@ -119,7 +119,7 @@ void NyLPC_cHttpStream_finalize(NyLPC_TcHttpStream_t* i_inst) { if(i_inst->txb!=NULL){ - NyLPC_cTcpSocket_releaseSendBuf(i_inst->_ref_sock,i_inst->txb); + NyLPC_iTcpSocket_releaseSendBuf(i_inst->_ref_sock,i_inst->txb); } } @@ -130,7 +130,7 @@ static NyLPC_TInt32 pread_func(void* i_inst,const void** o_buf_ptr,NyLPC_TUInt32 i_timeout) { NyLPC_TcHttpStream_t* inst=(NyLPC_TcHttpStream_t*)i_inst; - return NyLPC_cTcpSocket_precv(inst->_ref_sock,o_buf_ptr,i_timeout); + return NyLPC_iTcpSocket_precv(inst->_ref_sock,o_buf_ptr,i_timeout); } static NyLPC_TBool write_func(void* i_inst,const void* i_data,NyLPC_TInt32 i_length) @@ -143,7 +143,7 @@ while(l>0){ //送信バッファがNULLなら、割り当て。 if(inst->txb==NULL){ - inst->txb=(NyLPC_TUInt8*)NyLPC_cTcpSocket_allocSendBuf(inst->_ref_sock,HTTP_TX_BUF_HINT,&s,NyLPC_TiHttpPtrStream_DEFAULT_HTTP_TIMEOUT); + inst->txb=(NyLPC_TUInt8*)NyLPC_iTcpSocket_allocSendBuf(inst->_ref_sock,HTTP_TX_BUF_HINT,&s,NyLPC_TiHttpPtrStream_DEFAULT_HTTP_TIMEOUT); if(inst->txb==NULL){ return NyLPC_TBool_FALSE; } @@ -184,7 +184,7 @@ { NyLPC_TcHttpStream_t* inst=(NyLPC_TcHttpStream_t*)i_inst; - NyLPC_cTcpSocket_pseek(inst->_ref_sock,i_seek); + NyLPC_iTcpSocket_pseek(inst->_ref_sock,i_seek); } /** @@ -205,9 +205,9 @@ inst->tx_len+=2; } //送信する。 - if(!NyLPC_cTcpSocket_psend(inst->_ref_sock,inst->txb,inst->tx_len,NyLPC_TiHttpPtrStream_DEFAULT_HTTP_TIMEOUT)){ + if(!NyLPC_iTcpSocket_psend(inst->_ref_sock,inst->txb,inst->tx_len,NyLPC_TiHttpPtrStream_DEFAULT_HTTP_TIMEOUT)){ //失敗。 - NyLPC_cTcpSocket_releaseSendBuf(inst->_ref_sock,inst->txb); + NyLPC_iTcpSocket_releaseSendBuf(inst->_ref_sock,inst->txb); inst->txb=NULL; return NyLPC_TBool_FALSE; }
--- a/core/http/NyLPC_cHttpStream.h Thu Nov 13 14:06:19 2014 +0000 +++ b/core/http/NyLPC_cHttpStream.h Wed Nov 19 14:45:17 2014 +0000 @@ -36,19 +36,19 @@ extern "C" { #endif /* __cplusplus */ -typedef int NyLPC_TcTcpSocket_t; -void NyLPC_cTcpSocket_initialized(void* inst,const char* rb,int l); -void* NyLPC_cTcpSocket_allocSendBuf(void* inst,NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_len,NyLPC_TUInt32 i_to); -NyLPC_TBool NyLPC_cTcpSocket_psend(void* inst,void* i_buf,NyLPC_TUInt16 i_len,NyLPC_TUInt32 i_to); -NyLPC_TInt32 NyLPC_cTcpSocket_precv(void* i_inst,const void** o_buf_ptr,NyLPC_TUInt32 i_wait_msec); -void NyLPC_cTcpSocket_pseek(void* i_inst,NyLPC_TUInt16 i_seek); +typedef int NyLPC_TiMiMicIpTcpSocket_t; +void NyLPC_iTcpSocket_initialized(void* inst,const char* rb,int l); +void* NyLPC_iTcpSocket_allocSendBuf(void* inst,NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_len,NyLPC_TUInt32 i_to); +NyLPC_TBool NyLPC_iTcpSocket_psend(void* inst,void* i_buf,NyLPC_TUInt16 i_len,NyLPC_TUInt32 i_to); +NyLPC_TInt32 NyLPC_iTcpSocket_precv(void* i_inst,const void** o_buf_ptr,NyLPC_TUInt32 i_wait_msec); +void NyLPC_iTcpSocket_pseek(void* i_inst,NyLPC_TUInt16 i_seek); #ifdef __cplusplus } #endif /* __cplusplus */ #else -#include "../uip/NyLPC_cTcpSocket.h" +#include "../netif/NyLPC_iTcpSocket.h" #endif #ifdef __cplusplus @@ -65,7 +65,7 @@ struct NyLPC_TcHttpStream { NyLPC_TiHttpPtrStream_t super; - NyLPC_TcTcpSocket_t* _ref_sock; + NyLPC_TiTcpSocket_t* _ref_sock; NyLPC_TUInt8* txb;//送信バッファ NyLPC_TUInt16 txb_size;//送信バッファサイズ NyLPC_TUInt16 tx_len; //送信サイズ @@ -80,7 +80,7 @@ * このインスタンスは、NyLPC_TiHttpPtrStream_TInterfaceインタフェイスを提供します。 * @ */ -NyLPC_TBool NyLPC_cHttpStream_initialize(NyLPC_TcHttpStream_t* i_inst,NyLPC_TcTcpSocket_t* i_ref_sock); +NyLPC_TBool NyLPC_cHttpStream_initialize(NyLPC_TcHttpStream_t* i_inst,NyLPC_TiTcpSocket_t* i_ref_sock); void NyLPC_cHttpStream_finalize(NyLPC_TcHttpStream_t* i_inst);
--- a/core/http/NyLPC_cUrlReader.c Thu Nov 13 14:06:19 2014 +0000 +++ b/core/http/NyLPC_cUrlReader.c Wed Nov 19 14:45:17 2014 +0000 @@ -83,7 +83,7 @@ //16進数 p+=2; r=l=0; - while(isxdigit(*p)){ + while(isxdigit((int)(*p))){ r=r*16+NyLPC_ctox(*p); if(l!=(r>>4)){return NyLPC_TBool_FALSE;} l=r; @@ -91,7 +91,7 @@ } }else{ r=l=0; - while(isdigit(*p)){ + while(isdigit((int)(*p))){ r=r*10+NyLPC_ctoi(*p); if(l!=(r/10)){return NyLPC_TBool_FALSE;} l=r; @@ -120,7 +120,7 @@ //16進数 p+=2; r=l=0; - while(isxdigit(*p)){ + while(isxdigit((int)(*p))){ r=r*16+NyLPC_ctox(*p); if(l!=(r>>4)){return NyLPC_TBool_FALSE;} l=r; @@ -129,7 +129,7 @@ }else{ r=l=0; if(*p!='-'){ - while(isdigit(*p)){ + while(isdigit((int)(*p))){ r=r*10+NyLPC_ctoi(*p); if(l!=(r/10)){return NyLPC_TBool_FALSE;} l=r; @@ -137,7 +137,7 @@ } }else{ p++; - while(isdigit(*p)){ + while(isdigit((int)(*p))){ r=r*10+NyLPC_ctoi(*p); if(l!=(r/10)){return NyLPC_TBool_FALSE;} l=r;
--- a/core/http/json/NyLPC_cJsonRpcParser.c Thu Nov 13 14:06:19 2014 +0000 +++ b/core/http/json/NyLPC_cJsonRpcParser.c Wed Nov 19 14:45:17 2014 +0000 @@ -201,7 +201,7 @@ /** * 整数を構成する文字セットであるかを返します。 */ -#define isUnSignedCharSet(i_c) isdigit(i_c) +#define isUnSignedCharSet(i_c) isdigit((int)(i_c)) static void putchar_params(NyLPC_TcJsonRpcParser_t* i_inst, char i_c) {
--- a/core/include/NyLPC_config.h Thu Nov 13 14:06:19 2014 +0000 +++ b/core/include/NyLPC_config.h Wed Nov 19 14:45:17 2014 +0000 @@ -118,12 +118,18 @@ #define NyLPC_CONFIG_cHttpStream_DEBUG 0 //////////////////////////////////////////////////////////////////////////////////////////////// -//デバック情報 +//Application Configuration //////////////////////////////////////////////////////////////////////////////////////////////// #define NyLPC_cHttpdThread_SIZE_OF_THREAD_STACK (1024+512) #define NyLPC_cHttpd_MAX_PERSISTENT_CONNECTION 1 +#define NyLPC_cMiMicIpNetIf_config_TCPLISTENER_MAX 2 +#define NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX 3 +#define NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX 1 +#define NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX 2 + + /*固有プラットフォーム設定はここに記述します。*/ #undef NyLPC_ARCH #define NyLPC_ARCH NyLPC_ARCH_MBEDRTOS
--- a/core/include/NyLPC_net.h Thu Nov 13 14:06:19 2014 +0000 +++ b/core/include/NyLPC_net.h Wed Nov 19 14:45:17 2014 +0000 @@ -29,10 +29,8 @@ */ #ifndef NYLPC_NET_H_ #define NYLPC_NET_H_ -#include "../net/NyLPC_cNet.h" #include "../net/mdns/NyLPC_cMDnsServer.h" -#include "../net/apipa/NyLPC_cApipa.h" #include "../net/httpd/NyLPC_cHttpdConnection.h" #include "../net/httpd/NyLPC_cHttpd.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/include/NyLPC_netif.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,51 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + *********************************************************************************/ +/** + * @file + * このファイルは、uipディレクトリにあるヘッダファイルを集積します。 + */ +#ifndef NyLPC_uipService_H +#define NyLPC_uipService_H + +#include "NyLPC_stdlib.h" +#include "../netif/NyLPC_cIPv4Config.h" +#include "../netif/NyLPC_iTcpListener.h" +#include "../netif/NyLPC_iTcpSocket.h" +#include "../netif/NyLPC_iUdpSocket.h" +#include "../netif/NyLPC_NetIf_ip_types.h" +#include "../netif/NyLPC_cNetIf.h" +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + + +#endif +
--- a/core/include/NyLPC_uipService.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - *********************************************************************************/ -/** - * @file - * このファイルは、uipディレクトリにあるヘッダファイルを集積します。 - */ -#ifndef NyLPC_uipService_H -#define NyLPC_uipService_H - -#include "NyLPC_stdlib.h" -#include "../uip/NyLPC_cTcpListener.h" -#include "../uip/NyLPC_cTcpSocket.h" -#include "../uip/NyLPC_cUdpSocket.h" -#include "../uip/NyLPC_cUipService.h" -#include "../uip/NyLPC_uip_ethernet.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - - -#endif
--- a/core/net/NyLPC_cNet.c Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - *********************************************************************************/ -#include "NyLPC_cNet.h" -#include "dhcp/NyLPC_cDhcpClient.h" -#include "../uip/NyLPC_cUipService_protected.h" - - - -void NyLPC_cNet_initialize(NyLPC_TcNet_t* i_inst) -{ - //uipサービス初期化。いろいろ利用可能に。 - if(!NyLPC_TcUipService_isInitService()){ - NyLPC_cUipService_initialize(); - } -} - -void NyLPC_cNet_start(NyLPC_TcNet_t* i_inst,const NyLPC_TcNetConfig_t* i_ref_config) -{ - NyLPC_cUipService_start(&(i_ref_config->super)); - return; -} - -void NyLPC_cNet_stop(NyLPC_TcNet_t* i_inst) -{ - NyLPC_cUipService_stop(); - return; -} - -/** - * NyLPC_TcIPv4Config_tをDHCPで更新します。 - * この関数をコールする時は、サービスは停止中でなければなりません。 - * @param i_cfg - * 更新するi_cfg構造体。 - * emac,default_mssは設定済である必要があります。他のフィールド値は不定で構いません。 - * 更新されるフィールドは、ip,netmast,default_rootの3つです。 - * @return - * 更新に成功した場合TRUE - */ -NyLPC_TBool NyLPC_cNet_requestAddrDhcp(NyLPC_TcNet_t* i_net,NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat) -{ - NyLPC_TBool ret; - NyLPC_TcDhcpClient_t sock; - //netを開始 - NyLPC_cDhcpClient_initialize(&sock); - ret=NyLPC_cDhcpClient_requestAddr(&sock,i_cfg,i_repeat); - NyLPC_cDhcpClient_finalize(&sock); - return ret; -} -/** - * NyLPC_TcIPv4Config_tをAPIPAで更新します。 - * この関数をコールする時は、サービスは停止中でなければなりません。 - * @param i_cfg - * 更新するi_cfg構造体。 - * emac,default_mssは設定済である必要があります。他のフィールド値は不定で構いません。 - * 更新されるフィールドは、ip,netmast,default_rootの3つです。 - * @return - * 更新に成功した場合TRUE - */ -NyLPC_TBool NyLPC_cNet_requestAddrApipa(NyLPC_TcNet_t* i_net,NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat) -{ - NyLPC_TBool ret; - NyLPC_TcApipa_t sock; - //netを開始 - NyLPC_cApipa_initialize(&sock); - ret=NyLPC_cApipa_requestAddr(&sock,i_cfg,i_repeat); - NyLPC_cApipa_finalize(&sock); - return ret; -}
--- a/core/net/NyLPC_cNet.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - *********************************************************************************/ -#ifndef NYLPC_CNET_H_ -#define NYLPC_CNET_H_ - -#include "NyLPC_stdlib.h" -#include "NyLPC_uipService.h" -#include "NyLPC_cNetConfig.h" -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ -/** - * クラス型を定義します。 - */ -typedef struct NyLPC_TcNet NyLPC_TcNet_t; - - - - -struct NyLPC_TcNet -{ - int dummy; -}; - -/** - * ネットワークを初期化する。 - */ -void NyLPC_cNet_initialize(NyLPC_TcNet_t* i_inst); - -#define NyLPC_cNet_finalize(inst) -/** - * ネットワークサービスを開始します。 - * サービスは停止中でなければなりません。 - * 関数は、ネットワークアダプタの値を元にNyLPC_cMiMicEnv_PlatformName変数の値を更新します。 - * @param i_ref_config - * Networkコンフィギュレーション変数。このオブジェクトはcNetをstopするまで維持すること。 - */ -void NyLPC_cNet_start(NyLPC_TcNet_t* i_inst,const NyLPC_TcNetConfig_t* i_ref_config); -/** - * ネットワークスタックを停止します。 - * サービスは開始中でなければなりません。 - * start関数で開始済である必要があります。 - * この関数をコールする前に、全てのTCPソケットを閉じ、非同期なソケット操作を停止してください。 - */ -void NyLPC_cNet_stop(NyLPC_TcNet_t* i_inst); - -/** - * NyLPC_TcIPv4Config_tをDHCPで更新します。 - * この関数をコールする時は、サービスは停止中でなければなりません。 - * @param i_cfg - * 更新するi_cfg構造体。 - * emac,default_mssは設定済である必要があります。他のフィールド値は不定で構いません。 - * 更新されるフィールドは、ip,netmast,default_rootの3つです。 - * @return - * 更新に成功した場合TRUE - */ -NyLPC_TBool NyLPC_cNet_requestAddrDhcp(NyLPC_TcNet_t* i_net,NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* NYLPC_CNET_H_ */
--- a/core/net/NyLPC_cNetConfig.h Thu Nov 13 14:06:19 2014 +0000 +++ b/core/net/NyLPC_cNetConfig.h Wed Nov 19 14:45:17 2014 +0000 @@ -27,7 +27,7 @@ #define NYLPC_CNETCONFIG_H_ #include "NyLPC_stdlib.h" -#include "NyLPC_uipService.h" +#include "NyLPC_netif.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */
--- a/core/net/apipa/NyLPC_cApipa.c Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,92 +0,0 @@ -#include "NyLPC_cApipa.h" -#include "NyLPC_uipService.h" -#include "../uip/NyLPC_cUipService_protected.h" -#include <stdio.h> -#include <string.h> - - -/** - * ARPテーブルに指定IPが現れるまで待ちます。 - */ -static NyLPC_TBool waitForArpResponse(const struct NyLPC_TIPv4Addr* i_ip,NyLPC_TUInt32 i_wait_in_ms) -{ - NyLPC_TcStopwatch_t sw; - NyLPC_cStopwatch_initialize(&sw); - NyLPC_cStopwatch_startExpire(&sw,i_wait_in_ms); - while(!NyLPC_cStopwatch_isExpired(&sw)){ - NyLPC_cThread_yield(); - if(NyLPC_cUipService_hasArpInfo(i_ip)){ - return NyLPC_TBool_TRUE; - } - } - NyLPC_cStopwatch_finalize(&sw); - return NyLPC_TBool_FALSE; -} -static void makeIP(NyLPC_TcApipa_t* i_inst,struct NyLPC_TIPv4Addr* i_ip) -{ -// NyLPC_TIPv4Addr_set(i_ip,192,168,128,206);//for conflict test! - NyLPC_TIPv4Addr_set(i_ip,169,254,(i_inst->_seed>>8)&0xff,i_inst->_seed & 0xff); -} -static void updateSeed(NyLPC_TcApipa_t* i_inst) -{ - do{ - i_inst->_seed=(391*i_inst->_seed+392); - }while(((i_inst->_seed & 0xff)==0) || ((i_inst->_seed & 0xff00)==0)); -} - - - -void NyLPC_cApipa_initialize(NyLPC_TcApipa_t* i_inst) -{ - i_inst->_seed=0; -} - - -/** - * この関数はuipを操作します。 - * cNetは停止中である必要があります。 - */ -NyLPC_TBool NyLPC_cApipa_requestAddr(NyLPC_TcApipa_t* i_inst,NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat) -{ - int i; - NyLPC_TcIPv4Config_t cfg; - struct NyLPC_TIPv4Addr caip; - - //ゼロコンフィギュレーション用のIPを設定 - NyLPC_cIPv4Config_initialzeCopy(&cfg,i_cfg); - //seedを更新 - for(i=0;i<6;i++) - { - i_inst->_seed+=i_cfg->eth_mac.addr[i]; - } - NyLPC_cIPv4Config_setDefaultRoute(&cfg,&NyLPC_TIPv4Addr_ZERO); - for(i=i_repeat-1;i>=0;i--){ - NyLPC_cIPv4Config_setIp(&cfg,&NyLPC_TIPv4Addr_ZERO,&NyLPC_TIPv4Addr_ZERO); - updateSeed(i_inst); - makeIP(i_inst,&caip); - //startInterface - NyLPC_cUipService_start(&cfg); - NyLPC_cUipService_sendArpRequest(&caip); - //テーブル更新待ち - if(waitForArpResponse(&caip,512+(i_inst->_seed % 256))){ - NyLPC_cUipService_stop(); - continue; - } - NyLPC_cUipService_stop(); - //IPのコンフリクトテスト - NyLPC_cIPv4Config_setIp(&cfg,&caip,&NyLPC_TIPv4Addr_APIPA_MASK); - NyLPC_cUipService_start(&cfg); - //!ARP送信 - NyLPC_cUipService_sendArpRequest(&caip); - if(waitForArpResponse(&caip,512+(256-(i_inst->_seed % 256)))){ - //応答があったらエラー - NyLPC_cUipService_stop(); - continue; - } - //OK - NyLPC_cUipService_stop(); - NyLPC_cIPv4Config_setIp(i_cfg,&cfg.ip_addr,&cfg.netmask); - return NyLPC_TBool_TRUE; - } - return NyLPC_TBool_FALSE; -}
--- a/core/net/apipa/NyLPC_cApipa.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011-2013 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - *********************************************************************************/ -#ifndef NYLPC_CAPIPA_H_ -#define NYLPC_CAPIPA_H_ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#include "NyLPC_stdlib.h" -#include "NyLPC_net.h" - -typedef struct NyLPC_cApipa NyLPC_TcApipa_t; - -struct NyLPC_cApipa -{ - NyLPC_TUInt32 _seed; -}; -void NyLPC_cApipa_initialize(NyLPC_TcApipa_t* i_inst); - -#define NyLPC_cApipa_finalize(i_inst) - - -/** - * i_cfgにAutoIPのアドレスを取得します。 - * この関数はuipを操作します。uipServiceは停止中である必要があります。 - */ -NyLPC_TBool NyLPC_cApipa_requestAddr(NyLPC_TcApipa_t* i_inst,NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* NYLPC_CAPIPA_H_ */
--- a/core/net/dhcp/NyLPC_cDhcpClient.c Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,351 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011-2013 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - *********************************************************************************/ -#include "NyLPC_cDhcpClient.h" -#include <stdio.h> -#include <string.h> - -struct NyLPC_TDhcpHeader -{ - NyLPC_TUInt8 op; - NyLPC_TUInt8 htype; - NyLPC_TUInt8 hlen; - NyLPC_TUInt8 hops; - NyLPC_TUInt32 xid; - NyLPC_TUInt16 secs; - NyLPC_TUInt16 flags; - NyLPC_TUInt32 ciaddr; - NyLPC_TUInt32 yiaddr; - NyLPC_TUInt32 siaddr; - NyLPC_TUInt32 giaddr; - struct{ - struct NyLPC_TEthAddr emac; - NyLPC_TChar padding[10]; - }chaddr; - NyLPC_TChar sname[64]; - NyLPC_TChar file[128]; -}PACK_STRUCT_END; - -#define NyLPC_TDhcpHeader_BOOTREQUEST 1 -#define NyLPC_TDhcpHeader_BOOTREPLY 2 - -#define DHCP_OPT_ID_ROUTER 3 -#define DHCP_OPT_ID_SERVER_ID 54 -#define DHCP_OPT_ID_NETMASK 1 -#define DHCP_OPT_ID_MESSAGETYPE 53 - - - -/** - * DHCPパケットから32bit値を読み出す。 - * @return - * ネットワークオーダー - */ -static NyLPC_TBool getUInt32Option(const NyLPC_TUInt8* i_buf,NyLPC_TUInt16 len,NyLPC_TUInt8 i_id,NyLPC_TUInt32* o_v) -{ - const NyLPC_TUInt8* p=i_buf+sizeof(struct NyLPC_TDhcpHeader)+4; - while(*p!=0x00 && p<(i_buf+len-5)){ - if(*p==i_id){ - if(*(p+1)==4){ - *o_v=*((NyLPC_TUInt32*)(p+2)); - return NyLPC_TBool_TRUE; - } - }else{ - p+=(*(p+1))+2; - } - } - return NyLPC_TBool_FALSE; -} -static NyLPC_TBool getUInt8Option(const NyLPC_TUInt8* i_buf,NyLPC_TUInt16 len,NyLPC_TUInt8 i_id,NyLPC_TUInt8* o_v) -{ - const NyLPC_TUInt8* p=i_buf+sizeof(struct NyLPC_TDhcpHeader)+4; - while(*p!=0x00 && p<(i_buf+len-5)){ - if(*p==i_id){ - if(*(p+1)==1){ - *o_v=*(p+2); - return NyLPC_TBool_TRUE; - } - }else{ - p+=(*(p+1))+2; - } - } - return NyLPC_TBool_FALSE; -} -static NyLPC_TBool NyLPC_TDhcpHeader_parseDHCPOFFER(const NyLPC_TUInt8* i_buf,NyLPC_TUInt16 i_len,NyLPC_TUInt32 i_xid,NyLPC_TcDhcpClient_t* i_inst) -{ - struct NyLPC_TDhcpHeader* p=(struct NyLPC_TDhcpHeader*)i_buf; - //XIDのチェック - if(p->xid!=NyLPC_HTONL(i_xid)){ - return NyLPC_TBool_FALSE; - } - //OFFERのclient IPアドレスをresultへ保存情報の保存 - i_inst->_result->ip_addr.v=p->yiaddr; - //SERVER IDを保存 - if(!getUInt32Option(i_buf,i_len,DHCP_OPT_ID_SERVER_ID,&i_inst->_offerserver.v)){ - return NyLPC_TBool_FALSE; - } - return NyLPC_TBool_TRUE; -} - -static NyLPC_TBool NyLPC_TDhcpHeader_parseDHCPACK(const NyLPC_TUInt8* i_buf,NyLPC_TUInt16 i_len,NyLPC_TUInt32 i_xid,NyLPC_TcIPv4Config_t* result) -{ - struct NyLPC_TDhcpHeader* p=(struct NyLPC_TDhcpHeader*)i_buf; - //XIDのチェック - if(p->xid!=NyLPC_HTONL(i_xid)){ - return NyLPC_TBool_FALSE; - } - if(!getUInt32Option(i_buf,i_len,DHCP_OPT_ID_ROUTER,&result->dr_addr.v)){ - result->dr_addr=NyLPC_TIPv4Addr_ZERO; - } - if(!getUInt32Option(i_buf,i_len,DHCP_OPT_ID_NETMASK,&result->netmask.v)){ - result->netmask=NyLPC_TIPv4Addr_ZERO; - } - result->ip_addr.v=p->yiaddr; - return NyLPC_TBool_TRUE; -} - -static void NyLPC_TDhcpHeader_setDHCPDISCOVER(char* i_buf,NyLPC_TUInt32 i_xid,const struct NyLPC_TEthAddr* emac,NyLPC_TUInt16* o_len) -{ - struct NyLPC_TDhcpHeader* p=(struct NyLPC_TDhcpHeader*)i_buf; - memset(i_buf,0,sizeof(struct NyLPC_TDhcpHeader)); - p->op=NyLPC_TDhcpHeader_BOOTREQUEST; - p->htype=1; - p->hlen=6; - p->xid=NyLPC_HTONL(i_xid); - p->chaddr.emac=*emac; - p->flags=NyLPC_HTONS(0x8000); - memcpy(i_buf+sizeof(struct NyLPC_TDhcpHeader), - "\x63\x82\x53\x63" //4 - "\x35\x01\x01" //3 MESSAGE TYPE - "\x37\x03\x01\x03\x06" //5 REQUEST LIST(1,3,6) - "\x3d\x07\x01\x00\x00\x00\x00\x00\x00" //9 CLIENT INDIFIRE - "\xff",4+3+5+9+1); - //emacの上書き - memcpy((i_buf+sizeof(struct NyLPC_TDhcpHeader)+4+3+5+3),emac->addr,6); - //送信するパケットの長さ - *o_len=sizeof(struct NyLPC_TDhcpHeader)+4+3+5+9+1; - return; -} -static void NyLPC_TDhcpHeader_setDHCPREQUEST(char* i_buf,NyLPC_TUInt32 i_xid,const struct NyLPC_TIPv4Addr* i_sid,const struct NyLPC_TIPv4Addr* i_reqid,const struct NyLPC_TEthAddr* emac,NyLPC_TUInt16* o_len) -{ - struct NyLPC_TDhcpHeader* p=(struct NyLPC_TDhcpHeader*)i_buf; - memset(i_buf,0,sizeof(struct NyLPC_TDhcpHeader)); - p->op=NyLPC_TDhcpHeader_BOOTREQUEST; - p->htype=1; - p->hlen=6; - p->xid=NyLPC_HTONL(i_xid); - p->chaddr.emac=*emac; - p->flags=NyLPC_HTONS(0x8000); - memcpy(i_buf+sizeof(struct NyLPC_TDhcpHeader), - "\x63\x82\x53\x63" //4 - "\x35\x01\x03" //3 MESSAGE TYPE - "\x37\x03\x01\x03\x06" //5 REQUEST LIST(1,3,6) - "\x3d\x07\x01\x00\x00\x00\x00\x00\x00" //9 CLIENT INDIFIRE - "\x36\x04\x00\x00\x00\x00" // 6 SERVER ID - "\x32\x04\x00\x00\x00\x00" // 6 Reqested IP - "\xff",4+3+5+9+6+6+1); - //emacの上書き - memcpy((i_buf+sizeof(struct NyLPC_TDhcpHeader)+4+3+5+3),emac->addr,6); - //sidの上書き - memcpy((i_buf+sizeof(struct NyLPC_TDhcpHeader)+4+3+5+9+2),i_sid,4); - //reqidの上書き - memcpy((i_buf+sizeof(struct NyLPC_TDhcpHeader)+4+3+5+9+6+2),i_reqid,4); - //送信するパケットの長さ - *o_len=sizeof(struct NyLPC_TDhcpHeader)+4+3+5+9+6+6+1; - return; -} - - - -#define TcDhcpSock_ST_WAIT_OFFER 1 -#define TcDhcpSock_ST_WAIT_OFFER_OK 2 -#define TcDhcpSock_ST_WAIT_ACK 3 -#define TcDhcpSock_ST_WAIT_ACK_OK 4 -#define TcDhcpSock_ST_DONE_NG 3 -#define TcDhcpSock_ST_DONE_OK 4 - - - - -#define DHCP_OPT_ID_MESSAGETYPE_ACK 5 -#define DHCP_OPT_ID_MESSAGETYPE_OFFER 2 - -static NyLPC_TBool onPacket(NyLPC_TcUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info); - -/** - * DHCPソケットを作成します。 - */ -NyLPC_TBool NyLPC_cDhcpClient_initialize(NyLPC_TcDhcpClient_t* i_inst) -{ - if(!NyLPC_cUdpSocket_initialize(&(i_inst->super),68,NULL,0)){ - return NyLPC_TBool_FALSE; - } - NyLPC_cUdpSocket_setBroadcast(&(i_inst->super)); - NyLPC_cUdpSocket_setOnRxHandler(&(i_inst->super),onPacket); - return NyLPC_TBool_TRUE; -} -void NyLPC_cDhcpClient_finalize(NyLPC_TcDhcpClient_t* i_inst) -{ - NyLPC_cUdpSocket_finalize(&(i_inst->super)); -} -#define TIMEOUT_SOCKAPI_MS 1000 -#define TIMEOUT_RECVMSG_MS 3000 - -/** - * ネットワークを更新します。 - * emac/default_mssを設定したネットワークが必要です。 - */ -static NyLPC_TBool NyLPC_cDhcpClient_dhcpRequest(NyLPC_TcDhcpClient_t* i_sock,NyLPC_TcIPv4Config_t* i_result) -{ - char* buf; - NyLPC_TcStopwatch_t sw; - NyLPC_TUInt16 s; - NyLPC_TInt16 hint=sizeof(struct NyLPC_TDhcpHeader)+128; - i_sock->txid+=(*(NyLPC_TUInt16*)(&(i_result->eth_mac.addr[2])))+(*(NyLPC_TUInt16*)(&(i_result->eth_mac.addr[4]))); - i_sock->_result=i_result; - buf=NyLPC_cUdpSocket_allocSendBuf(&i_sock->super,hint,&s,TIMEOUT_SOCKAPI_MS); - if(buf==NULL || s<hint){ - return NyLPC_TBool_FALSE; - } - NyLPC_TDhcpHeader_setDHCPDISCOVER(buf,i_sock->txid,&i_sock->_result->eth_mac,&s); - i_sock->_status=TcDhcpSock_ST_WAIT_OFFER; - if(!NyLPC_cUdpSocket_psend(&i_sock->super,&NyLPC_TIPv4Addr_BROADCAST,67,buf,s)){ - NyLPC_cUdpSocket_releaseSendBuf(&i_sock->super,buf); - return NyLPC_TBool_FALSE; - } - NyLPC_cStopwatch_initialize(&sw); - NyLPC_cStopwatch_startExpire(&sw,TIMEOUT_RECVMSG_MS); - while(i_sock->_status==TcDhcpSock_ST_WAIT_OFFER){ - if(NyLPC_cStopwatch_isExpired(&sw)){ - return NyLPC_TBool_FALSE; - } - } - //レスポンスのチェック - if(i_sock->_status!=TcDhcpSock_ST_WAIT_OFFER_OK) - { - return NyLPC_TBool_FALSE; - } - buf=NyLPC_cUdpSocket_allocSendBuf(&i_sock->super,hint,&s,TIMEOUT_SOCKAPI_MS); - if(buf==NULL || s<hint){ - return NyLPC_TBool_FALSE; - } - NyLPC_TDhcpHeader_setDHCPREQUEST(buf,i_sock->txid,&(i_sock->_offerserver),&(i_sock->_result->ip_addr),&i_sock->_result->eth_mac,&s); - i_sock->_status=TcDhcpSock_ST_WAIT_ACK; - if(!NyLPC_cUdpSocket_psend(&i_sock->super,&NyLPC_TIPv4Addr_BROADCAST,67,buf,s)){ - NyLPC_cUdpSocket_releaseSendBuf(&i_sock->super,buf); - return NyLPC_TBool_FALSE; - } - NyLPC_cStopwatch_startExpire(&sw,TIMEOUT_RECVMSG_MS); - while(i_sock->_status==TcDhcpSock_ST_WAIT_ACK){ - if(NyLPC_cStopwatch_isExpired(&sw)){ - return NyLPC_TBool_FALSE; - } - } - //レスポンスのチェック - if(i_sock->_status!=TcDhcpSock_ST_WAIT_ACK_OK) - { - return NyLPC_TBool_FALSE; - } - return NyLPC_TBool_TRUE; -} - -/** - * NyLPC_TcIPv4Config_tをDHCPで更新します。 - * この関数をコールする時は、サービスは停止中でなければなりません。 - * @param i_cfg - * 更新するi_cfg構造体。 - * emac,default_mssは設定済である必要があります。他のフィールド値は不定で構いません。 - * 更新されるフィールドは、ip,netmast,default_rootの3つです。 - * @return - * 更新に成功した場合TRUE - */ -NyLPC_TBool NyLPC_cDhcpClient_requestAddr(NyLPC_TcDhcpClient_t* i_inst,NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat) -{ - NyLPC_TInt16 i; - NyLPC_TBool ret=NyLPC_TBool_FALSE; - NyLPC_TcIPv4Config_t c2; - //工場出荷時設定でリセットしてIPを0に - NyLPC_cIPv4Config_initialzeCopy(&c2,i_cfg); - NyLPC_cIPv4Config_setIp(&c2,&NyLPC_TIPv4Addr_ZERO,&NyLPC_TIPv4Addr_ZERO); - NyLPC_cIPv4Config_setDefaultRoute(&c2,&NyLPC_TIPv4Addr_ZERO); - //netを開始 - NyLPC_cUipService_start(&c2); - for(i=i_repeat-1;i>=0;i--){ - ret=NyLPC_cDhcpClient_dhcpRequest(i_inst,i_cfg); - if(ret){ - break; - } - } - NyLPC_cUipService_stop(); - NyLPC_cIPv4Config_finalize(&c2); - return ret; -} - - - -static NyLPC_TBool onPacket(NyLPC_TcUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info) -{ - NyLPC_TUInt8 mt;//message type - NyLPC_TcDhcpClient_t* inst=(NyLPC_TcDhcpClient_t*)i_inst; - struct NyLPC_TDhcpHeader* dnsh=(struct NyLPC_TDhcpHeader*)i_buf; - if(i_info->size<sizeof(struct NyLPC_TDhcpHeader)+1){ - return NyLPC_TBool_FALSE;//DROP - } - switch(inst->_status) - { - case TcDhcpSock_ST_WAIT_ACK: - if(dnsh->op!=NyLPC_TDhcpHeader_BOOTREPLY){ - return NyLPC_TBool_FALSE; - } - if(!getUInt8Option(i_buf,i_info->size,DHCP_OPT_ID_MESSAGETYPE,&mt)){ - return NyLPC_TBool_FALSE; - } - if(mt!=DHCP_OPT_ID_MESSAGETYPE_ACK){ - return NyLPC_TBool_FALSE; - } - if(!NyLPC_TDhcpHeader_parseDHCPACK(i_buf,i_info->size,inst->txid,inst->_result)){ - return NyLPC_TBool_FALSE; - } - inst->_status=TcDhcpSock_ST_WAIT_ACK_OK; - break; - case TcDhcpSock_ST_WAIT_OFFER: - if(dnsh->op!=NyLPC_TDhcpHeader_BOOTREPLY){ - return NyLPC_TBool_FALSE; - } - if(!getUInt8Option(i_buf,i_info->size,DHCP_OPT_ID_MESSAGETYPE,&mt)){ - return NyLPC_TBool_FALSE; - } - if(mt!=DHCP_OPT_ID_MESSAGETYPE_OFFER){ - return NyLPC_TBool_FALSE; - } - if(!NyLPC_TDhcpHeader_parseDHCPOFFER(i_buf,i_info->size,inst->txid,inst)){ - return NyLPC_TBool_FALSE; - } - inst->_status=TcDhcpSock_ST_WAIT_OFFER_OK; - break; - } - return NyLPC_TBool_FALSE; - -}
--- a/core/net/dhcp/NyLPC_cDhcpClient.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011-2013 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - *********************************************************************************/ -#ifndef NYLPC_CDHCPCLIENT_H_ -#define NYLPC_CDHCPCLIENT_H_ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#include "NyLPC_net.h" - -typedef struct NyLPC_TcDhcpClient NyLPC_TcDhcpClient_t; - -struct NyLPC_TcDhcpClient{ - NyLPC_TcUdpSocket_t super; - NyLPC_TcIPv4Config_t* _result; - NyLPC_TUInt32 txid; - volatile NyLPC_TUInt16 _status; - //offer情報 - struct NyLPC_TIPv4Addr _offerserver; -}; - - -/** - * DHCPソケットを作成します。 - */ -NyLPC_TBool NyLPC_cDhcpClient_initialize(NyLPC_TcDhcpClient_t* i_inst); - -void NyLPC_cDhcpClient_finalize(NyLPC_TcDhcpClient_t* i_inst); - -/** - * NyLPC_TcIPv4Config_tをDHCPで更新します。 - * この関数をコールする時は、サービスは停止中でなければなりません。 - * @param i_cfg - * 更新するi_cfg構造体。 - * emac,default_mssは設定済である必要があります。他のフィールド値は不定で構いません。 - * 更新されるフィールドは、ip,netmast,default_rootの3つです。 - * @return - * 更新に成功した場合TRUE - */ -NyLPC_TBool NyLPC_cDhcpClient_requestAddr(NyLPC_TcDhcpClient_t* i_inst,NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat); - - - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif
--- a/core/net/httpcl/NyLPC_cHttpClient.c Thu Nov 13 14:06:19 2014 +0000 +++ b/core/net/httpcl/NyLPC_cHttpClient.c Wed Nov 19 14:45:17 2014 +0000 @@ -15,15 +15,19 @@ -void NyLPC_cHttpClient_initialize(NyLPC_TcHttpClient_t* i_inst,void* i_rx_buf,NyLPC_TUInt16 i_rx_size) +NyLPC_TBool NyLPC_cHttpClient_initialize(NyLPC_TcHttpClient_t* i_inst,void* i_rx_buf,NyLPC_TUInt16 i_rx_size) { - NyLPC_cTcpSocket_initialize(&i_inst->_sock,i_rx_buf,i_rx_size); + i_inst->_sock=NyLPC_cNetIf_createTcpSocketEx(NyLPC_TSocketType_TCP_NORMAL); + if(i_inst->_sock==NULL){ + return NyLPC_TBool_FALSE; + } i_inst->_state=NyLPC_TcHttpClient_ST_CLOSED; + return NyLPC_TBool_TRUE; } void NyLPC_cHttpClient_finalize(NyLPC_TcHttpClient_t* i_inst) { NyLPC_cHttpClient_close(i_inst); - NyLPC_cTcpSocket_finalize(&i_inst->_sock); + NyLPC_iTcpSocket_finalize(i_inst->_sock); } void NyLPC_cHttpClient_close(NyLPC_TcHttpClient_t* i_inst) @@ -44,7 +48,7 @@ case NyLPC_TcHttpClient_ST_CLOSED: return; } - NyLPC_cTcpSocket_close(&i_inst->_sock,1000); + NyLPC_iTcpSocket_close(i_inst->_sock,1000); i_inst->_state=NyLPC_TcHttpClient_ST_CLOSED; } @@ -61,11 +65,11 @@ //ステータスをclosedへ遷移 NyLPC_cHttpClient_close(i_inst); //接続 - if(!NyLPC_cTcpSocket_connect(&i_inst->_sock,i_addr,i_port,3000)){ + if(!NyLPC_iTcpSocket_connect(i_inst->_sock,i_addr,i_port,3000)){ return NyLPC_TBool_FALSE; } //streamの生成 - if(!NyLPC_cHttpStream_initialize(&i_inst->_stream,&(i_inst->_sock))){ + if(!NyLPC_cHttpStream_initialize(&i_inst->_stream,i_inst->_sock)){ NyLPC_OnErrorGoto(ERROR); } //ステータス遷移 @@ -108,8 +112,8 @@ if(!NyLPC_cHttpHeaderWriter_writeRequestHeader( &i_inst->pw.head_writer, i_method, - NyLPC_cTcpSocket_getPeerAddr(&(i_inst->_sock)), - NyLPC_cTcpSocket_getPeerPort(&(i_inst->_sock)),i_path)){ + NyLPC_iTcpSocket_getPeerAddr((i_inst->_sock)), + NyLPC_iTcpSocket_getPeerPort((i_inst->_sock)),i_path)){ NyLPC_OnErrorGoto(Error_1); } //MimeType
--- a/core/net/httpcl/NyLPC_cHttpClient.h Thu Nov 13 14:06:19 2014 +0000 +++ b/core/net/httpcl/NyLPC_cHttpClient.h Wed Nov 19 14:45:17 2014 +0000 @@ -11,7 +11,7 @@ #include "NyLPC_stdlib.h" #include "NyLPC_net.h" #include "NyLPC_http.h" -#include "NyLPC_uipService.h" +#include "NyLPC_netif.h" #ifdef __cplusplus extern "C" { @@ -24,7 +24,7 @@ { NyLPC_TUInt8 _state; NyLPC_TUInt8 _padding1; - NyLPC_TcTcpSocket_t _sock; + NyLPC_TiTcpSocket_t* _sock; NyLPC_TcHttpStream_t _stream; union{ NyLPC_TcHttpHeaderWriter_t head_writer; @@ -35,7 +35,7 @@ }; -void NyLPC_cHttpClient_initialize(NyLPC_TcHttpClient_t* i_inst,void* i_rx_buf,NyLPC_TUInt16 i_rx_size); +NyLPC_TBool NyLPC_cHttpClient_initialize(NyLPC_TcHttpClient_t* i_inst,void* i_rx_buf,NyLPC_TUInt16 i_rx_size); void NyLPC_cHttpClient_finalize(NyLPC_TcHttpClient_t* i_inst);
--- a/core/net/httpd/NyLPC_cHttpd.c Thu Nov 13 14:06:19 2014 +0000 +++ b/core/net/httpd/NyLPC_cHttpd.c Wed Nov 19 14:45:17 2014 +0000 @@ -1,19 +1,25 @@ #include "NyLPC_cHttpd_protected.h" - -void NyLPC_cHttpd_initialize(NyLPC_TcHttpd_t* i_inst,NyLPC_TUInt16 i_port_number) +NyLPC_TBool NyLPC_cHttpd_initialize(NyLPC_TcHttpd_t* i_inst,NyLPC_TUInt16 i_port_number) { int i; i_inst->_num_of_active_connection=0; NyLPC_cMutex_initialize(&i_inst->_mutex); - NyLPC_cTcpListener_initialize(&(i_inst->_listener),i_port_number); + i_inst->_listener=NyLPC_cNetIf_createTcpListenerEx(i_port_number); + if(i_inst->_listener==NULL){ + return NyLPC_TBool_FALSE; + } for(i=0;i<NyLPC_cHttpd_NUMBER_OF_CONNECTION_THREAD;i++){ - NyLPC_cHttpdThread_initialize(&(i_inst->_thread[i]),i_inst,NyLPC_TcThread_PRIORITY_IDLE); + if(!NyLPC_cHttpdThread_initialize(&(i_inst->_thread[i]),i_inst,NyLPC_TcThread_PRIORITY_IDLE)){ + return NyLPC_TBool_FALSE; + } } + return NyLPC_TBool_TRUE; } void NyLPC_cHttpd_finalize(NyLPC_TcHttpd_t* i_inst) { + NyLPC_iTcpListener_finaize(i_inst->_listener); NyLPC_cMutex_finalize(&i_inst->_mutex); } @@ -23,7 +29,7 @@ for(;;){ //ターミネイト状態のタスクを検索 for(i=0;i<NyLPC_cHttpd_NUMBER_OF_CONNECTION_THREAD;i++){ - NyLPC_cHttpdThread_start(&(i_inst->_thread[i]),&i_inst->_listener); + NyLPC_cHttpdThread_start(&(i_inst->_thread[i]),i_inst->_listener); } NyLPC_cThread_yield(); }
--- a/core/net/httpd/NyLPC_cHttpd.h Thu Nov 13 14:06:19 2014 +0000 +++ b/core/net/httpd/NyLPC_cHttpd.h Wed Nov 19 14:45:17 2014 +0000 @@ -53,7 +53,7 @@ NyLPC_TcHttpd_onRequest onRequest; }function; NyLPC_TcMutex_t _mutex; - NyLPC_TcTcpListener_t _listener; + NyLPC_TiTcpListener_t* _listener; NyLPC_TcHttpdThread_t _thread[NyLPC_cHttpd_NUMBER_OF_CONNECTION_THREAD]; NyLPC_TInt16 _num_of_active_connection; }; @@ -61,7 +61,7 @@ -void NyLPC_cHttpd_initialize(NyLPC_TcHttpd_t* i_inst,NyLPC_TUInt16 i_port_number); +NyLPC_TBool NyLPC_cHttpd_initialize(NyLPC_TcHttpd_t* i_inst,NyLPC_TUInt16 i_port_number); void NyLPC_cHttpd_finalize(NyLPC_TcHttpd_t* i_inst); void NyLPC_cHttpd_loop(NyLPC_TcHttpd_t* i_inst); void NyLPC_cHttpd_lock(NyLPC_TcHttpd_t* i_inst);
--- a/core/net/httpd/NyLPC_cHttpdConnection.c Thu Nov 13 14:06:19 2014 +0000 +++ b/core/net/httpd/NyLPC_cHttpdConnection.c Wed Nov 19 14:45:17 2014 +0000 @@ -1,17 +1,22 @@ #include "NyLPC_cHttpdConnection_protected.h" #include "NyLPC_http.h" +#include "NyLPC_netif.h" #include "NyLPC_cHttpdUtils.h" #include "./NyLPC_cHttpd_protected.h" -void NyLPC_cHttpdConnection_initialize(NyLPC_TcHttpdConnection_t* i_inst,NyLPC_TcHttpd_t* i_parent_httpd) +NyLPC_TBool NyLPC_cHttpdConnection_initialize(NyLPC_TcHttpdConnection_t* i_inst,NyLPC_TcHttpd_t* i_parent_httpd) { - NyLPC_cTcpSocket_initialize(&(i_inst->_socket),i_inst->_rxbuf,NyLPC_cHttpdConnection_SIZE_OF_RX_BUF); + i_inst->_socket=NyLPC_cNetIf_createTcpSocketEx(NyLPC_TSocketType_TCP_HTTP); + if(i_inst->_socket==NULL){ + return NyLPC_TBool_FALSE; + } NyLPC_cHttpRequestPrefixParser_initialize(&(i_inst->_pparser)); i_inst->_parent_httpd=i_parent_httpd; i_inst->_res_status=NyLPC_cHttpdConnection_ResStatus_CLOSED; i_inst->_req_status=NyLPC_cHttpdConnection_ReqStatus_LISTEN; + return NyLPC_TBool_TRUE; } void NyLPC_cHttpdConnection_finalize(NyLPC_TcHttpdConnection_t* i_inst) @@ -19,7 +24,7 @@ NyLPC_cHttpdConnection_closeResponse(i_inst); NyLPC_cHttpdConnection_closeSocket(i_inst); NyLPC_cHttpRequestPrefixParser_finalize(i_inst); - NyLPC_cTcpSocket_finalize(&(i_inst->_socket)); + NyLPC_iTcpSocket_finalize(i_inst->_socket); } const NyLPC_TChar* NyLPC_cHttpdConnection_getUrlPrefix(const NyLPC_TcHttpdConnection_t* i_inst) @@ -236,11 +241,11 @@ /** * listenerでConnectionのソケットに接続を待ちます。 */ -NyLPC_TBool NyLPC_cHttpdConnection_listenSocket(NyLPC_TcHttpdConnection_t* i_inst,NyLPC_TcTcpListener_t* i_listener) +NyLPC_TBool NyLPC_cHttpdConnection_listenSocket(NyLPC_TcHttpdConnection_t* i_inst,NyLPC_TiTcpListener_t* i_listener) { NyLPC_Assert(i_inst->_req_status==NyLPC_cHttpdConnection_ReqStatus_LISTEN); //リスニング - if(!NyLPC_cTcpListener_listen(i_listener,&(i_inst->_socket),NyLPC_cHttpdConnection_TIMEOUT_LISTEN)){ + if(!NyLPC_iTcpListener_listen(i_listener,i_inst->_socket,NyLPC_cHttpdConnection_TIMEOUT_LISTEN)){ return NyLPC_TBool_FALSE; } //成功したらステータス遷移 @@ -255,11 +260,11 @@ { NyLPC_Assert(i_inst->_req_status==NyLPC_cHttpdConnection_ReqStatus_ACCEPT); - if(!NyLPC_cTcpSocket_accept(&(i_inst->_socket),NyLPC_cHttpdConnection_TIMEOUT_ACCEPT)){ + if(!NyLPC_iTcpSocket_accept(i_inst->_socket,NyLPC_cHttpdConnection_TIMEOUT_ACCEPT)){ NyLPC_OnErrorGoto(Error); } //HttpStreamの生成 - if(!NyLPC_cHttpStream_initialize(&i_inst->_in_stream,&(i_inst->_socket))){ + if(!NyLPC_cHttpStream_initialize(&i_inst->_in_stream,i_inst->_socket)){ NyLPC_OnErrorGoto(Error_Connected); } //初回だけHEADに遷移 @@ -268,7 +273,7 @@ i_inst->_connection_message_mode=NyLPC_TcHttpdConnection_CONNECTION_MODE_CLOSE; return NyLPC_TBool_TRUE; Error_Connected: - NyLPC_cTcpSocket_close(&(i_inst->_socket),NyLPC_cHttpdConnection_TIMEOUT_CLOSE); + NyLPC_iTcpSocket_close(i_inst->_socket,NyLPC_cHttpdConnection_TIMEOUT_CLOSE); i_inst->_req_status=NyLPC_cHttpdConnection_ReqStatus_LISTEN; Error: return NyLPC_TBool_FALSE; @@ -287,7 +292,7 @@ i_inst->_req_status=NyLPC_cHttpdConnection_ReqStatus_REQPARSE; return NyLPC_TBool_TRUE; Error_Prefetch: - NyLPC_cTcpSocket_close(&(i_inst->_socket),NyLPC_cHttpdConnection_TIMEOUT_CLOSE); + NyLPC_iTcpSocket_close(i_inst->_socket,NyLPC_cHttpdConnection_TIMEOUT_CLOSE); i_inst->_req_status=NyLPC_cHttpdConnection_ReqStatus_LISTEN; return NyLPC_TBool_FALSE; } @@ -346,7 +351,7 @@ case NyLPC_cHttpdConnection_ReqStatus_PREFETCH: NyLPC_cHttpStream_finalize(&i_inst->_in_stream); case NyLPC_cHttpdConnection_ReqStatus_ACCEPT: - NyLPC_cTcpSocket_close(&(i_inst->_socket),NyLPC_cHttpdConnection_TIMEOUT_CLOSE); + NyLPC_iTcpSocket_close(i_inst->_socket,NyLPC_cHttpdConnection_TIMEOUT_CLOSE); default: break; }
--- a/core/net/httpd/NyLPC_cHttpdConnection.h Thu Nov 13 14:06:19 2014 +0000 +++ b/core/net/httpd/NyLPC_cHttpdConnection.h Wed Nov 19 14:45:17 2014 +0000 @@ -20,12 +20,6 @@ #endif -/** HTTPコネクションの受信バッファのサイズ - */ -#ifndef NyLPC_cHttpdConnection_SIZE_OF_RX_BUF -# define NyLPC_cHttpdConnection_SIZE_OF_RX_BUF 512 -#endif - typedef NyLPC_TUInt8 NyLPC_TcHttpdConnection_Status; /** リクエストプレフィクスを読み出した状態*/ @@ -68,8 +62,7 @@ NyLPC_TUInt8 _res_status;//レスポンスステータス NyLPC_TUInt8 _connection_message_mode;//COnnection:closeをヘッダに書き込むかのフラグ NyLPC_TcHttpd_t* _parent_httpd; //NyLPC_cHttpd - NyLPC_TcTcpSocket_t _socket; - NyLPC_TUInt8 _rxbuf[NyLPC_cHttpdConnection_SIZE_OF_RX_BUF]; + NyLPC_TiTcpSocket_t* _socket; NyLPC_TcHttpStream_t _in_stream; NyLPC_TcHttpRequestPrefixParser_t _pparser; union{ @@ -82,7 +75,7 @@ * @param i_parent_httpd * */ -void NyLPC_cHttpdConnection_initialize(NyLPC_TcHttpdConnection_t* i_inst,NyLPC_TcHttpd_t* i_parent_httpd); +NyLPC_TBool NyLPC_cHttpdConnection_initialize(NyLPC_TcHttpdConnection_t* i_inst,NyLPC_TcHttpd_t* i_parent_httpd); void NyLPC_cHttpdConnection_finalize(NyLPC_TcHttpdConnection_t* i_inst); /**
--- a/core/net/httpd/NyLPC_cHttpdConnection_protected.h Thu Nov 13 14:06:19 2014 +0000 +++ b/core/net/httpd/NyLPC_cHttpdConnection_protected.h Wed Nov 19 14:45:17 2014 +0000 @@ -7,9 +7,9 @@ #ifndef NYLPC_CHTTPDCONNECTION_PROTECTED_H_ #define NYLPC_CHTTPDCONNECTION_PROTECTED_H_ -#include "NyLPC_uipService.h" +#include "NyLPC_netif.h" +#include "NyLPC_stdlib.h" #include "NyLPC_cHttpdConnection.h" -#include "NyLPC_stdlib.h" #include "NyLPC_cHttpdUtils.h" #ifdef __cplusplus @@ -51,7 +51,7 @@ /** * ソケットをlistenします。LISTEN状態のソケットに使えます。 */ -NyLPC_TBool NyLPC_cHttpdConnection_listenSocket(NyLPC_TcHttpdConnection_t* i_inst,NyLPC_TcTcpListener_t* i_listener); +NyLPC_TBool NyLPC_cHttpdConnection_listenSocket(NyLPC_TcHttpdConnection_t* i_inst,NyLPC_TiTcpListener_t* i_listener); /** * コネクションのソケットをacceptします。
--- a/core/net/httpd/NyLPC_cHttpdThread.c Thu Nov 13 14:06:19 2014 +0000 +++ b/core/net/httpd/NyLPC_cHttpdThread.c Wed Nov 19 14:45:17 2014 +0000 @@ -6,10 +6,13 @@ static int server(void* p); -void NyLPC_cHttpdThread_initialize(NyLPC_TcHttpdThread_t* i_inst,NyLPC_TcHttpd_t* i_parent,NyLPC_TInt32 i_prio) +NyLPC_TBool NyLPC_cHttpdThread_initialize(NyLPC_TcHttpdThread_t* i_inst,NyLPC_TcHttpd_t* i_parent,NyLPC_TInt32 i_prio) { - NyLPC_cHttpdConnection_initialize(&(i_inst->_connection),i_parent); + if(!NyLPC_cHttpdConnection_initialize(&(i_inst->_connection),i_parent)){ + return NyLPC_TBool_FALSE; + } NyLPC_cThread_initialize(&(i_inst->_super),NyLPC_cHttpdThread_SIZE_OF_THREAD_STACK,i_prio); + return NyLPC_TBool_TRUE; } void NyLPC_cHttpdThread_finalize(NyLPC_TcHttpdThread_t* i_inst) { @@ -17,7 +20,7 @@ NyLPC_cHttpdConnection_finalize(&(i_inst->_connection)); } -NyLPC_TBool NyLPC_cHttpdThread_start(NyLPC_TcHttpdThread_t* i_inst,NyLPC_TcTcpListener_t* i_listener) +NyLPC_TBool NyLPC_cHttpdThread_start(NyLPC_TcHttpdThread_t* i_inst,NyLPC_TiTcpListener_t* i_listener) { //停止中? if(!NyLPC_cThread_isTerminated(&(i_inst->_super))){
--- a/core/net/httpd/NyLPC_cHttpdThread.h Thu Nov 13 14:06:19 2014 +0000 +++ b/core/net/httpd/NyLPC_cHttpdThread.h Wed Nov 19 14:45:17 2014 +0000 @@ -37,9 +37,9 @@ }; -void NyLPC_cHttpdThread_initialize(NyLPC_TcHttpdThread_t* i_inst,NyLPC_TcHttpd_t* i_parent,NyLPC_TInt32 i_prio); +NyLPC_TBool NyLPC_cHttpdThread_initialize(NyLPC_TcHttpdThread_t* i_inst,NyLPC_TcHttpd_t* i_parent,NyLPC_TInt32 i_prio); void NyLPC_cHttpdThread_finalize(NyLPC_TcHttpdThread_t* i_inst); -NyLPC_TBool NyLPC_cHttpdThread_start(NyLPC_TcHttpdThread_t* i_inst,NyLPC_TcTcpListener_t* i_listener); +NyLPC_TBool NyLPC_cHttpdThread_start(NyLPC_TcHttpdThread_t* i_inst,NyLPC_TiTcpListener_t* i_listener); #ifdef __cplusplus }
--- a/core/net/httpd/mod/NyLPC_cMocMiMicSetting.c Thu Nov 13 14:06:19 2014 +0000 +++ b/core/net/httpd/mod/NyLPC_cMocMiMicSetting.c Wed Nov 19 14:45:17 2014 +0000 @@ -30,7 +30,6 @@ #include "NyLPC_mimicVm.h" #include "NyLPC_flash.h" #include "../NyLPC_cHttpdConnection_protected.h" -#include "../../NyLPC_cNet.h" //#include <ctype.h> #define MOD_VERSION "ModMiMicSetting/1.4" @@ -200,7 +199,7 @@ //未知のクエリは無視 if(i_c!='\0' && i_c!='&'){ //許可する文字列は、[:AlNum:]||'_' - if(!isalnum(i_c) && i_c!='_'){ + if(!isalnum((int)i_c) && i_c!='_'){ NyLPC_OnErrorGoto(ERROR); } out->content.setup.tmp.host_name[out->content.setup.tmp.host_len++]=i_c; @@ -376,6 +375,7 @@ NyLPC_TBool ret; const struct NyLPC_TMiMicConfigulation* config; const NyLPC_TcNetConfig_t* currebt_cfg; + const struct NyLPC_TNetInterfaceInfo* netif_info; NyLPC_Assert( (NyLPC_cHttpdConnection_getMethod(i_connection)==NyLPC_THttpMethodType_GET)|| (NyLPC_cHttpdConnection_getMethod(i_connection)==NyLPC_THttpMethodType_HEAD)); @@ -428,7 +428,8 @@ NyLPC_OnErrorGoto(Error); } //write current status - currebt_cfg=(const NyLPC_TcNetConfig_t*)NyLPC_cUipService_refCurrentConfig(); + netif_info=NyLPC_cNetIf_getInterfaceInfo(); + currebt_cfg=(const NyLPC_TcNetConfig_t*)(netif_info->current_config); if(!NyLPC_cHttpdConnection_sendResponseBodyF(i_connection, "\"cur\":{" "\"mac00010203\":%u,"
--- a/core/net/httpd/mod/NyLPC_cModJsonRpc.c Thu Nov 13 14:06:19 2014 +0000 +++ b/core/net/httpd/mod/NyLPC_cModJsonRpc.c Wed Nov 19 14:45:17 2014 +0000 @@ -146,7 +146,7 @@ return _table[i].n; } } - return _table[6].n; + return _table[5].n; } NyLPC_TBool NyLPC_cModJsonRpc_putError(NyLPC_TcModJsonRpc_t* i_inst,NyLPC_TUInt32 i_id,NyLPC_TInt32 i_code)
--- a/core/net/httpd/mod/NyLPC_cModUPnPDevice.c Thu Nov 13 14:06:19 2014 +0000 +++ b/core/net/httpd/mod/NyLPC_cModUPnPDevice.c Wed Nov 19 14:45:17 2014 +0000 @@ -28,6 +28,7 @@ #include "NyLPC_net.h" #include "NyLPC_stdlib.h" #include "NyLPC_http.h" +#include <string.h> #include <ctype.h> @@ -227,7 +228,7 @@ return -1; } //2桁の16進数であること - if(!isxdigit(*(i_str+1)) || !isxdigit(*(i_str+2))){ + if(!isxdigit((int)(*(i_str+1))) || !isxdigit((int)(*(i_str+2)))){ return -1; } //サービスID化
--- a/core/net/httpd/mod/NyLPC_cModUPnPDevice.h Thu Nov 13 14:06:19 2014 +0000 +++ b/core/net/httpd/mod/NyLPC_cModUPnPDevice.h Wed Nov 19 14:45:17 2014 +0000 @@ -31,7 +31,7 @@ #include "NyLPC_stdlib.h" #include "NyLPC_http.h" -#include "../../NyLPC_cNet.h" + #ifdef __cplusplus extern "C" {
--- a/core/net/mdns/NyLPC_cMDnsServer.c Thu Nov 13 14:06:19 2014 +0000 +++ b/core/net/mdns/NyLPC_cMDnsServer.c Wed Nov 19 14:45:17 2014 +0000 @@ -24,7 +24,7 @@ * *********************************************************************************/ #include "NyLPC_cMDnsServer.h" -#include "NyLPC_uipService.h" +#include "NyLPC_netif.h" #include "NyLPC_http.h" #include "NyLPC_utils.h" #include <stdio.h> @@ -615,7 +615,7 @@ *(i_packet + l + 1) = (NyLPC_TUInt8)i_next_domain; l += 2; memcpy(i_packet + l, "\x00\x04\x00\x00\x00\x08", 6); - return l + 6; + return l + 6; } /** * NSECレコードレスポンスを書きだす。 @@ -778,7 +778,7 @@ int i,i2; for(i2=0;i2<i_inst->_ref_record->num_of_srv;i2++){ //Bufferの取得 - obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,TIMEOUT_IN_MS); + obuf=NyLPC_iUdpSocket_allocSendBuf(i_inst->_socket,512,&obuflen,TIMEOUT_IN_MS); if(obuf==NULL){ return; } @@ -808,7 +808,7 @@ NyLPC_OnErrorGoto(ERROR); } //Aレコード - l=writeARecord(obuf,l,obuflen,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr)); + l=writeARecord(obuf,l,obuflen,i_inst->_ref_record->a,NyLPC_iUdpSocket_getSockIP(i_inst->_socket)); if(l<=0){ NyLPC_OnErrorGoto(ERROR); } @@ -822,13 +822,13 @@ if(l<=0){ NyLPC_OnErrorGoto(ERROR); } - if(!NyLPC_cUdpSocket_psend(&(i_inst->_super),&MDNS_MCAST_IPADDR,MDNS_MCAST_PORT,obuf,l)){ + if(!NyLPC_iUdpSocket_psend(i_inst->_socket,&MDNS_MCAST_IPADDR,MDNS_MCAST_PORT,obuf,l)){ NyLPC_OnErrorGoto(ERROR); } } return; ERROR: - NyLPC_cUdpSocket_releaseSendBuf(&(i_inst->_super),obuf); + NyLPC_iUdpSocket_releaseSendBuf(i_inst->_socket,obuf); return; } @@ -850,7 +850,7 @@ goto DROP; } //Bufferの取得 - obuf = NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super), 512, &obuflen, 0); + obuf = NyLPC_iUdpSocket_allocSendBuf(i_inst->_socket, 512, &obuflen, 0); if (obuf == NULL){ goto DROP; } @@ -865,7 +865,7 @@ NyLPC_OnErrorGoto(ERROR); } //Aレコード - l = writeARecord(obuf, l, obuflen, i_inst->_ref_record->a, &(i_inst->_super.uip_udp_conn.lipaddr)); + l = writeARecord(obuf, l, obuflen, i_inst->_ref_record->a, NyLPC_iUdpSocket_getSockIP(i_inst->_socket)); if (l <= 0){ NyLPC_OnErrorGoto(ERROR); } @@ -915,14 +915,14 @@ goto DROP; } //Bufferの取得 - obuf = NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super), 512, &obuflen, 0); + obuf = NyLPC_iUdpSocket_allocSendBuf(i_inst->_socket, 512, &obuflen, 0); if (obuf == NULL){ goto DROP; } //Headerのコピー l = setResponseHeader(obuf, i_dns_header, 1, 0, 1); //A、(NSEC - l = writeARecordByQuery(obuf, l, obuflen, q, &(i_inst->_super.uip_udp_conn.lipaddr)); + l = writeARecordByQuery(obuf, l, obuflen, q, NyLPC_iUdpSocket_getSockIP(i_inst->_socket)); if (l <= 0){ NyLPC_OnErrorGoto(ERROR); } @@ -935,7 +935,7 @@ //_service._dns-sd._udpかどうか if (NyLPC_TDnsQuestion_isEqualName(q, NULL, "_services._dns-sd._udp")){ //Bufferの取得 - obuf = NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super), 512, &obuflen, 0); + obuf = NyLPC_iUdpSocket_allocSendBuf(i_inst->_socket, 512, &obuflen, 0); if (obuf == NULL){ goto DROP; } @@ -954,7 +954,7 @@ goto DROP; } //Bufferの取得 - obuf = NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super), 512, &obuflen, 0); + obuf = NyLPC_iUdpSocket_allocSendBuf(i_inst->_socket, 512, &obuflen, 0); if (obuf == NULL){ goto DROP; } @@ -974,7 +974,7 @@ NyLPC_OnErrorGoto(ERROR); } //Aレコード - l = writeARecord(obuf, l, obuflen, i_inst->_ref_record->a, &(i_inst->_super.uip_udp_conn.lipaddr)); + l = writeARecord(obuf, l, obuflen, i_inst->_ref_record->a,NyLPC_iUdpSocket_getSockIP(i_inst->_socket)); if (l <= 0){ NyLPC_OnErrorGoto(ERROR); } @@ -997,14 +997,14 @@ goto DROP; } //Bufferの取得 - obuf = NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super), 512, &obuflen, 0); + obuf = NyLPC_iUdpSocket_allocSendBuf(i_inst->_socket, 512, &obuflen, 0); l = setResponseHeader(obuf, i_dns_header, 1, 0, 2); l = writeTXTRecord(i_inst, ptr_recode, obuf, l, obuflen); if (l <= 0){ NyLPC_OnErrorGoto(ERROR); } //A recoad - l = writeARecord(obuf, l, obuflen, i_inst->_ref_record->a, &(i_inst->_super.uip_udp_conn.lipaddr)); + l = writeARecord(obuf, l, obuflen, i_inst->_ref_record->a,NyLPC_iUdpSocket_getSockIP(i_inst->_socket)); if (l <= 0){ NyLPC_OnErrorGoto(ERROR); } @@ -1022,12 +1022,12 @@ default: goto DROP; } - if (!NyLPC_cUdpSocket_psend(&(i_inst->_super), &MDNS_MCAST_IPADDR, MDNS_MCAST_PORT, obuf, l)){ + if (!NyLPC_iUdpSocket_psend(i_inst->_socket, &MDNS_MCAST_IPADDR, MDNS_MCAST_PORT, obuf, l)){ NyLPC_OnErrorGoto(ERROR); } return; ERROR: - NyLPC_cUdpSocket_releaseSendBuf(&(i_inst->_super), obuf); + NyLPC_iUdpSocket_releaseSendBuf(i_inst->_socket, obuf); DROP: return; } @@ -1036,7 +1036,7 @@ #define ST_WAIT 3 //待機 -static NyLPC_TBool onPacket(NyLPC_TcUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info) +static NyLPC_TBool onPacket(NyLPC_TiUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info) { NyLPC_TUInt16 in_len; NyLPC_TUInt16 num_of_query; @@ -1061,7 +1061,7 @@ goto DROP; } in_len+=s; - sendReply2((NyLPC_TcMDnsServer_t*)i_inst,(const struct NyLPC_TDnsHeader*)i_buf,&q); + sendReply2((NyLPC_TcMDnsServer_t*)i_inst->_tag,(const struct NyLPC_TDnsHeader*)i_buf,&q); } //パケット処理終了 return NyLPC_TBool_FALSE; @@ -1069,9 +1069,9 @@ return NyLPC_TBool_FALSE; } -static void onPeriodic(NyLPC_TcUdpSocket_t* i_inst) +static void onPeriodic(NyLPC_TiUdpSocket_t* i_inst) { - NyLPC_TcMDnsServer_t* inst=(NyLPC_TcMDnsServer_t*)i_inst; + NyLPC_TcMDnsServer_t* inst=(NyLPC_TcMDnsServer_t*)i_inst->_tag; //Announce Timeout if(NyLPC_cStopwatch_isExpired(&((NyLPC_TcMDnsServer_t*)inst)->_periodic_sw)){ switch(inst->_state){ @@ -1098,10 +1098,11 @@ { NyLPC_cStopwatch_initialize(&(i_inst->_periodic_sw)); NyLPC_cStopwatch_startExpire(&(i_inst->_periodic_sw),1000); - NyLPC_cUdpSocket_initialize(&(i_inst->_super),MDNS_MCAST_PORT,NULL,0); - NyLPC_cUdpSocket_setOnRxHandler(&(i_inst->_super),onPacket); - NyLPC_cUdpSocket_setOnPeriodicHandler(&(i_inst->_super),onPeriodic); - NyLPC_cUdpSocket_joinMulticast(&(i_inst->_super),&MDNS_MCAST_IPADDR); + i_inst->_socket=NyLPC_cNetIf_createUdpSocketEx(MDNS_MCAST_PORT,NyLPC_TSocketType_UDP_NOBUF); + i_inst->_socket->_tag=i_inst; + NyLPC_iUdpSocket_setOnRxHandler(i_inst->_socket,onPacket); + NyLPC_iUdpSocket_setOnPeriodicHandler(i_inst->_socket,onPeriodic); + NyLPC_iUdpSocket_joinMulticast(i_inst->_socket,&MDNS_MCAST_IPADDR); i_inst->_state=ST_WAIT; i_inst->_state_val=0; i_inst->_ref_record=i_ref_record; @@ -1110,7 +1111,7 @@ void NyLPC_cMDnsServer_finalize( NyLPC_TcMDnsServer_t* i_inst) { - NyLPC_cUdpSocket_finalize(&(i_inst->_super)); + NyLPC_iUdpSocket_finalize(i_inst->_socket); NyLPC_cStopwatch_finalize(&(i_inst->_periodic_sw)); }
--- a/core/net/mdns/NyLPC_cMDnsServer.h Thu Nov 13 14:06:19 2014 +0000 +++ b/core/net/mdns/NyLPC_cMDnsServer.h Wed Nov 19 14:45:17 2014 +0000 @@ -25,12 +25,12 @@ *********************************************************************************/ #ifndef NYLPC_CMDNSSERVER_H_ #define NYLPC_CMDNSSERVER_H_ +#include "NyLPC_netif.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ -#include "NyLPC_net.h" /** * NyLPC_TDnsRecordで使用するサービスレコード @@ -68,7 +68,7 @@ struct NyLPC_TcMDnsServer { /** マルチキャストのUDPソケット*/ - NyLPC_TcUdpSocket_t _super; + NyLPC_TiUdpSocket_t* _socket; /**周期実行タイマ*/ NyLPC_TcStopwatch_t _periodic_sw; /** 動作モード(private)*/
--- a/core/net/upnp/NyLPC_cSsdpSocket.c Thu Nov 13 14:06:19 2014 +0000 +++ b/core/net/upnp/NyLPC_cSsdpSocket.c Wed Nov 19 14:45:17 2014 +0000 @@ -25,8 +25,8 @@ *********************************************************************************/ #include "NyLPC_cSsdpSocket.h" #include "NyLPC_http.h" -#include "NyLPC_uipService.h" -#include "../uip/NyLPC_cUipService_protected.h" +#include "NyLPC_netif.h" + #include <stdio.h> #include <string.h> @@ -119,7 +119,7 @@ // "USN: %s%s\r\n" //5+2=7 // "ST: %s\r\n\r\n" //4+4=8 l=166+len_location+len_usn+len_udn+i_st_len; - obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->super),l,&l,TIMEOUT_IN_MS); + obuf=NyLPC_iUdpSocket_allocSendBuf(i_inst->_socket,l,&l,TIMEOUT_IN_MS); if(obuf==NULL){ return NULL; @@ -127,7 +127,7 @@ //必要なメモリサイズを確保できた? if(l<161+len_location+len_usn+len_udn+i_st_len) { - NyLPC_cUdpSocket_releaseSendBuf(&i_inst->super,obuf); + NyLPC_iUdpSocket_releaseSendBuf(i_inst->_socket,obuf); return NULL; } //ワーク変数lの再初期化 @@ -140,7 +140,7 @@ "LOCATION: http://"); l+=strlen(obuf); //IP addr:port\r\n - l+=NyLPC_TIPv4Addr_toString(NyLPC_cUdpSocket_getSockIP(&i_inst->super),obuf+l); + l+=NyLPC_TIPv4Addr_toString(NyLPC_iUdpSocket_getSockIP(i_inst->_socket),obuf+l); *(obuf+l)=':'; l+=1+NyLPC_itoa(i_inst->location_port,obuf+l+1,10); *(obuf+l)='/';l++; @@ -203,14 +203,14 @@ // "USN: %s%s\r\n" //5+2=7 // "NT: %s\r\n\r\n" //4+4=8 l2=204+len_location+len_usn+len_udn+((len_usn>0)?len_usn:len_udn); - obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->super),l2,&l,TIMEOUT_IN_MS); + obuf=NyLPC_iUdpSocket_allocSendBuf(i_inst->_socket,l2,&l,TIMEOUT_IN_MS); if(obuf==NULL){ return NULL; } //必要なメモリサイズを確保できた? if(l<l2) { - NyLPC_cUdpSocket_releaseSendBuf(&i_inst->super,obuf); + NyLPC_iUdpSocket_releaseSendBuf(i_inst->_socket,obuf); return NULL; } //ワーク変数lの再初期化 @@ -224,7 +224,7 @@ "LOCATION: http://"); l+=strlen(obuf); //IP addr:port\r\n - l+=NyLPC_TIPv4Addr_toString(NyLPC_cUdpSocket_getSockIP(&i_inst->super),obuf+l); + l+=NyLPC_TIPv4Addr_toString(NyLPC_iUdpSocket_getSockIP(i_inst->_socket),obuf+l); *(obuf+l)=':'; l+=1+NyLPC_itoa(i_inst->location_port,obuf+l+1,10); *(obuf+l)='/';l++; @@ -337,14 +337,14 @@ return NyLPC_TBool_TRUE;//OK } -static NyLPC_TBool onPacket(NyLPC_TcUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info) +static NyLPC_TBool onPacket(NyLPC_TiUdpSocket_t* i_sock,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info) { //パケット解析 void* tx; struct TMSearchHeader header; NyLPC_TInt16 tx_len; NyLPC_TInt8 i,i2; - NyLPC_TcSsdpSocket_t* sock=(NyLPC_TcSsdpSocket_t*)i_inst; + NyLPC_TcSsdpSocket_t* inst=((NyLPC_TcSsdpSocket_t*)i_sock->_tag); if(!parseHeader(&header,i_buf,i_info->size)){ NyLPC_OnErrorGoto(ERROR1); } @@ -364,40 +364,40 @@ //STによる処理分岐 if(strncmp("ssdp:all",header.result.st_str,8)==0){ tx=allocMsearchResponeTx( - sock,header.result.st_str, - sock->ref_device_record[0]->udn,STR_UPNP_ROOT_DEVICE, + inst,header.result.st_str, + inst->ref_device_record[0]->udn,STR_UPNP_ROOT_DEVICE, header.result.st_len, &tx_len); if(tx==NULL){ NyLPC_OnErrorGoto(ERROR1); } - if(!NyLPC_cUdpSocket_psend(i_inst,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){ + if(!NyLPC_iUdpSocket_psend(i_sock,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){ NyLPC_OnErrorGoto(ERROR2); } //全デバイスの送信 - for(i=0;i<sock->number_of_device;i++){ + for(i=0;i<inst->number_of_device;i++){ tx=allocMsearchResponeTx( - sock,header.result.st_str, - sock->ref_device_record[i]->udn,sock->ref_device_record[i]->device_type, + inst,header.result.st_str, + inst->ref_device_record[i]->udn,inst->ref_device_record[i]->device_type, header.result.st_len, &tx_len); if(tx==NULL){ NyLPC_OnErrorGoto(ERROR1); } - if(!NyLPC_cUdpSocket_psend(i_inst,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){ + if(!NyLPC_iUdpSocket_psend(i_sock,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){ NyLPC_OnErrorGoto(ERROR2); } - for(i2=0;i2<sock->ref_device_record[i]->number_of_service;i2++){ + for(i2=0;i2<inst->ref_device_record[i]->number_of_service;i2++){ //serviceに一致 tx=allocMsearchResponeTx( - sock,header.result.st_str, - sock->ref_device_record[i]->udn,sock->ref_device_record[i]->services[i2].service_type, + inst,header.result.st_str, + inst->ref_device_record[i]->udn,inst->ref_device_record[i]->services[i2].service_type, header.result.st_len, &tx_len); if(tx==NULL){ NyLPC_OnErrorGoto(ERROR1); } - if(!NyLPC_cUdpSocket_psend(i_inst,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){ + if(!NyLPC_iUdpSocket_psend(i_sock,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){ NyLPC_OnErrorGoto(ERROR2); } } @@ -405,18 +405,18 @@ }else if(strncmp("uuid:",header.result.st_str,5)==0){ //UDNの一致するデバイスの送信 NyLPC_TInt16 i; - for(i=sock->number_of_device-1;i>=0;i--){ - if(strncmp(header.result.st_str,sock->ref_device_record[i]->udn,header.result.st_len)==0){ + for(i=inst->number_of_device-1;i>=0;i--){ + if(strncmp(header.result.st_str,inst->ref_device_record[i]->udn,header.result.st_len)==0){ //UDN一致 tx=allocMsearchResponeTx( - sock,header.result.st_str, - sock->ref_device_record[i]->udn,NULL, + inst,header.result.st_str, + inst->ref_device_record[i]->udn,NULL, header.result.st_len, &tx_len); if(tx==NULL){ NyLPC_OnErrorGoto(ERROR1); } - if(!NyLPC_cUdpSocket_psend(i_inst,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){ + if(!NyLPC_iUdpSocket_psend(i_sock,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){ NyLPC_OnErrorGoto(ERROR2); } break;//送信処理終了 @@ -425,46 +425,46 @@ }else if(strncmp(STR_UPNP_ROOT_DEVICE,header.result.st_str,15)==0){ //rootDeviceはSTR_UPNP_ROOT_DEVICE tx=allocMsearchResponeTx( - sock,header.result.st_str, - sock->ref_device_record[0]->udn,STR_UPNP_ROOT_DEVICE, + inst,header.result.st_str, + inst->ref_device_record[0]->udn,STR_UPNP_ROOT_DEVICE, header.result.st_len, &tx_len); if(tx==NULL){ NyLPC_OnErrorGoto(ERROR1); } - if(!NyLPC_cUdpSocket_psend(i_inst,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){ + if(!NyLPC_iUdpSocket_psend(i_sock,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){ NyLPC_OnErrorGoto(ERROR2); } }else if(strncmp("urn:",header.result.st_str,4)==0){ - for(i=0;i<sock->number_of_device;i++){ + for(i=0;i<inst->number_of_device;i++){ //urn一致チェック - if(strncmp(sock->ref_device_record[i]->device_type,header.result.st_str,header.result.st_len)==0){ + if(strncmp(inst->ref_device_record[i]->device_type,header.result.st_str,header.result.st_len)==0){ //deviceに一致 tx=allocMsearchResponeTx( - sock,header.result.st_str, - sock->ref_device_record[i]->udn,sock->ref_device_record[i]->device_type, + inst,header.result.st_str, + inst->ref_device_record[i]->udn,inst->ref_device_record[i]->device_type, header.result.st_len, &tx_len); if(tx==NULL){ NyLPC_OnErrorGoto(ERROR1); } - if(!NyLPC_cUdpSocket_psend(i_inst,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){ + if(!NyLPC_iUdpSocket_psend(i_sock,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){ NyLPC_OnErrorGoto(ERROR2); } continue; } - for(i2=0;i2<sock->ref_device_record[i]->number_of_service;i2++){ - if(strncmp(sock->ref_device_record[i]->services[i2].service_type,header.result.st_str,header.result.st_len)==0){ + for(i2=0;i2<inst->ref_device_record[i]->number_of_service;i2++){ + if(strncmp(inst->ref_device_record[i]->services[i2].service_type,header.result.st_str,header.result.st_len)==0){ //serviceに一致 tx=allocMsearchResponeTx( - sock,header.result.st_str, - sock->ref_device_record[i]->udn,sock->ref_device_record[i]->services[i2].service_type, + inst,header.result.st_str, + inst->ref_device_record[i]->udn,inst->ref_device_record[i]->services[i2].service_type, header.result.st_len, &tx_len); if(tx==NULL){ NyLPC_OnErrorGoto(ERROR1); } - if(!NyLPC_cUdpSocket_psend(i_inst,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){ + if(!NyLPC_iUdpSocket_psend(i_sock,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){ NyLPC_OnErrorGoto(ERROR2); } } @@ -474,7 +474,7 @@ //正常終了 return NyLPC_TBool_FALSE; ERROR2: - NyLPC_cUdpSocket_releaseSendBuf(i_inst,tx); + NyLPC_iUdpSocket_releaseSendBuf(i_sock,tx); ERROR1: return NyLPC_TBool_FALSE; } @@ -484,36 +484,36 @@ #define FLAG_ORDER_STOP_SERVICE 1 #define FLAG_IS_SERVICE_RUNNING 2 -static void onPeriodic(NyLPC_TcUdpSocket_t* i_inst) +static void onPeriodic(NyLPC_TiUdpSocket_t* i_sock) { - NyLPC_TcSsdpSocket_t* sock=(NyLPC_TcSsdpSocket_t*)i_inst; - if(NyLPC_TUInt8_isBitOn(sock->_flags,FLAG_IS_SERVICE_RUNNING)){ + NyLPC_TcSsdpSocket_t* inst=(NyLPC_TcSsdpSocket_t*)i_sock->_tag; + if(NyLPC_TUInt8_isBitOn(inst->_flags,FLAG_IS_SERVICE_RUNNING)){ //実行中 //停止要求着てる? - if(NyLPC_TUInt8_isBitOn(sock->_flags,FLAG_ORDER_STOP_SERVICE)) + if(NyLPC_TUInt8_isBitOn(inst->_flags,FLAG_ORDER_STOP_SERVICE)) { //状態変更 - NyLPC_TUInt8_unsetBit(sock->_flags,FLAG_IS_SERVICE_RUNNING); + NyLPC_TUInt8_unsetBit(inst->_flags,FLAG_IS_SERVICE_RUNNING); //要求フラグクリア - NyLPC_TUInt8_unsetBit(sock->_flags,FLAG_ORDER_STOP_SERVICE); + NyLPC_TUInt8_unsetBit(inst->_flags,FLAG_ORDER_STOP_SERVICE); //@bug ByeBye送信しろ - }else if(NyLPC_cStopwatch_isExpired(&sock->_periodic_sw)){ + }else if(NyLPC_cStopwatch_isExpired(&inst->_periodic_sw)){ //Notify送信 - NyLPC_cSsdpSocket_notify(sock); + NyLPC_cSsdpSocket_notify(inst); //タイマ再始動 - NyLPC_cStopwatch_startExpire(&sock->_periodic_sw,SSDP_NOTIFY_INTERVAL); + NyLPC_cStopwatch_startExpire(&inst->_periodic_sw,SSDP_NOTIFY_INTERVAL); } }else{ //停止中 //開始要求着てる? - if(NyLPC_TUInt8_isBitOn(sock->_flags,FLAG_ORDER_START_SERVICE)) + if(NyLPC_TUInt8_isBitOn(inst->_flags,FLAG_ORDER_START_SERVICE)) { //状態変更 - NyLPC_TUInt8_setBit(sock->_flags,FLAG_IS_SERVICE_RUNNING); + NyLPC_TUInt8_setBit(inst->_flags,FLAG_IS_SERVICE_RUNNING); //要求フラグクリア - NyLPC_TUInt8_unsetBit(sock->_flags,FLAG_ORDER_START_SERVICE); + NyLPC_TUInt8_unsetBit(inst->_flags,FLAG_ORDER_START_SERVICE); //次回expireするように - NyLPC_cStopwatch_startExpire(&sock->_periodic_sw,SSDP_NOTIFY_INTERVAL); + NyLPC_cStopwatch_startExpire(&inst->_periodic_sw,SSDP_NOTIFY_INTERVAL); } } } @@ -540,11 +540,13 @@ const struct NyLPC_TUPnPDevDescDevice* i_ref_dev_record, NyLPC_TUInt16 i_server_port,const NyLPC_TChar* i_ref_location_path) { - NyLPC_cUdpSocket_initialize(&(i_inst->super),1900,NULL,0); - NyLPC_cUdpSocket_setOnRxHandler(&(i_inst->super),onPacket); - NyLPC_cUdpSocket_setOnPeriodicHandler(&(i_inst->super),onPeriodic); + i_inst->_socket=NyLPC_cNetIf_createUdpSocketEx(1900,NyLPC_TSocketType_UDP_NOBUF); + i_inst->_socket->_tag=i_inst; - NyLPC_cUdpSocket_joinMulticast(&(i_inst->super),&SSDP_MCAST_IPADDR); + NyLPC_iUdpSocket_setOnRxHandler(i_inst->_socket,onPacket); + NyLPC_iUdpSocket_setOnPeriodicHandler(i_inst->_socket,onPeriodic); + + NyLPC_iUdpSocket_joinMulticast(i_inst->_socket,&SSDP_MCAST_IPADDR); i_inst->_flags=0; NyLPC_cStopwatch_initialize(&(i_inst->_periodic_sw)); i_inst->number_of_device=0; @@ -555,7 +557,7 @@ void NyLPC_cSsdpSocket_finalize(NyLPC_TcSsdpSocket_t* i_inst) { NyLPC_cStopwatch_finalize(&(i_inst->_periodic_sw)); - NyLPC_cUdpSocket_finalize(&(i_inst->super)); + NyLPC_iUdpSocket_finalize(i_inst->_socket); } void NyLPC_cSsdpSocket_start(NyLPC_TcSsdpSocket_t* i_inst) @@ -598,7 +600,7 @@ if(tx==NULL){ NyLPC_OnErrorGoto(ERROR1); } - if(!NyLPC_cUdpSocket_psend(&i_inst->super,&SSDP_MCAST_IPADDR,1900,tx,tx_len)){ + if(!NyLPC_iUdpSocket_psend(i_inst->_socket,&SSDP_MCAST_IPADDR,1900,tx,tx_len)){ NyLPC_OnErrorGoto(ERROR2); } //all device @@ -611,7 +613,7 @@ if(tx==NULL){ NyLPC_OnErrorGoto(ERROR1); } - if(!NyLPC_cUdpSocket_psend(&i_inst->super,&SSDP_MCAST_IPADDR,1900,tx,tx_len)){ + if(!NyLPC_iUdpSocket_psend(i_inst->_socket,&SSDP_MCAST_IPADDR,1900,tx,tx_len)){ NyLPC_OnErrorGoto(ERROR2); } //devicatype @@ -622,7 +624,7 @@ if(tx==NULL){ NyLPC_OnErrorGoto(ERROR1); } - if(!NyLPC_cUdpSocket_psend(&i_inst->super,&SSDP_MCAST_IPADDR,1900,tx,tx_len)){ + if(!NyLPC_iUdpSocket_psend(i_inst->_socket,&SSDP_MCAST_IPADDR,1900,tx,tx_len)){ NyLPC_OnErrorGoto(ERROR2); } for(i2=0;i2<i_inst->ref_device_record[i]->number_of_service;i2++){ @@ -633,14 +635,14 @@ if(tx==NULL){ NyLPC_OnErrorGoto(ERROR1); } - if(!NyLPC_cUdpSocket_psend(&i_inst->super,&SSDP_MCAST_IPADDR,1900,tx,tx_len)){ + if(!NyLPC_iUdpSocket_psend(i_inst->_socket,&SSDP_MCAST_IPADDR,1900,tx,tx_len)){ NyLPC_OnErrorGoto(ERROR2); } } } return; ERROR2: - NyLPC_cUdpSocket_releaseSendBuf(&i_inst->super,tx); + NyLPC_iUdpSocket_releaseSendBuf(i_inst->_socket,tx); ERROR1: return; }
--- a/core/net/upnp/NyLPC_cSsdpSocket.h Thu Nov 13 14:06:19 2014 +0000 +++ b/core/net/upnp/NyLPC_cSsdpSocket.h Wed Nov 19 14:45:17 2014 +0000 @@ -7,8 +7,8 @@ #ifndef NYLPC_CSSDPSOCKET_H_ #define NYLPC_CSSDPSOCKET_H_ +#include "NyLPC_netif.h" #include "NyLPC_UPnP_types.h" -#include "NyLPC_uipService.h" #ifdef __cplusplus extern "C" { @@ -27,7 +27,7 @@ struct NyLPC_TcSsdpSocket { - NyLPC_TcUdpSocket_t super; + NyLPC_TiUdpSocket_t* _socket; NyLPC_TcStopwatch_t _periodic_sw; /** * locationパス
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/NyLPC_NetIf_ethernet_types.c Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,59 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + * + * Parts of this file were leveraged from uIP: + * + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "NyLPC_NetIf_ethernet_types.h" + +const struct NyLPC_TEthAddr NyLPC_TEthAddr_BROADCAST = { { 0xff, 0xff, 0xff,0xff, 0xff, 0xff } }; + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/NyLPC_NetIf_ethernet_types.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,110 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + * + * Parts of this file were leveraged from uIP: + * + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef NyLPC_NetIF_ethernet_types_h +#define NyLPC_NetIF_ethernet_types_h +#include "../include/NyLPC_config.h" +#include "../include/NyLPC_stdlib.h" +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#ifndef PACK_STRUCT_END + #define PACK_STRUCT_END __attribute((packed)) +#endif + +/********************************************************************** + * + * struct NyLPC_TEthAddr + * + **********************************************************************/ + +/** + * この構造体は、48bitのイーサネットアドレスを格納します。 + */ +struct NyLPC_TEthAddr +{ + NyLPC_TUInt8 addr[6]; +}PACK_STRUCT_END; + + +/** + * 構造体にEthernetアドレスをセットします。 + * 次のように使います。 + \code + struct NyLPC_TEthAddr en=NyLPC_TEthAddr_pack(1,2,3,4,5,6); + \endcode + */ +#define NyLPC_TEthAddr_pack(a1,a2,a3,a4,a5,a6) {{(a1),(a2),(a3),(a4),(a5),(a6)}} +/** + * 変数にEthernetアドレスをセットします。 + * 次のように使います。 + \code + struct NyLPC_TEthAddr en; + NyLPC_TEthAddr_set(&en,1,2,3,4,5,6); + \endcode + */ +#define NyLPC_TEthAddr_set(v,a1,a2,a3,a4,a5,a6) {(v)->addr[0]=(a1);(v)->addr[1]=(a2);(v)->addr[2]=(a3);(v)->addr[3]=(a4);(v)->addr[4]=(a5);(v)->addr[5]=(a6);} + +extern const struct NyLPC_TEthAddr NyLPC_TEthAddr_BROADCAST; + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/NyLPC_NetIf_ip_types.c Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,432 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + * + * Parts of this file were leveraged from uIP: + * + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "NyLPC_NetIf_ip_types.h" + + + +const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_ZERO={0x00000000}; +const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_ALL ={0xffffffff}; +const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_BROADCAST = { 0xffffffff }; +const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_MULTICAST = NyLPC_TIPv4Addr_pack(224,0,0,0); +const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_MULTICAST_MASK = NyLPC_TIPv4Addr_pack(224,0,0,0); +const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_APIPA_MASK = NyLPC_TIPv4Addr_pack(255,255,0,0); + +NyLPC_TInt16 NyLPC_TIPv4Addr_toString(const struct NyLPC_TIPv4Addr* i_ip,NyLPC_TChar* i_buf) +{ + NyLPC_TUInt32 ip; + NyLPC_TChar* p=i_buf; + NyLPC_TUInt8 v; + NyLPC_TInt8 l; + //IPをホストオーダーにする。 + ip=NyLPC_NTOHL(i_ip->v); + for(l=3;l>=0;l--){ + v=(ip>>(8*l))&0xff; + if(v>=100){ + *p=(v/100)+'0'; + p++; + } + if(v>=10){ + *p=((v%100)/10)+'0'; + p++; + } + *p=(v%10)+'0'; + *(p+1)='.'; + p+=2; + } + *(p-1)='\0'; + return p-i_buf-1; +} + + +NyLPC_TUInt16 NyLPC_uip_chksum(NyLPC_TUInt16 sum, const NyLPC_TUInt8 *data, NyLPC_TUInt16 len) +{ + NyLPC_TUInt16 t; + const NyLPC_TUInt8 *dataptr; + const NyLPC_TUInt8 *last_byte; + + dataptr = data; + last_byte = data + len - 1; + + while (dataptr < last_byte) { /* At least two more bytes */ + t = (dataptr[0] << 8) + dataptr[1]; + sum += t; + if (sum < t) { + sum++; /* carry */ + } + dataptr += 2; + } + + if (dataptr == last_byte) { + t = (dataptr[0] << 8) + 0; + sum += t; + if (sum < t) { + sum++; /* carry */ + } + } + + /* Return sum in host byte order. */ + return sum; +} + +/*-------------------------------------------------------------------------------- + * + * struct NyLPC_TEthernetIIHeader + * + *------------------------------------------------------------------------------*/ + +/** + * Ethernetヘッダの内容を、ARPパケットの内容に一致するように書き換えます。 + * i_structの後方にあるものと仮定します。 + * 戻り値は、フレームの長さです。 + */ +NyLPC_TUInt16 NyLPC_TEthernetIIHeader_setArpTx( + struct NyLPC_TEthernetIIHeader* i_struct, + const struct NyLPC_TEthAddr* i_my_eth_addr) +{ + struct NyLPC_TArpHeader* arph=(struct NyLPC_TArpHeader*)(((NyLPC_TUInt8*)i_struct)+sizeof(struct NyLPC_TEthernetIIHeader)); + + i_struct->type = NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_ARP); + switch(arph->opcode){ + case NyLPC_HTONS(ARP_REPLY): + memcpy(i_struct->src.addr, i_my_eth_addr->addr, 6); + memcpy(i_struct->dest.addr, arph->dhwaddr.addr, 6); + break; + case NyLPC_HTONS(ARP_REQUEST): + memset(i_struct->dest.addr, 0xff, 6); + memcpy(i_struct->src.addr, i_my_eth_addr->addr, 6); + break; + } + return sizeof(struct NyLPC_TEthernetIIHeader)+sizeof(struct NyLPC_TArpHeader); +} + +/** + * イーサネットヘッダをIPv4向けにセットアップする。 + * 関数は、ペイロードをIPv4ヘッダとして、フレームサイズを計算する。 + */ +NyLPC_TUInt16 NyLPC_TEthernetIIHeader_setIPv4Tx( + struct NyLPC_TEthernetIIHeader* i_eth, + const struct NyLPC_TEthAddr* i_src_eth_addr, + const struct NyLPC_TEthAddr* i_dest_eth_addr) +{ + struct NyLPC_TIPv4Header* iph=(struct NyLPC_TIPv4Header*)(((NyLPC_TUInt8*)i_eth)+sizeof(struct NyLPC_TEthernetIIHeader)); + + i_eth->type = NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_IP); + /* Build an ethernet header. */ + memcpy(i_eth->dest.addr,i_dest_eth_addr, 6); + memcpy(i_eth->src.addr, i_src_eth_addr->addr, 6); + + + //IPフラグメントに応じたサイズ計算 + switch(iph->proto){ + case UIP_PROTO_TCP: + return sizeof(struct NyLPC_TEthernetIIHeader)+NyLPC_htons(iph->len16); + case UIP_PROTO_UDP: + return sizeof(struct NyLPC_TEthernetIIHeader)+NyLPC_htons(iph->len16); + case UIP_PROTO_ICMP: + return sizeof(struct NyLPC_TEthernetIIHeader)+NyLPC_htons(iph->len16); + } + return 0; +} +/*-------------------------------------------------------------------------------- + * + * struct NyLPC_TIPv4Header + * + *------------------------------------------------------------------------------*/ + +/** + * based on uip_ipchksum + */ +NyLPC_TUInt16 NyLPC_TIPv4Header_makeIpChecksum(const struct NyLPC_TIPv4Header* ip_header) +{ + NyLPC_TUInt16 sum; + sum = NyLPC_uip_chksum(0, (const NyLPC_TUInt8 *)ip_header,NyLPC_TIPv4Header_getHeaderLength(ip_header)); + return (sum == 0) ? 0xffff : NyLPC_htons(sum); +} + + + +NyLPC_TBool NyLPC_TIPv4Header_isCorrectIpCheckSum(const struct NyLPC_TIPv4Header* ip_header) +{ + return (NyLPC_TIPv4Header_makeIpChecksum(ip_header)==0xffff); +} + +NyLPC_TBool NyLPC_cIPv4Packet_isCorrectTcpCheckSum(const struct NyLPC_TIPv4Header* ip_header) +{ + return (NyLPC_TIPv4Header_makeTcpChecksum(ip_header) == 0xffff); +} + + + + +/** + * TCPチェックサムを計算します。 + * ペイロードはIPヘッダの後方に連続して存在する物と仮定します。 + * i_lenは、ペイロード長さ + */ +NyLPC_TUInt16 NyLPC_TIPv4Header_makeTcpChecksum( + const struct NyLPC_TIPv4Header* i_iph) +{ + NyLPC_TUInt16 sum; + NyLPC_TUInt16 iph_len=NyLPC_TIPv4Header_getHeaderLength(i_iph); + NyLPC_TUInt16 len = NyLPC_ntohs((i_iph)->len16)- iph_len; + NyLPC_ArgAssert(i_iph!=NULL); + /*TCP疑似ヘッダ部分*/ + /* IP protocol and length fields. This addition cannot carry. */ + sum = len + i_iph->proto; + /* Sum IP source and destination addresses. */ + sum = NyLPC_uip_chksum(sum, (NyLPC_TUInt8 *) &(i_iph->srcipaddr), 2 * sizeof(struct NyLPC_TIPv4Addr)); + /* Sum TCP header and data. */ + sum = NyLPC_uip_chksum(sum, (((NyLPC_TUInt8 *)(i_iph))+iph_len),len); + // sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], i_len_of_data); + return (sum == 0) ? 0xffff : NyLPC_htons(sum); +} + +static NyLPC_TUInt16 pid=0x3939; +/** + * IPヘッダを送信パケット用に設定する。 + * ipid16にはコールされるたびに新しい値を設定する。 + * ipcecksumには0を設定する。 + * この関数は、パケットサイズ,ローカルIP/リモートIPの設定はしない。 + */ +void NyLPC_TIPv4Header_writeTxIpHeader( + struct NyLPC_TIPv4Header* i_struct, + NyLPC_TUInt8 i_proto) +{ + //IPパケットのセット + i_struct->proto=i_proto; + i_struct->ttl = UIP_DEFAULT_IP_TTL; + i_struct->tos = 0; + i_struct->ipid16=(pid++); + i_struct->ipoffset=0;//NyLPC_HTONS(0|0x4000); + i_struct->ipchksum = 0; +} +/*-------------------------------------------------------------------------------- + * + * struct NyLPC_TIPv6Header + * + *------------------------------------------------------------------------------*/ +#define IPV6_HEADER_SIZE 40 +/** + * IPヘッダーを作って埋める関数 + */ +void NyLPC_TIPv6Header_setSendHeader( + struct NyLPC_TIPv6Header* i_iph, + uip_ip6addr_t i_src, + uip_ip6addr_t i_dest, + NyLPC_TUInt8 i_proto, + NyLPC_TUInt8 i_ttl, + NyLPC_TUInt16 i_len) +{ + i_iph->srcipaddr=i_src; + i_iph->destipaddr=i_dest; + i_iph->proto=i_proto; + i_iph->ttl = i_ttl; + i_iph->vtc = 0x60; + i_iph->tcflow = 0x00; + i_iph->flow = 0x00; + i_iph->len16= NyLPC_htons(i_len - IPV6_HEADER_SIZE); + return; +} + + +/** + * チェックサムは、TCP疑似ヘッダから計算。 + * i_tcpiphの送信/受信アドレス、ProtocolID,DATAフィールドは有効であること。 + */ +NyLPC_TUInt16 NyLPC_TIPv6Header_makeTcpChecksum( + struct NyLPC_TIPv6Header* i_iph, + NyLPC_TUInt16 i_len) +{ + NyLPC_TUInt16 sum; + NyLPC_TUInt16 len; + len = i_len; + /*TCP疑似ヘッダ部分*/ + /* IP protocol and length fields. This addition cannot carry. */ + sum = len + i_iph->proto; + /* Sum IP source and destination addresses. */ + sum = NyLPC_uip_chksum(sum, (NyLPC_TUInt8 *) &(i_iph->srcipaddr), 2 * sizeof(uip_ip6addr_t)); + /* Sum TCP header and data. */ + sum = NyLPC_uip_chksum(sum, (((NyLPC_TUInt8 *)(i_iph))+IPV6_HEADER_SIZE),len); + // sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], i_len_of_data); + return (sum == 0) ? 0xffff : NyLPC_htons(sum); +} + + + +/*-------------------------------------------------------------------------------- + * + * struct NyLPC_TTcpHeader + * + *------------------------------------------------------------------------------*/ + + +/** + * MMSオプションの値を返す。 + */ +NyLPC_TBool NyLPC_TTcpHeader_getTcpMmsOpt( + const struct NyLPC_TTcpHeader* i_struct,NyLPC_TUInt16* o_val) +{ + NyLPC_TUInt8* opt; + opt=NyLPC_TTcpHeader_getTcpOptFragmentPtr(i_struct,TCP_OPT_MSS); + if(opt!=NULL){ + if (*(opt+1) == TCP_OPT_MSS_LEN) + { + // An MSS option with the right option length. + *o_val = ((NyLPC_TUInt16) (*(opt+2)) << 8) | (NyLPC_TUInt16) (*(opt + 3)); + //And we are done processing options. + return NyLPC_TBool_TRUE; + } + } + return NyLPC_TBool_FALSE; +} + +#define DEFAULT_TCP_HEADER_LEN 20 +/** + * TCPフラグメントのポインタを返す。 + */ +NyLPC_TUInt8* NyLPC_TTcpHeader_getTcpOptFragmentPtr( + const struct NyLPC_TTcpHeader* i_struct, + NyLPC_TUInt8 i_opt_id) +{ + NyLPC_TUInt8 opt; + int c; + NyLPC_TUInt8* opt_buf=((NyLPC_TUInt8*)(i_struct+1)); + + /* Parse the TCP MSS option, if present. */ + if ((i_struct->tcpoffset & 0xf0) > 0x50){ + for (c = 0; c < ((i_struct->tcpoffset >> 4) - 5) << 2;) + { + opt=opt_buf[c]; + if(opt==i_opt_id){ + return opt_buf+c;//found! + } + switch(opt) + { + case TCP_OPT_NOOP: + continue;//NOP option. + case TCP_OPT_END: + return NULL;//End of options. + default: + // All other options have a length field, so that we easily can skip past them. + if (opt_buf[1 + c] == 0) { + // If the length field is zero, the options are malformed and we don't process them further. + NyLPC_OnErrorGoto(ERROR_INVALID_OPTION); + } + c += opt_buf[1 + c]; + } + } + } +ERROR_INVALID_OPTION: + return NULL; +} +/* + * Optionパラメタを書きだす。 + */ +void NyLPC_TTcpHeader_setMmsOpt(NyLPC_TUInt8* i_opt_addr,NyLPC_TUInt16 i_mms) +{ + i_opt_addr[0] = TCP_OPT_MSS; + i_opt_addr[1] = TCP_OPT_MSS_LEN; + i_opt_addr[2] = (i_mms) / 256; + i_opt_addr[3] = (i_mms) & 255; + return; +} + + +NyLPC_TUInt16 NyLPC_TTcpHeader_getHeaderLength(const struct NyLPC_TTcpHeader* ip_header) +{ + return (ip_header->tcpoffset>>4)*4; +} +/*-------------------------------------------------------------------------------- + * + * struct NyLPC_TUdpHeader + * + *------------------------------------------------------------------------------*/ + + + +/*-------------------------------------------------------------------------------- + * + * struct NyLPC_TArpHeader + * + *------------------------------------------------------------------------------*/ +/** + * i_req_addrを問い合わせるARP_REQUESTを生成します。 + */ +void NyLPC_TArpHeader_setArpRequest( + struct NyLPC_TArpHeader* i_struct, + const struct NyLPC_TIPv4Addr i_saddr, + const struct NyLPC_TEthAddr* i_srceth, + const struct NyLPC_TIPv4Addr* i_req_addr) +{ + memset(i_struct->dhwaddr.addr, 0x00, 6); + memcpy(i_struct->shwaddr.addr, i_srceth, 6); + i_struct->dipaddr=*i_req_addr; + i_struct->sipaddr=i_saddr; + i_struct->opcode = NyLPC_HTONS(ARP_REQUEST); /* ARP request. */ + i_struct->hwtype = NyLPC_HTONS(ARP_HWTYPE_ETH); + i_struct->protocol = NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_IP); + i_struct->hwlen = 6; + i_struct->protolen = 4; + return; +} + +/*-------------------------------------------------------------------------------- + * + * class IPv4Route + * + *------------------------------------------------------------------------------*/ + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/NyLPC_NetIf_ip_types.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,480 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + * + * Parts of this file were leveraged from uIP: + * + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef NyLPC_NETIF_IP_TYPES_h +#define NyLPC_NETIF_IP_TYPES_h +#include "NyLPC_config.h" +#include "NyLPC_stdlib.h" +#include "NyLPC_NetIf_ethernet_types.h" +#include "NyLPC_NetIf_ip_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define UIP_PROTO_ICMP 1 +#define UIP_PROTO_TCP 6 +#define UIP_PROTO_UDP 17 +#define UIP_PROTO_ICMP6 58 + +#define ARP_REQUEST 1 +#define ARP_REPLY 2 +#define ARP_HWTYPE_ETH 1 + +/** イーサネットヘッダのサイズ値*/ +#define UIP_ETHERHEADER_LEN 14 +#define UIP_TCPH_LEN 20 /* Size of TCP header */ +#define UIP_IPH_LEN 20 /* Size of IP header */ + +#ifndef PACK_STRUCT_END + #define PACK_STRUCT_END __attribute((packed)) +#endif + +/********************************************************************** + * + * + * + **********************************************************************/ + +/** + * IPアドレスを格納します。 + * IPアドレスは、ネットワークオーダーで設定します。 + */ +struct NyLPC_TIPv4Addr +{ + NyLPC_TUInt32 v; +}PACK_STRUCT_END; +extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_ZERO; +extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_ALL; +extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_BROADCAST; +extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_MULTICAST; +extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_MULTICAST_MASK; +extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_APIPA_MASK; + +/** + * addr1とaddr2が全く同じであるかをテストします。 + * \hideinitializer + */ +#define NyLPC_TIPv4Addr_isEqual(v1,v2) ((v1)->v==(v2)->v) +/** + * addr1とaddr2をmaskでマスクした結果を比較します。 + * \hideinitializer + */ +#define NyLPC_TIPv4Addr_isEqualWithMask(addr1, addr2, mask) ((((addr1)->v) & ((mask)->v))==(((addr2)->v) & ((mask)->v))) + +/** + * 変数にIP v4アドレスをセットします。 + * 次のように使います。 + \code + NyLPC_TIPv4Addr ip; + NyLPC_TIpv4Addr_set(&ip,1,2,3,4); + \endcode + */ +#define NyLPC_TIPv4Addr_set(s,a0,a1,a2,a3) (s)->v=NyLPC_htonl((0xff000000&(((NyLPC_TUInt32)(a0))<<24))|(0x00ff0000&(((NyLPC_TUInt32)(a1))<<16))|(0x0000ff00&(((NyLPC_TUInt32)(a2))<<8))|(0x000000ff&((NyLPC_TUInt32)(a3)))) +#define NyLPC_TIPv4Addr_pack(a0,a1,a2,a3) {NyLPC_HTONL((0xff000000&(((NyLPC_TUInt32)(a0))<<24))|(0x00ff0000&(((NyLPC_TUInt32)(a1))<<16))|(0x0000ff00&(((NyLPC_TUInt32)(a2))<<8))|(0x000000ff&((NyLPC_TUInt32)(a3))))} + +/** + * IPアドレスを文字列に変換して返します。 + */ +NyLPC_TInt16 NyLPC_TIPv4Addr_toString(const struct NyLPC_TIPv4Addr* i_ip,NyLPC_TChar* i_buf); + + + + + +struct uip_ip6addr +{ + NyLPC_TUInt16 v[8]; +}PACK_STRUCT_END; + +typedef struct uip_ip6addr uip_ip6addr_t; + +NyLPC_TUInt16 NyLPC_uip_chksum(NyLPC_TUInt16 sum, const NyLPC_TUInt8 *data, NyLPC_TUInt16 len); + + + + +/** + * TTL + */ +#define UIP_DEFAULT_IP_TTL 64 + + + +/** + * The maximum number of times a segment should be retransmitted + * before the connection should be aborted. + * + * This should not be changed. + */ +#define UIP_MAXRTX 8 + + + + + +# if UIP_BYTE_ORDER == NyLPC_ENDIAN_BIG +# define NyLPC_HTONS(n) (n) +# define NyLPC_htons(n) (n) +# define NyLPC_ntohs(n) (n) +# define NyLPC_htonl(n) (n) +# define NyLPC_ntohl(n) (n) +# define NyLPC_HTONS(n) (n) +# define NyLPC_NTOHS(n) (n) +# else +# define NyLPC_htonl(n) NyLPC_TUInt32_bswap(n) +# define NyLPC_ntohl(n) NyLPC_TUInt32_bswap(n) +# define NyLPC_htons(n) NyLPC_TUInt16_bswap(n) +# define NyLPC_ntohs(n) NyLPC_TUInt16_bswap(n) +# define NyLPC_HTONS(n) NyLPC_TUInt16_BSWAP(n) +# define NyLPC_NTOHS(n) NyLPC_TUInt16_BSWAP(n) +# define NyLPC_NTOHL(n) NyLPC_TUInt32_BSWAP(n) +# define NyLPC_HTONL(n) NyLPC_TUInt32_BSWAP(n) +#endif /* NyLPC_HTONS */ + + + + +/********************************************************************** + * + * struct NyLPC_TEthernetIIHeader + * + **********************************************************************/ + +#define NyLPC_TEthernetIIHeader_TYPE_IP 0x0800 +#define NyLPC_TEthernetIIHeader_TYPE_ARP 0x0806 +#define NyLPC_TEthernetIIHeader_TYPE_IPV6 0x86DD +//#define UIP_ETHTYPE_IP 0x0800 +//#define UIP_ETHTYPE_ARP 0x0806 +//#define UIP_ETHTYPE_IP6 0x86dd + +struct NyLPC_TEthernetIIHeader +{ + struct NyLPC_TEthAddr dest; + struct NyLPC_TEthAddr src; + NyLPC_TUInt16 type; +}PACK_STRUCT_END; + + +NyLPC_TUInt16 NyLPC_TEthernetIIHeader_setArpTx( + struct NyLPC_TEthernetIIHeader* i_struct, + const struct NyLPC_TEthAddr* i_my_eth_addr); + +NyLPC_TUInt16 NyLPC_TEthernetIIHeader_setIPv4Tx( + struct NyLPC_TEthernetIIHeader* i_eth, + const struct NyLPC_TEthAddr* i_src_eth_addr, + const struct NyLPC_TEthAddr* i_dest_eth_addr); +/********************************************************************** + * + * struct NyLPC_TIPv4Header + * + **********************************************************************/ + + +/** + * IPパケットヘッダのメモリマップ構造体 + * 値はすべてネットワークオーダーです。 + */ +struct NyLPC_TIPv4Header +{ + NyLPC_TUInt8 vhl; + NyLPC_TUInt8 tos; + NyLPC_TUInt16 len16; + NyLPC_TUInt16 ipid16; + NyLPC_TUInt16 ipoffset; + NyLPC_TUInt8 ttl; + NyLPC_TUInt8 proto; + NyLPC_TUInt16 ipchksum; + struct NyLPC_TIPv4Addr srcipaddr; + struct NyLPC_TIPv4Addr destipaddr; +}PACK_STRUCT_END; + + + + +NyLPC_TBool NyLPC_TIPv4Header_isCorrectIpCheckSum( + const struct NyLPC_TIPv4Header* ip_header); + +NyLPC_TBool NyLPC_cIPv4Packet_isCorrectTcpCheckSum( + const struct NyLPC_TIPv4Header* ip_header); + +NyLPC_TUInt16 NyLPC_TIPv4Header_makeIpChecksum(const struct NyLPC_TIPv4Header* ip_header); + + +NyLPC_TUInt16 NyLPC_TIPv4Header_makeTcpChecksum( + const struct NyLPC_TIPv4Header* i_iph); + +#define NyLPC_TIPv4Header_isDestAddrEqual(i_struct,i_addr) ((i_struct)->destipaddr==(i_addr)) +#define NyLPC_TIPv4Header_isSrcAddrEqual(i_struct,i_addr) ((i_struct)->srcipaddr==(i_addr)) + +/** + * IPヘッダの長さを返す。 + */ +#define NyLPC_TIPv4Header_getHeaderLength(i_iph) (((i_iph)->vhl & 0x0f)*4) +/** + * IPパケット全体の長さを返す。 + */ +#define NyLPC_TIPv4Header_getPacketLength(i_iph) (NyLPC_ntohs((i_iph)->len16)) + +/** + * IPヘッダを送信パケット用に設定する。 + * ipid16にはコールされるたびに新しい値を設定する。 + * ipcecksumには0を設定する。 + * この関数は、パケットサイズ,ローカルIP/リモートIPの設定はしない。 + */ +void NyLPC_TIPv4Header_writeTxIpHeader( + struct NyLPC_TIPv4Header* i_struct, + NyLPC_TUInt8 i_proto); +/********************************************************************** + * + * struct NyLPC_TIPv6Header + * + **********************************************************************/ + + +struct NyLPC_TIPv6Header +{ + /* IPv6 header. */ + NyLPC_TUInt8 vtc; + NyLPC_TUInt8 tcflow; + NyLPC_TUInt16 flow; + NyLPC_TUInt8 len16; + NyLPC_TUInt8 proto, ttl; + uip_ip6addr_t srcipaddr; + uip_ip6addr_t destipaddr; +}PACK_STRUCT_END; + +void NyLPC_TIPv6Header_setSendHeader( + struct NyLPC_TIPv6Header* i_iph, + uip_ip6addr_t i_src, + uip_ip6addr_t i_dest, + NyLPC_TUInt8 i_proto, + NyLPC_TUInt8 i_ttl, + NyLPC_TUInt16 i_len); + +NyLPC_TUInt16 NyLPC_TIPv6Header_makeTcpChecksum( + struct NyLPC_TIPv6Header* i_iph, + NyLPC_TUInt16 i_len); + +#define NyLPC_TIPv6Header_isDestAddrEqual(i_struct,i_addr) (memcmp((i_struct)->destipaddr,(i_addr),sizeof(uip_ip6addr_t))) +#define NyLPC_TIPv6Header_isSrcAddrEqual(i_struct,i_addr) (memcmp(i_struct)->srcipaddr,(i_addr),sizeof(uip_ip6addr_t))) +/********************************************************************** + * + * struct NyLPC_TTcpHeader + * + **********************************************************************/ +#define TCP_OPT_END 0 /* End of TCP options list */ +#define TCP_OPT_NOOP 1 /* "No-operation" TCP option */ +#define TCP_OPT_MSS 2 /* Maximum segment size TCP option */ +#define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */ + +/** + * TCP/IPヘッダのメモリマップ構造体 + * マルチバイトの値は、全てネットワークオーダーです。 + */ +struct NyLPC_TTcpHeader +{ + //TCP header. + NyLPC_TUInt16 srcport; + NyLPC_TUInt16 destport; + NyLPC_TUInt32 seqno32; + NyLPC_TUInt32 ackno32; + NyLPC_TUInt8 tcpoffset; + NyLPC_TUInt8 flags; + NyLPC_TUInt16 wnd16; + NyLPC_TUInt16 tcpchksum; + NyLPC_TUInt8 urgp[2]; +// NyLPC_TUInt8 optdata[4]; +} PACK_STRUCT_END; + + +NyLPC_TUInt8* NyLPC_TTcpHeader_getTcpOptFragmentPtr( + const struct NyLPC_TTcpHeader* i_struct, + NyLPC_TUInt8 i_opt_id); + +NyLPC_TBool NyLPC_TTcpHeader_getTcpMmsOpt( + const struct NyLPC_TTcpHeader* i_struct,NyLPC_TUInt16* o_val); + +/** + * この関数は、TCPヘッダの長さを返します。ヘッダの長さは、i_structのフィールドから計算します。 + * @param i_struct + * 構造体のアドレス。 + */ +NyLPC_TUInt16 NyLPC_TTcpHeader_getHeaderLength(const struct NyLPC_TTcpHeader* i_struct); + +/** + * この関数は、指定したアドレスに、mmsオプション値を書き込みます。 + */ +void NyLPC_TTcpHeader_setMmsOpt(NyLPC_TUInt8* i_opt_addr,NyLPC_TUInt16 i_mms); + + +/********************************************************************** + * + * struct NyLPC_TUdpHeader + * + **********************************************************************/ + +/** + * UDP/IPヘッダのメモリマップ構造体 + */ +struct NyLPC_TUdpHeader +{ + NyLPC_TUInt16 srcport; + NyLPC_TUInt16 destport; + NyLPC_TUInt16 udplen; + NyLPC_TUInt16 udpchksum; +} PACK_STRUCT_END; + +/** + * UDPヘッダの長さを返す。 + */ +#define NyLPC_TUdpHeader_getHeaderLength(i_struct) (8) + +/********************************************************************** + * + * struct NyLPC_TIcmpipHeader + * + **********************************************************************/ + + +struct NyLPC_TIcmpHeader +{ + /* ICMP (echo) header. */ + NyLPC_TUInt8 type, icode; + NyLPC_TUInt16 icmpchksum; + #if !UIP_CONF_IPV6 + NyLPC_TUInt16 id, seqno; + #else /* !UIP_CONF_IPV6 */ + NyLPC_TUInt8 flags, reserved1, reserved2, reserved3; + NyLPC_TUInt8 icmp6data[16]; + NyLPC_TUInt8 options[1]; + #endif /* !UIP_CONF_IPV6 */ +} PACK_STRUCT_END; + +/********************************************************************** + * + * struct NyLPC_TIcmpipHeader + * + **********************************************************************/ + +struct NyLPC_TArpHeader +{ + NyLPC_TUInt16 hwtype; + NyLPC_TUInt16 protocol; + NyLPC_TUInt8 hwlen; + NyLPC_TUInt8 protolen; + NyLPC_TUInt16 opcode; + struct NyLPC_TEthAddr shwaddr; + struct NyLPC_TIPv4Addr sipaddr; + struct NyLPC_TEthAddr dhwaddr; + struct NyLPC_TIPv4Addr dipaddr; +} PACK_STRUCT_END; + + +/** + * i_req_addrを問い合わせるARP_REQUESTを生成します。 + */ +void NyLPC_TArpHeader_setArpRequest( + struct NyLPC_TArpHeader* i_struct, + const struct NyLPC_TIPv4Addr i_saddr, + const struct NyLPC_TEthAddr* i_srceth, + const struct NyLPC_TIPv4Addr* i_req_addr); + + +typedef struct NyLPC_TcEthernetIIPayload NyLPC_TcEthernetIIPayload_t; + + + + +/********************************************************************** + * + * NyLPC_TIPv6Payload + * + **********************************************************************/ + + +struct NyLPC_TIPv6Payload +{ + struct NyLPC_TIPv6Header* header; + union{ + void* rawbuf; + void* tcp; + void* udp; + void* icmp6; + }payload; +}; + +struct NyLPC_TcEthernetIIPayload +{ + struct NyLPC_TEthernetIIHeader* header; + union{ + void* rawbuf; + struct NyLPC_TArpHeader* arp; + struct NyLPC_TIPv4Payload* ipv4; + struct NyLPC_TIPv6Payload* ipv6; + }payload; + NyLPC_TUInt16 len; +}; + + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/NyLPC_cIPv4Config.c Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,72 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + *********************************************************************************/ + +#include "NyLPC_cIPv4Config.h" + + + +/** + * See header file. + */ +void NyLPC_cIPv4Config_initialzeForEthernet(NyLPC_TcIPv4Config_t* i_inst,const struct NyLPC_TEthAddr* i_ether_addr,NyLPC_TUInt16 i_ether_frame_len) +{ + i_inst->ip_addr=i_inst->netmask=i_inst->dr_addr=NyLPC_TIPv4Addr_ZERO; + i_inst->eth_mac=*i_ether_addr; + //mssの計算 + i_inst->default_mss=i_ether_frame_len-(UIP_ETHERHEADER_LEN+UIP_TCPH_LEN + UIP_IPH_LEN); + return; +} +void NyLPC_cIPv4Config_initialzeCopy(NyLPC_TcIPv4Config_t* i_inst,const NyLPC_TcIPv4Config_t* i_src) +{ + memcpy(i_inst,i_src,sizeof(NyLPC_TcIPv4Config_t)); +} +/** + * See header file. + */ +void NyLPC_cIPv4Config_setDefaultRoute(NyLPC_TcIPv4Config_t* i_inst,const struct NyLPC_TIPv4Addr* i_dr_addr) +{ + i_inst->dr_addr=*i_dr_addr; + return; +} + +/** + * See header file. + */ +void NyLPC_cIPv4Config_setIp(NyLPC_TcIPv4Config_t* i_inst,const struct NyLPC_TIPv4Addr* i_ipaddr,const struct NyLPC_TIPv4Addr* i_netmask) +{ + i_inst->ip_addr=*i_ipaddr; + i_inst->netmask=*i_netmask; + return; +} + +/** + * See header file. + */ +NyLPC_TBool NyLPC_cIPv4Config_isLocalIP(const NyLPC_TcIPv4Config_t* i_inst,const struct NyLPC_TIPv4Addr* i_target_ip) +{ + return NyLPC_TIPv4Addr_isEqualWithMask(&(i_inst->ip_addr),i_target_ip,&(i_inst->netmask)); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/NyLPC_cIPv4Config.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,135 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + *********************************************************************************/ +/** + * @file + * このファイルは、NyLPC_cIPv4Configクラスを定義します。 + */ +#ifndef NYLPC_CIPV4CONFIG_H_ +#define NYLPC_CIPV4CONFIG_H_ + + +#include "NyLPC_NetIf_ip_types.h" + +/** + * クラス型を定義します。 + * NyLPC_cIPv4Configクラスは、IPと、下位のネットワーク層の設定を保持します。 + * 関連するオブジェクトが、ネットワーク設定を問い合わせる為に使います。 + */ +typedef struct NyLPC_TcIPv4Config NyLPC_TcIPv4Config_t; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +/********************************************************************** + * + * class NyLPC_TcIPv4Config + * + **********************************************************************/ + + + + +/** + * NyLPC_TcIPv4Configクラスの構造体です。 + */ +struct NyLPC_TcIPv4Config +{ + /** イーサネットアドレスを格納します。 */ + struct NyLPC_TEthAddr eth_mac; + /** IPアドレスを格納します。Network orderです。 */ + struct NyLPC_TIPv4Addr ip_addr; + /** ネットマスクを格納します。Network orderです。 */ + struct NyLPC_TIPv4Addr netmask; + /** デフォルトゲートウェイアドレスを格納します。Network orderです。 */ + struct NyLPC_TIPv4Addr dr_addr; + /** デフォルトMMSサイズです。送信パケットのMSS値、受信パケットのデフォルトMSS値として使います。 */ + NyLPC_TUInt16 default_mss; +}; + +#define NyLPC_TcIPv4Config_getEtherMac000120203(v)(((v)->eth_mac.addr[0]<<24)|((v)->eth_mac.addr[1]<<16)|((v)->eth_mac.addr[2]<<8)|((v)->eth_mac.addr[3]<<0)) +#define NyLPC_TcIPv4Config_getEtherMac0405xxxx(v) (((v)->eth_mac.addr[4]<<24)|((v)->eth_mac.addr[5]<<16)) + +/** + * コンストラクタです。 + * イーサネット用にコンフィギュレーションを初期化します。 + * @param i_inst + * 初期化するインスタンスです。 + * @param i_ether_frame_len + * イーサネットフレームのサイズ。この数値から、MSSのデフォルト値を計算します。 + */ +void NyLPC_cIPv4Config_initialzeForEthernet(NyLPC_TcIPv4Config_t* i_inst,const struct NyLPC_TEthAddr* i_ether_addr,NyLPC_TUInt16 i_ether_frame_len); + +/** + * コピーコンストラクタ + */ +void NyLPC_cIPv4Config_initialzeCopy(NyLPC_TcIPv4Config_t* i_inst,const NyLPC_TcIPv4Config_t* i_src); + + +/** + * デストラクタです。インスタンスを破棄して、確保している動的リソースを元に戻します。 + * @param i_inst + * 破棄するインスタンスです。 + * initializeに成功したインスタンスだけが指定できます。 + */ +#define NyLPC_cIPv4Config_finalize(i_inst) + +/** + * この関数は、IPのデフォルトゲートウェイを設定します。dr_addrの値を更新します。 + * @param i_inst + * 操作するインスタンスです。 + * @param i_dr_addr + * 設定するIPアドレスを格納したアドレスです。 + */ +void NyLPC_cIPv4Config_setDefaultRoute(NyLPC_TcIPv4Config_t* i_inst,const struct NyLPC_TIPv4Addr* i_dr_addr); + +/** + * この関数は、ローカルIPアドレスとネットマスクを設定します。 + * @param i_inst + * 操作するインスタンスです。 + * @param i_ipaddr + * 設定するIPアドレスを格納したアドレスです。 + * @param i_netmask + * 設定するネットマスクを格納したアドレスです。 + */ +void NyLPC_cIPv4Config_setIp(NyLPC_TcIPv4Config_t* i_inst,const struct NyLPC_TIPv4Addr* i_ipaddr,const struct NyLPC_TIPv4Addr* i_netmask); + +/** + * この関数は、i_target_ipが、現在のIPアドレスに対するローカルアドレスであるかを返します。 + * @param i_inst + * 操作するインスタンスです。 + * @param i_target_ip + * 確認するIPアドレスです。 + * @return + * i_target_ipがローカルIPアドレスなら、TRUEを返します。 + */ +NyLPC_TBool NyLPC_cIPv4Config_isLocalIP(const NyLPC_TcIPv4Config_t* i_inst,const struct NyLPC_TIPv4Addr* i_target_ip); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/NyLPC_cNetIf.c Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,102 @@ + +#include "NyLPC_cNetIf.h" +#include "./mimicip/NyLPC_cMiMicIpNetIf_protected.h" +#include "dhcp/NyLPC_cDhcpClient.h" +#include "apipa/NyLPC_cApipa.h" + + +/** + * 唯一のネットワークインタフェイス + */ +const static struct NyLPC_TiNetInterface_Interface* netif; + + + + + +void NyLPC_cNetIf_initialize(void) +{ + if(netif==NULL){ + //ここでネットワークインタフェイスを切り替えてくれ。 + netif=NyLPC_cMiMicIpNetIf_getNetInterface(); + } +} + +void NyLPC_cNetIf_start(const NyLPC_TcIPv4Config_t* i_ref_config) +{ + netif->start(i_ref_config); + return; +} + +void NyLPC_cNetIf_stop(void) +{ + netif->stop(); + return; +} + + + +/** + * 指定したIPアドレスを要求するARPリクエストを発行します。 + */ +void NyLPC_cNetIf_sendArpRequest(const struct NyLPC_TIPv4Addr* i_addr) +{ + netif->sendarprequest(i_addr); +} +/** + * ARPテーブルに指定したIPがあるかを返します。 + */ +NyLPC_TBool NyLPC_cNetIf_hasArpInfo(const struct NyLPC_TIPv4Addr* i_addr) +{ + return netif->hasarpinfo(i_addr); +} + +NyLPC_TBool NyLPC_cNetIf_isInitService(void) +{ + return netif->isinitservice(); +} + +NyLPC_TiTcpSocket_t* NyLPC_cNetIf_createTcpSocketEx(NyLPC_TSocketType i_socktype) +{ + return netif->createTcpSocketEx(i_socktype); +} +NyLPC_TiUdpSocket_t* NyLPC_cNetIf_createUdpSocketEx(NyLPC_TUInt16 i_port,NyLPC_TSocketType i_socktype) +{ + return netif->createUdpSocetEx(i_port,i_socktype); +} +NyLPC_TiTcpListener_t* NyLPC_cNetIf_createTcpListenerEx(NyLPC_TUInt16 i_port) +{ + return netif->createTcpListener(i_port); +} + +const struct NyLPC_TNetInterfaceInfo* NyLPC_cNetIf_getInterfaceInfo(void) +{ + return netif->getinterfaceinfo(); +} + + + +NyLPC_TBool NyLPC_cNetIf_requestAddrDhcp(NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat) +{ + NyLPC_TBool ret; + NyLPC_TcDhcpClient_t sock; + //netを開始 + NyLPC_cDhcpClient_initialize(&sock); + ret=NyLPC_cDhcpClient_requestAddr(&sock,i_cfg,i_repeat); + NyLPC_cDhcpClient_finalize(&sock); + return ret; +} + +NyLPC_TBool NyLPC_cNetIf_requestAddrApipa(NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat) +{ + NyLPC_TBool ret; + NyLPC_TcApipa_t sock; + //netを開始 + NyLPC_cApipa_initialize(&sock); + ret=NyLPC_cApipa_requestAddr(&sock,i_cfg,i_repeat); + NyLPC_cApipa_finalize(&sock); + return ret; +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/NyLPC_cNetIf.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,68 @@ +#ifndef NYLPC_CNETIF_H_ +#define NYLPC_CNETIF_H_ +#include "NyLPC_stdlib.h" +#include "NyLPC_cIPv4Config.h" +#include "NyLPC_iTcpListener.h" +#include "NyLPC_iTcpSocket.h" +#include "NyLPC_iUdpSocket.h" +#include "NyLPC_iNetInterface.h" +#include "NyLPC_NetIf_ip_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct NyLPC_TcNetIf NyLPC_TcNetIf_t; + +void NyLPC_cNetIf_initialize(void); +#define NyLPC_cNetIf_finalize() + +NyLPC_TiTcpSocket_t* NyLPC_cNetIf_createTcpSocketEx(NyLPC_TSocketType i_socktype); +NyLPC_TiUdpSocket_t* NyLPC_cNetIf_createUdpSocketEx(NyLPC_TUInt16 i_port,NyLPC_TSocketType i_socktype); +NyLPC_TiTcpListener_t* NyLPC_cNetIf_createTcpListenerEx(NyLPC_TUInt16 i_port); + +/** + * 指定したIPアドレスを要求するARPリクエストを発行します。 + */ +void NyLPC_cNetIf_sendArpRequest(const struct NyLPC_TIPv4Addr* i_addr); + +/** + * ARPテーブルに指定したIPがあるかを返します。 + */ +NyLPC_TBool NyLPC_cNetIf_hasArpInfo(const struct NyLPC_TIPv4Addr* i_addr); + +void NyLPC_cNetIf_start(const NyLPC_TcIPv4Config_t* i_ref_config); +void NyLPC_cNetIf_stop(void); +NyLPC_TBool NyLPC_cNetIf_isInitService(void); + +/** + * NyLPC_TcIPv4Config_tをDHCPで更新します。 + * この関数をコールする時は、サービスは停止中でなければなりません。 + * @param i_cfg + * 更新するi_cfg構造体。 + * emac,default_mssは設定済である必要があります。他のフィールド値は不定で構いません。 + * 更新されるフィールドは、ip,netmast,default_rootの3つです。 + * @return + * 更新に成功した場合TRUE + */ +NyLPC_TBool NyLPC_cNetIf_requestAddrDhcp(NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat); +/** + * NyLPC_TcIPv4Config_tをAPIPAで更新します。 + * この関数をコールする時は、サービスは停止中でなければなりません。 + * @param i_cfg + * 更新するi_cfg構造体。 + * emac,default_mssは設定済である必要があります。他のフィールド値は不定で構いません。 + * 更新されるフィールドは、ip,netmast,default_rootの3つです。 + * @return + * 更新に成功した場合TRUE + */ +NyLPC_TBool NyLPC_cNetIf_requestAddrApipa(NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat); + +const struct NyLPC_TNetInterfaceInfo* NyLPC_cNetIf_getInterfaceInfo(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/NyLPC_iNetInterface.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,98 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + *********************************************************************************/ +#ifndef NYLPC_INETINTERFACE_H_ +#define NYLPC_INETINTERFACE_H_ + + +#include "NyLPC_stdlib.h" +#include "NyLPC_os.h" +#include "NyLPC_iTcpSocket.h" +#include "NyLPC_iUdpSocket.h" +#include "NyLPC_iTcpListener.h" +#include "NyLPC_cIPv4Config.h" +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +struct NyLPC_TNetInterfaceInfo{ + const char* device_name; + const NyLPC_TcIPv4Config_t* current_config; +}; + +/** + * ソケット生成のヒント値 + */ +typedef NyLPC_TUInt16 NyLPC_TSocketType; +#define NyLPC_TSocketType_TCP_NORMAL 0x0100 +#define NyLPC_TSocketType_TCP_HTTP 0x0101 +#define NyLPC_TSocketType_UDP_NORMAL 0x0200 +#define NyLPC_TSocketType_UDP_NOBUF 0x0202 +/********************************************************************** + * Function + **********************************************************************/ + +/** + * 制限時間付きでソケットに接続を待ちます。 + */ +typedef NyLPC_TiTcpSocket_t* (*NyLPC_TiNetInterface_createTcpSocetEx)(NyLPC_TSocketType i_socktype); +typedef NyLPC_TiUdpSocket_t* (*NyLPC_TiNetInterface_createUdpSocetEx)(NyLPC_TUInt16 i_port,NyLPC_TSocketType i_socktype); +typedef NyLPC_TiTcpListener_t* (*NyLPC_TiNetInterface_createTcpListener)(NyLPC_TUInt16 i_port); +/** + * Start関数はイベント関数の定期コールが開始される前に呼び出されます。 + */ +typedef void (*NyLPC_TiNetInterface_start)(const NyLPC_TcIPv4Config_t* i_cfg); +typedef void (*NyLPC_TiNetInterface_stop)(void); + +typedef void(*NyLPC_TiNetInterface_sendArpRequest)(const struct NyLPC_TIPv4Addr* i_addr); +typedef NyLPC_TBool(*NyLPC_TiNetInterface_hasArpInfo)(const struct NyLPC_TIPv4Addr* i_addr); +typedef NyLPC_TBool(*NyLPC_TiNetInterface_isInitService)(void); + +typedef const struct NyLPC_TNetInterfaceInfo* (*NyLPC_TiNetInterface_getInterfaceInfo)(void); + +/********************************************************************** + * Interface + **********************************************************************/ +struct NyLPC_TiNetInterface_Interface +{ + NyLPC_TiNetInterface_createTcpSocetEx createTcpSocketEx; + NyLPC_TiNetInterface_createUdpSocetEx createUdpSocetEx; + NyLPC_TiNetInterface_createTcpListener createTcpListener; + NyLPC_TiNetInterface_start start; + NyLPC_TiNetInterface_stop stop; + NyLPC_TiNetInterface_sendArpRequest sendarprequest; + NyLPC_TiNetInterface_hasArpInfo hasarpinfo; + NyLPC_TiNetInterface_isInitService isinitservice; + NyLPC_TiNetInterface_getInterfaceInfo getinterfaceinfo; +}; + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* NYLPC_CTCPLISTENER_H_ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/NyLPC_iTcpListener.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,75 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + *********************************************************************************/ +#ifndef NYLPC_ITCPLISTENER_H_ +#define NYLPC_ITCPLISTENER_H_ + + +#include "NyLPC_stdlib.h" +#include "NyLPC_os.h" +#include "NyLPC_NetIf_ip_types.h" +#include "NyLPC_iTcpSocket.h" +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct NyLPC_TiTcpListener NyLPC_TiTcpListener_t; + +/********************************************************************** + * Function + **********************************************************************/ + + +/** + * 制限時間付きでソケットに接続を待ちます。 + */ +typedef NyLPC_TBool (*NyLPC_TiTcpListener_listen)(NyLPC_TiTcpListener_t* i_inst,NyLPC_TiTcpSocket_t* i_sock,NyLPC_TUInt32 i_wait_msec); +typedef void (*NyLPC_TiTcpListener_finaize)(NyLPC_TiTcpListener_t* i_inst); +/********************************************************************** + * Interface + **********************************************************************/ + +/** + */ +struct NyLPC_TiTcpListener_Interface +{ + NyLPC_TiTcpListener_listen listen; + NyLPC_TiTcpListener_finaize finalize; +}; + +struct NyLPC_TiTcpListener +{ + const struct NyLPC_TiTcpListener_Interface* _interface; +}; + +#define NyLPC_iTcpListener_listen(i_inst,i_sock,i_wait_msec) ((i_inst)->_interface->listen((i_inst),(i_sock),(i_wait_msec))) +#define NyLPC_iTcpListener_finaize(i_inst) ((i_inst)->_interface->finalize((i_inst))) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* NYLPC_ITCPLISTENER_H_ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/NyLPC_iTcpSocket.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,155 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + *********************************************************************************/ +#ifndef NYLPC_ITCPSOCKET_H_ +#define NYLPC_ITCPSOCKET_H_ + + +#include "NyLPC_stdlib.h" +#include "NyLPC_os.h" +#include "NyLPC_NetIf_ip_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct NyLPC_TiTcpSocket NyLPC_TiTcpSocket_t; + +/********************************************************************** + * Function + **********************************************************************/ + + +typedef const struct NyLPC_TIPv4Addr* (*NyLPC_TiTcpSocket_getPeerAddr)(const NyLPC_TiTcpSocket_t* i_inst); +typedef NyLPC_TUInt16 (*NyLPC_TiTcpSocket_getPeerPort)(const NyLPC_TiTcpSocket_t* i_inst); + + +typedef NyLPC_TBool (*NyLPC_TiTcpSocket_accept)(NyLPC_TiTcpSocket_t* i_inst,NyLPC_TUInt32 i_wait_in_msec); +/** + * @return + * 1 - 以上:受信に成功した。 + * 0 - タイムアウト + * -1 - ソケットがクローズしている + */ +typedef NyLPC_TInt32 (*NyLPC_TiTcpSocket_precv)(NyLPC_TiTcpSocket_t* i_inst,const void** o_buf_ptr,NyLPC_TUInt32 i_wait_msec); +typedef void (*NyLPC_TiTcpSocket_pseek)(NyLPC_TiTcpSocket_t* i_inst,NyLPC_TUInt16 i_seek); +/** + * 送信未達は保障されません。 + * エラーを検出したら、基本的にはソケットをクローズしてください。 + * @param i_wait_msec + * 送信失敗までの待ち時間を指定します。現在は、 + * RTT推定ができないため、TCPの再送を考慮して、最低でも10秒(10000)程度を指定してください。 + * @return + * 送信したバイト数を返します。エラーならば0未満の数を返します。 + * + */ +typedef NyLPC_TInt32(*NyLPC_TiTcpSocket_send)(NyLPC_TiTcpSocket_t* i_inst,const void* i_buf_ptr,NyLPC_TInt32 i_len,NyLPC_TUInt32 i_wait_in_msec); +typedef void(*NyLPC_TiTcpSocket_close)(NyLPC_TiTcpSocket_t* i_inst,NyLPC_TUInt32 i_wait_in_msec); + + +/** + * NyLPC_iTcpSocket_psendで送信するための送信バッファ準備します。 + * @param i_hint + * 送信を希望するデータサイズを指定します。 + * アロケータは出来る限り希望に沿ってメモリを返します。 + * @param o_buf_size + * 取得できたバッファサイズを返します。 + * @return + * 成功した場合、送信バッファを返します。 + * アプリケーションは、可能な限り速やかにデータを書き込んで、NyLPC_iTcpSocket_psendをコールしてください。 + * @note + * Optionフィールドを持つパケットを送信する場合は、オプションデータサイズの合計をデータサイズに指定して、payloadwriterで調整すること。 + */ +typedef void* (*NyLPC_TiTcpSocket_allocSendBuf)(NyLPC_TiTcpSocket_t* i_inst,NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_buf_size,NyLPC_TUInt32 i_wait_in_msec); + +/** + * NyLPC_iTcpSocket_allocSendBufで確保したメモリを開放します。 + */ +typedef void (*NyLPC_TiTcpSocket_releaseSendBuf)(NyLPC_TiTcpSocket_t* i_inst,void* i_buf_ptr); + +/** + * 事前にAllocしたTxパケットを送信します。 + * このAPIはゼロコピー送信をサポートするためのものです。 + * @param i_buf_ptr + * allocSendBufで取得したメモリを指定します。 + * @return + * 失敗した場合、メモリは開放されません。 + */ +typedef NyLPC_TBool (*NyLPC_TiTcpSocket_psend)(NyLPC_TiTcpSocket_t* i_inst,void* i_buf_ptr,int i_len,NyLPC_TUInt32 i_wait_in_msec); + +/** + * TCPソケットをクライアントとしてサーバへ接続します。 + */ +typedef NyLPC_TBool (*NyLPC_TiTcpSocket_connect)(NyLPC_TiTcpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_peer_port,NyLPC_TUInt32 i_wait_in_msec); + +typedef void (*NyLPC_TiTcpSocket_finalize)(NyLPC_TiTcpSocket_t* i_inst); + +/********************************************************************** + * Interface + **********************************************************************/ + +/** + */ +struct NyLPC_TiTcpSocket_Interface +{ + NyLPC_TiTcpSocket_getPeerAddr getpeeraddr; + NyLPC_TiTcpSocket_getPeerPort getpeerport; + NyLPC_TiTcpSocket_accept accept; + NyLPC_TiTcpSocket_precv precv; + NyLPC_TiTcpSocket_pseek pseek; + NyLPC_TiTcpSocket_send send; + NyLPC_TiTcpSocket_close close; + NyLPC_TiTcpSocket_allocSendBuf allocSendBuf; + NyLPC_TiTcpSocket_releaseSendBuf releaseSendBuf; + NyLPC_TiTcpSocket_psend psend; + NyLPC_TiTcpSocket_connect connect; + NyLPC_TiTcpSocket_finalize finalize; +}; + +struct NyLPC_TiTcpSocket +{ + const struct NyLPC_TiTcpSocket_Interface* _interface; +}; + + +#define NyLPC_iTcpSocket_getPeerAddr(i_inst) ((i_inst)->_interface->getpeeraddr((i_inst))) +#define NyLPC_iTcpSocket_getPeerPort(i_inst) ((i_inst)->_interface->getpeerport((i_inst))) +#define NyLPC_iTcpSocket_accept(i_inst,i_wait_in_msec) ((i_inst)->_interface->accept((i_inst),(i_wait_in_msec))) +#define NyLPC_iTcpSocket_precv(i_inst,o_buf_ptr,i_wait_msec) ((i_inst)->_interface->precv((i_inst),(o_buf_ptr),(i_wait_msec))) +#define NyLPC_iTcpSocket_pseek(i_inst,i_seek) ((i_inst)->_interface->pseek((i_inst),(i_seek))) +#define NyLPC_iTcpSocket_send(i_inst,i_buf_ptr,i_len,i_wait_in_msec) ((i_inst)->_interface->send((i_inst),(i_buf_ptr),(i_len),(i_wait_in_msec))) +#define NyLPC_iTcpSocket_close(i_inst,i_wait_in_msec) ((i_inst)->_interface->close((i_inst),(i_wait_in_msec))) +#define NyLPC_iTcpSocket_allocSendBuf(i_inst,i_hint,o_buf_size,i_wait_in_msec) ((i_inst)->_interface->allocSendBuf((i_inst),(i_hint),(o_buf_size),(i_wait_in_msec))) +#define NyLPC_iTcpSocket_releaseSendBuf(i_inst,i_buf_ptr) ((i_inst)->_interface->releaseSendBuf((i_inst),(i_buf_ptr))) +#define NyLPC_iTcpSocket_psend(i_inst,i_buf_ptr,i_len,i_wait_in_msec) ((i_inst)->_interface->psend((i_inst),(i_buf_ptr),(i_len),(i_wait_in_msec))) +#define NyLPC_iTcpSocket_connect(i_inst,i_addr,i_peer_port,i_wait_in_msec) ((i_inst)->_interface->connect((i_inst),(i_addr),(i_peer_port),(i_wait_in_msec))) +#define NyLPC_iTcpSocket_finalize(i_inst) ((i_inst)->_interface->finalize((i_inst))) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* NYLPC_ITCPSOCKET_H_ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/NyLPC_iUdpSocket.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,200 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + *********************************************************************************/ +#ifndef NYLPC_IIUDPSOCKET_H_ +#define NYLPC_IIUDPSOCKET_H_ + + +#include "NyLPC_stdlib.h" +#include "NyLPC_os.h" +#include "NyLPC_NetIf_ip_types.h" +#include "NyLPC_iTcpSocket.h" +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct NyLPC_TiUdpSocket NyLPC_TiUdpSocket_t; +/********************************************************************** + * Struct + **********************************************************************/ + +/** + * 受信情報を格納する構造体 + */ +struct NyLPC_TIPv4RxInfo +{ + NyLPC_TUInt16 size;//パケットサイズ + NyLPC_TUInt16 port;//受信ポート + NyLPC_TUInt16 peer_port;//PEERポート + struct NyLPC_TIPv4Addr ip;//受信IP + struct NyLPC_TIPv4Addr peer_ip;//PEERIP +}; + + +/********************************************************************** + * Event + **********************************************************************/ + +/** + * 受信時に非同期にコールされるハンドラ + * UIPサービスタスクが実行する。 + * @return + * TRUEならパケットを受信キューへ追加する。FALSEならパケットを受信キューへ追加しない。 + */ +typedef NyLPC_TBool (*NyLPC_TiUdpSocket_onRxHandler)(NyLPC_TiUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info); + +/** + * 非同期にコールされるハンドラ。 + * UIPサービスタスクが実行する。 + */ +typedef void (*NyLPC_TiUdpSocket_onPeriodicHandler)(NyLPC_TiUdpSocket_t* i_inst); + +/********************************************************************** + * Function + **********************************************************************/ + + + +/** + * マルチキャストアドレスに参加する。 + * @param i_addr + * 参加するマルチキャストグループを指定する。 + * 同じマルチキャスとグループに参加できるのは、システムの中で1つに限られます。 + * 0を指定した場合、マルチキャスとグループから離脱します。 + */ +typedef void (*NyLPC_TiUdpSocket_joinMulticast)(NyLPC_TiUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr); + +/** + * ブロードキャストに参加する。 + */ +typedef void (*NyLPC_TiUdpSocket_setBroadcast)(NyLPC_TiUdpSocket_t* i_inst); + + +/** + * この関数は、ソケットの受信バッファの読み取り位置と、読み出せるデータサイズを返却します。 + * 関数はポインターを返却するだけで、バッファの読み取り位置をシークしません。 + * シークするにはNyLPC_cTcpSocket_pseekを使います。 + */ +typedef NyLPC_TInt32 (*NyLPC_TiUdpSocket_precv)(NyLPC_TiUdpSocket_t* i_inst,const void** o_buf_ptr,const struct NyLPC_TIPv4RxInfo** o_info,NyLPC_TUInt32 i_wait_msec); +/** + * 受信バッファを次のバッファまでシークします。 + */ +typedef void (*NyLPC_TiUdpSocket_pseek)(NyLPC_TiUdpSocket_t* i_inst); + +/** + * 送信バッファを割り当てて返します。 + * 割り当てたメモリは、releaseSendBuf関数か、psend関数を成功させて開放する必要があります。 + * @param i_hint + * 取得したいメモリサイズをセットします。 + * 関数は要求サイズより小さいメモリを返すことがあります。 + */ +typedef void* (*NyLPC_TiUdpSocket_allocSendBuf)(NyLPC_TiUdpSocket_t* i_inst,NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_buf_size,NyLPC_TUInt32 i_wait_in_msec); + +typedef void (*NyLPC_TiUdpSocket_releaseSendBuf)(NyLPC_TiUdpSocket_t* i_inst,void* i_buf_ptr); + +/** + * 事前にAllocしたTxパケットを送信します。 + * このAPIはゼロコピー送信をサポートするためのものです。 + * @param i_buf_ptr + * allocSendBufで取得したメモリを指定します。 + * @return + * 関数が失敗した場合、i_buf_ptrは「開放されません。」 + */ +typedef NyLPC_TBool (*NyLPC_TiUdpSocket_psend)(NyLPC_TiUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_port,void* i_buf_ptr,int i_len); + +/** + * 最大送信サイズは1200バイトです。 + */ +typedef NyLPC_TInt32 (*NyLPC_TiUdpSocket_send)(NyLPC_TiUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_port,const void* i_buf_ptr,NyLPC_TInt32 i_len,NyLPC_TUInt32 i_wait_in_msec); + +/** + * 非同期パケットハンドラを設定する。 + */ +typedef void (*NyLPC_TiUdpSocket_setOnRxHandler)(NyLPC_TiUdpSocket_t* i_inst,NyLPC_TiUdpSocket_onRxHandler i_handler); + +/** + * 非同期タイマ呼び出しハンドラを設定する。 + */ +typedef void (*NyLPC_TiUdpSocket_setOnPeriodicHandler)(NyLPC_TiUdpSocket_t* i_inst,NyLPC_TiUdpSocket_onPeriodicHandler i_handler); + + +/** + * ソケットのローカルIPのアドレスを返す。 + * 値はuipが動作中のみ有効。 + */ +typedef struct NyLPC_TIPv4Addr* (*NyLPC_TiUdpSocket_getSockIP)(const NyLPC_TiUdpSocket_t* i_inst); + +typedef void (*NyLPC_TiUdpSocket_finalize)(NyLPC_TiUdpSocket_t* i_inst); + + +/********************************************************************** + * Interface + **********************************************************************/ + +/** + */ +struct NyLPC_TiUdpSocket_Interface +{ + NyLPC_TiUdpSocket_joinMulticast joinMulticast; + NyLPC_TiUdpSocket_setBroadcast setBroadcast; + NyLPC_TiUdpSocket_precv precv; + NyLPC_TiUdpSocket_pseek pseek; + NyLPC_TiUdpSocket_allocSendBuf allocSendBuf; + NyLPC_TiUdpSocket_releaseSendBuf releaseSendBuf; + NyLPC_TiUdpSocket_psend psend; + NyLPC_TiUdpSocket_send send; + NyLPC_TiUdpSocket_setOnRxHandler setOnRxHandler; + NyLPC_TiUdpSocket_setOnPeriodicHandler setOnPeriodicHandler; + NyLPC_TiUdpSocket_getSockIP getSockIP; + NyLPC_TiUdpSocket_finalize finalize; +}; + +struct NyLPC_TiUdpSocket +{ + const struct NyLPC_TiUdpSocket_Interface* _interface; + void* _tag; +}; + + +#define NyLPC_iUdpSocket_joinMulticast(i_inst,i_addr) ((i_inst)->_interface->joinMulticast((i_inst),(i_addr))) +#define NyLPC_iUdpSocket_setBroadcast(i_inst) ((i_inst)->_interface->setBroadcast((i_inst))) +#define NyLPC_iUdpSocket_precv(i_inst,o_buf_ptr,o_info,i_wait_msec) ((i_inst)->_interface->precv((i_inst),(o_buf_ptr),(o_info),(i_wait_msec))) +#define NyLPC_iUdpSocket_pseek(i_inst) ((i_inst)->_interface->pseek((i_inst))) +#define NyLPC_iUdpSocket_allocSendBuf(i_inst,i_hint,o_buf_size,i_wait_in_msec) ((i_inst)->_interface->allocSendBuf((i_inst),(i_hint),(o_buf_size),(i_wait_in_msec))) +#define NyLPC_iUdpSocket_releaseSendBuf(i_inst,i_buf_ptr) ((i_inst)->_interface->releaseSendBuf((i_inst),(i_buf_ptr))) +#define NyLPC_iUdpSocket_psend(i_inst,i_addr,i_port,i_buf_ptr,i_len) ((i_inst)->_interface->psend((i_inst),(i_addr),(i_port),(i_buf_ptr),(i_len))) +#define NyLPC_iUdpSocket_send(i_inst,i_addr,i_port,i_buf_ptr,i_len,i_wait_in_msec) ((i_inst)->_interface->send((i_inst),(i_addr),(i_port),(i_buf_ptr),(i_len),(i_wait_in_msec))) +#define NyLPC_iUdpSocket_setOnRxHandler(i_inst,i_handler) ((i_inst)->_interface->setOnRxHandler((i_inst),(i_handler))) +#define NyLPC_iUdpSocket_setOnPeriodicHandler(i_inst,i_handler) ((i_inst)->_interface->setOnPeriodicHandler((i_inst),(i_handler))) +#define NyLPC_iUdpSocket_getSockIP(i_inst) ((i_inst)->_interface->getSockIP((i_inst))) +#define NyLPC_iUdpSocket_finalize(i_inst) ((i_inst)->_interface->finalize((i_inst))) + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* NYLPC_IIUDPSOCKET_H_ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/apipa/NyLPC_cApipa.c Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,91 @@ +#include "NyLPC_cApipa.h" +#include "../NyLPC_cNetIf.h" +#include <stdio.h> +#include <string.h> + + +/** + * ARPテーブルに指定IPが現れるまで待ちます。 + */ +static NyLPC_TBool waitForArpResponse(const struct NyLPC_TIPv4Addr* i_ip,NyLPC_TUInt32 i_wait_in_ms) +{ + NyLPC_TcStopwatch_t sw; + NyLPC_cStopwatch_initialize(&sw); + NyLPC_cStopwatch_startExpire(&sw,i_wait_in_ms); + while(!NyLPC_cStopwatch_isExpired(&sw)){ + NyLPC_cThread_yield(); + if(NyLPC_cNetIf_hasArpInfo(i_ip)){ + return NyLPC_TBool_TRUE; + } + } + NyLPC_cStopwatch_finalize(&sw); + return NyLPC_TBool_FALSE; +} +static void makeIP(NyLPC_TcApipa_t* i_inst,struct NyLPC_TIPv4Addr* i_ip) +{ +// NyLPC_TIPv4Addr_set(i_ip,192,168,128,206);//for conflict test! + NyLPC_TIPv4Addr_set(i_ip,169,254,(i_inst->_seed>>8)&0xff,i_inst->_seed & 0xff); +} +static void updateSeed(NyLPC_TcApipa_t* i_inst) +{ + do{ + i_inst->_seed=(391*i_inst->_seed+392); + }while(((i_inst->_seed & 0xff)==0) || ((i_inst->_seed & 0xff00)==0)); +} + + + +void NyLPC_cApipa_initialize(NyLPC_TcApipa_t* i_inst) +{ + i_inst->_seed=0; +} + + +/** + * この関数はuipを操作します。 + * cNetは停止中である必要があります。 + */ +NyLPC_TBool NyLPC_cApipa_requestAddr(NyLPC_TcApipa_t* i_inst,NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat) +{ + int i; + NyLPC_TcIPv4Config_t cfg; + struct NyLPC_TIPv4Addr caip; + + //ゼロコンフィギュレーション用のIPを設定 + NyLPC_cIPv4Config_initialzeCopy(&cfg,i_cfg); + //seedを更新 + for(i=0;i<6;i++) + { + i_inst->_seed+=i_cfg->eth_mac.addr[i]; + } + NyLPC_cIPv4Config_setDefaultRoute(&cfg,&NyLPC_TIPv4Addr_ZERO); + for(i=i_repeat-1;i>=0;i--){ + NyLPC_cIPv4Config_setIp(&cfg,&NyLPC_TIPv4Addr_ZERO,&NyLPC_TIPv4Addr_ZERO); + updateSeed(i_inst); + makeIP(i_inst,&caip); + //startInterface + NyLPC_cNetIf_start(&cfg); + NyLPC_cNetIf_sendArpRequest(&caip); + //テーブル更新待ち + if(waitForArpResponse(&caip,512+(i_inst->_seed % 256))){ + NyLPC_cNetIf_stop(); + continue; + } + NyLPC_cNetIf_stop(); + //IPのコンフリクトテスト + NyLPC_cIPv4Config_setIp(&cfg,&caip,&NyLPC_TIPv4Addr_APIPA_MASK); + NyLPC_cNetIf_start(&cfg); + //!ARP送信 + NyLPC_cNetIf_sendArpRequest(&caip); + if(waitForArpResponse(&caip,512+(256-(i_inst->_seed % 256)))){ + //応答があったらエラー + NyLPC_cNetIf_stop(); + continue; + } + //OK + NyLPC_cNetIf_stop(); + NyLPC_cIPv4Config_setIp(i_cfg,&cfg.ip_addr,&cfg.netmask); + return NyLPC_TBool_TRUE; + } + return NyLPC_TBool_FALSE; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/apipa/NyLPC_cApipa.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,56 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011-2013 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + *********************************************************************************/ +#ifndef NYLPC_CAPIPA_H_ +#define NYLPC_CAPIPA_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "NyLPC_stdlib.h" +#include "../NyLPC_cIPv4Config.h" + +typedef struct NyLPC_cApipa NyLPC_TcApipa_t; + +struct NyLPC_cApipa +{ + NyLPC_TUInt32 _seed; +}; +void NyLPC_cApipa_initialize(NyLPC_TcApipa_t* i_inst); + +#define NyLPC_cApipa_finalize(i_inst) + + +/** + * i_cfgにAutoIPのアドレスを取得します。 + * この関数はuipを操作します。uipServiceは停止中である必要があります。 + */ +NyLPC_TBool NyLPC_cApipa_requestAddr(NyLPC_TcApipa_t* i_inst,NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* NYLPC_CAPIPA_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/dhcp/NyLPC_cDhcpClient.c Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,354 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011-2013 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + *********************************************************************************/ +#include "NyLPC_cDhcpClient.h" +#include "../NyLPC_cNetIf.h" +#include <stdio.h> +#include <string.h> + +struct NyLPC_TDhcpHeader +{ + NyLPC_TUInt8 op; + NyLPC_TUInt8 htype; + NyLPC_TUInt8 hlen; + NyLPC_TUInt8 hops; + NyLPC_TUInt32 xid; + NyLPC_TUInt16 secs; + NyLPC_TUInt16 flags; + NyLPC_TUInt32 ciaddr; + NyLPC_TUInt32 yiaddr; + NyLPC_TUInt32 siaddr; + NyLPC_TUInt32 giaddr; + struct{ + struct NyLPC_TEthAddr emac; + NyLPC_TChar padding[10]; + }chaddr; + NyLPC_TChar sname[64]; + NyLPC_TChar file[128]; +}PACK_STRUCT_END; + +#define NyLPC_TDhcpHeader_BOOTREQUEST 1 +#define NyLPC_TDhcpHeader_BOOTREPLY 2 + +#define DHCP_OPT_ID_ROUTER 3 +#define DHCP_OPT_ID_SERVER_ID 54 +#define DHCP_OPT_ID_NETMASK 1 +#define DHCP_OPT_ID_MESSAGETYPE 53 + + + +/** + * DHCPパケットから32bit値を読み出す。 + * @return + * ネットワークオーダー + */ +static NyLPC_TBool getUInt32Option(const NyLPC_TUInt8* i_buf,NyLPC_TUInt16 len,NyLPC_TUInt8 i_id,NyLPC_TUInt32* o_v) +{ + const NyLPC_TUInt8* p=i_buf+sizeof(struct NyLPC_TDhcpHeader)+4; + while(*p!=0x00 && p<(i_buf+len-5)){ + if(*p==i_id){ + if(*(p+1)==4){ + *o_v=*((NyLPC_TUInt32*)(p+2)); + return NyLPC_TBool_TRUE; + } + }else{ + p+=(*(p+1))+2; + } + } + return NyLPC_TBool_FALSE; +} +static NyLPC_TBool getUInt8Option(const NyLPC_TUInt8* i_buf,NyLPC_TUInt16 len,NyLPC_TUInt8 i_id,NyLPC_TUInt8* o_v) +{ + const NyLPC_TUInt8* p=i_buf+sizeof(struct NyLPC_TDhcpHeader)+4; + while(*p!=0x00 && p<(i_buf+len-5)){ + if(*p==i_id){ + if(*(p+1)==1){ + *o_v=*(p+2); + return NyLPC_TBool_TRUE; + } + }else{ + p+=(*(p+1))+2; + } + } + return NyLPC_TBool_FALSE; +} +static NyLPC_TBool NyLPC_TDhcpHeader_parseDHCPOFFER(const NyLPC_TUInt8* i_buf,NyLPC_TUInt16 i_len,NyLPC_TUInt32 i_xid,NyLPC_TcDhcpClient_t* i_inst) +{ + struct NyLPC_TDhcpHeader* p=(struct NyLPC_TDhcpHeader*)i_buf; + //XIDのチェック + if(p->xid!=NyLPC_HTONL(i_xid)){ + return NyLPC_TBool_FALSE; + } + //OFFERのclient IPアドレスをresultへ保存情報の保存 + i_inst->_result->ip_addr.v=p->yiaddr; + //SERVER IDを保存 + if(!getUInt32Option(i_buf,i_len,DHCP_OPT_ID_SERVER_ID,&i_inst->_offerserver.v)){ + return NyLPC_TBool_FALSE; + } + return NyLPC_TBool_TRUE; +} + +static NyLPC_TBool NyLPC_TDhcpHeader_parseDHCPACK(const NyLPC_TUInt8* i_buf,NyLPC_TUInt16 i_len,NyLPC_TUInt32 i_xid,NyLPC_TcIPv4Config_t* result) +{ + struct NyLPC_TDhcpHeader* p=(struct NyLPC_TDhcpHeader*)i_buf; + //XIDのチェック + if(p->xid!=NyLPC_HTONL(i_xid)){ + return NyLPC_TBool_FALSE; + } + if(!getUInt32Option(i_buf,i_len,DHCP_OPT_ID_ROUTER,&result->dr_addr.v)){ + result->dr_addr=NyLPC_TIPv4Addr_ZERO; + } + if(!getUInt32Option(i_buf,i_len,DHCP_OPT_ID_NETMASK,&result->netmask.v)){ + result->netmask=NyLPC_TIPv4Addr_ZERO; + } + result->ip_addr.v=p->yiaddr; + return NyLPC_TBool_TRUE; +} + +static void NyLPC_TDhcpHeader_setDHCPDISCOVER(char* i_buf,NyLPC_TUInt32 i_xid,const struct NyLPC_TEthAddr* emac,NyLPC_TUInt16* o_len) +{ + struct NyLPC_TDhcpHeader* p=(struct NyLPC_TDhcpHeader*)i_buf; + memset(i_buf,0,sizeof(struct NyLPC_TDhcpHeader)); + p->op=NyLPC_TDhcpHeader_BOOTREQUEST; + p->htype=1; + p->hlen=6; + p->xid=NyLPC_HTONL(i_xid); + p->chaddr.emac=*emac; + p->flags=NyLPC_HTONS(0x8000); + memcpy(i_buf+sizeof(struct NyLPC_TDhcpHeader), + "\x63\x82\x53\x63" //4 + "\x35\x01\x01" //3 MESSAGE TYPE + "\x37\x03\x01\x03\x06" //5 REQUEST LIST(1,3,6) + "\x3d\x07\x01\x00\x00\x00\x00\x00\x00" //9 CLIENT INDIFIRE + "\xff",4+3+5+9+1); + //emacの上書き + memcpy((i_buf+sizeof(struct NyLPC_TDhcpHeader)+4+3+5+3),emac->addr,6); + //送信するパケットの長さ + *o_len=sizeof(struct NyLPC_TDhcpHeader)+4+3+5+9+1; + return; +} +static void NyLPC_TDhcpHeader_setDHCPREQUEST(char* i_buf,NyLPC_TUInt32 i_xid,const struct NyLPC_TIPv4Addr* i_sid,const struct NyLPC_TIPv4Addr* i_reqid,const struct NyLPC_TEthAddr* emac,NyLPC_TUInt16* o_len) +{ + struct NyLPC_TDhcpHeader* p=(struct NyLPC_TDhcpHeader*)i_buf; + memset(i_buf,0,sizeof(struct NyLPC_TDhcpHeader)); + p->op=NyLPC_TDhcpHeader_BOOTREQUEST; + p->htype=1; + p->hlen=6; + p->xid=NyLPC_HTONL(i_xid); + p->chaddr.emac=*emac; + p->flags=NyLPC_HTONS(0x8000); + memcpy(i_buf+sizeof(struct NyLPC_TDhcpHeader), + "\x63\x82\x53\x63" //4 + "\x35\x01\x03" //3 MESSAGE TYPE + "\x37\x03\x01\x03\x06" //5 REQUEST LIST(1,3,6) + "\x3d\x07\x01\x00\x00\x00\x00\x00\x00" //9 CLIENT INDIFIRE + "\x36\x04\x00\x00\x00\x00" // 6 SERVER ID + "\x32\x04\x00\x00\x00\x00" // 6 Reqested IP + "\xff",4+3+5+9+6+6+1); + //emacの上書き + memcpy((i_buf+sizeof(struct NyLPC_TDhcpHeader)+4+3+5+3),emac->addr,6); + //sidの上書き + memcpy((i_buf+sizeof(struct NyLPC_TDhcpHeader)+4+3+5+9+2),i_sid,4); + //reqidの上書き + memcpy((i_buf+sizeof(struct NyLPC_TDhcpHeader)+4+3+5+9+6+2),i_reqid,4); + //送信するパケットの長さ + *o_len=sizeof(struct NyLPC_TDhcpHeader)+4+3+5+9+6+6+1; + return; +} + + + +#define TcDhcpSock_ST_WAIT_OFFER 1 +#define TcDhcpSock_ST_WAIT_OFFER_OK 2 +#define TcDhcpSock_ST_WAIT_ACK 3 +#define TcDhcpSock_ST_WAIT_ACK_OK 4 +#define TcDhcpSock_ST_DONE_NG 3 +#define TcDhcpSock_ST_DONE_OK 4 + + + + +#define DHCP_OPT_ID_MESSAGETYPE_ACK 5 +#define DHCP_OPT_ID_MESSAGETYPE_OFFER 2 + +static NyLPC_TBool onPacket(NyLPC_TiUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info); + +/** + * DHCPソケットを作成します。 + */ +NyLPC_TBool NyLPC_cDhcpClient_initialize(NyLPC_TcDhcpClient_t* i_inst) +{ + i_inst->_socket=NyLPC_cNetIf_createUdpSocketEx(68,NyLPC_TSocketType_UDP_NOBUF); + if(i_inst->_socket==NULL){ + return NyLPC_TBool_FALSE; + } + i_inst->_socket->_tag=i_inst; + NyLPC_iUdpSocket_setBroadcast(i_inst->_socket); + NyLPC_iUdpSocket_setOnRxHandler(i_inst->_socket,onPacket); + return NyLPC_TBool_TRUE; +} +void NyLPC_cDhcpClient_finalize(NyLPC_TcDhcpClient_t* i_inst) +{ + NyLPC_iUdpSocket_finalize(i_inst->_socket); +} +#define TIMEOUT_SOCKAPI_MS 1000 +#define TIMEOUT_RECVMSG_MS 3000 + +/** + * ネットワークを更新します。 + * emac/default_mssを設定したネットワークが必要です。 + */ +static NyLPC_TBool NyLPC_cDhcpClient_dhcpRequest(NyLPC_TcDhcpClient_t* i_inst,NyLPC_TcIPv4Config_t* i_result) +{ + char* buf; + NyLPC_TcStopwatch_t sw; + NyLPC_TUInt16 s; + NyLPC_TInt16 hint=sizeof(struct NyLPC_TDhcpHeader)+128; + i_inst->txid+=(*(NyLPC_TUInt16*)(&(i_result->eth_mac.addr[2])))+(*(NyLPC_TUInt16*)(&(i_result->eth_mac.addr[4]))); + i_inst->_result=i_result; + buf=NyLPC_iUdpSocket_allocSendBuf(i_inst->_socket,hint,&s,TIMEOUT_SOCKAPI_MS); + if(buf==NULL || s<hint){ + return NyLPC_TBool_FALSE; + } + NyLPC_TDhcpHeader_setDHCPDISCOVER(buf,i_inst->txid,&i_inst->_result->eth_mac,&s); + i_inst->_status=TcDhcpSock_ST_WAIT_OFFER; + if(!NyLPC_iUdpSocket_psend(i_inst->_socket,&NyLPC_TIPv4Addr_BROADCAST,67,buf,s)){ + NyLPC_iUdpSocket_releaseSendBuf(i_inst->_socket,buf); + return NyLPC_TBool_FALSE; + } + NyLPC_cStopwatch_initialize(&sw); + NyLPC_cStopwatch_startExpire(&sw,TIMEOUT_RECVMSG_MS); + while(i_inst->_status==TcDhcpSock_ST_WAIT_OFFER){ + if(NyLPC_cStopwatch_isExpired(&sw)){ + return NyLPC_TBool_FALSE; + } + } + //レスポンスのチェック + if(i_inst->_status!=TcDhcpSock_ST_WAIT_OFFER_OK) + { + return NyLPC_TBool_FALSE; + } + buf=NyLPC_iUdpSocket_allocSendBuf(i_inst->_socket,hint,&s,TIMEOUT_SOCKAPI_MS); + if(buf==NULL || s<hint){ + return NyLPC_TBool_FALSE; + } + NyLPC_TDhcpHeader_setDHCPREQUEST(buf,i_inst->txid,&(i_inst->_offerserver),&(i_inst->_result->ip_addr),&i_inst->_result->eth_mac,&s); + i_inst->_status=TcDhcpSock_ST_WAIT_ACK; + if(!NyLPC_iUdpSocket_psend(i_inst->_socket,&NyLPC_TIPv4Addr_BROADCAST,67,buf,s)){ + NyLPC_iUdpSocket_releaseSendBuf(i_inst->_socket,buf); + return NyLPC_TBool_FALSE; + } + NyLPC_cStopwatch_startExpire(&sw,TIMEOUT_RECVMSG_MS); + while(i_inst->_status==TcDhcpSock_ST_WAIT_ACK){ + if(NyLPC_cStopwatch_isExpired(&sw)){ + return NyLPC_TBool_FALSE; + } + } + //レスポンスのチェック + if(i_inst->_status!=TcDhcpSock_ST_WAIT_ACK_OK) + { + return NyLPC_TBool_FALSE; + } + return NyLPC_TBool_TRUE; +} + +/** + * NyLPC_TcIPv4Config_tをDHCPで更新します。 + * この関数をコールする時は、サービスは停止中でなければなりません。 + * @param i_cfg + * 更新するi_cfg構造体。 + * emac,default_mssは設定済である必要があります。他のフィールド値は不定で構いません。 + * 更新されるフィールドは、ip,netmast,default_rootの3つです。 + * @return + * 更新に成功した場合TRUE + */ +NyLPC_TBool NyLPC_cDhcpClient_requestAddr(NyLPC_TcDhcpClient_t* i_inst,NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat) +{ + NyLPC_TInt16 i; + NyLPC_TBool ret=NyLPC_TBool_FALSE; + NyLPC_TcIPv4Config_t c2; + //工場出荷時設定でリセットしてIPを0に + NyLPC_cIPv4Config_initialzeCopy(&c2,i_cfg); + NyLPC_cIPv4Config_setIp(&c2,&NyLPC_TIPv4Addr_ZERO,&NyLPC_TIPv4Addr_ZERO); + NyLPC_cIPv4Config_setDefaultRoute(&c2,&NyLPC_TIPv4Addr_ZERO); + //netを開始 + NyLPC_cNetIf_start(&c2); + for(i=i_repeat-1;i>=0;i--){ + ret=NyLPC_cDhcpClient_dhcpRequest(i_inst,i_cfg); + if(ret){ + break; + } + } + NyLPC_cNetIf_stop(); + NyLPC_cIPv4Config_finalize(&c2); + return ret; +} + + + +static NyLPC_TBool onPacket(NyLPC_TiUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info) +{ + NyLPC_TUInt8 mt;//message type + NyLPC_TcDhcpClient_t* inst=(NyLPC_TcDhcpClient_t*)i_inst->_tag; + struct NyLPC_TDhcpHeader* dnsh=(struct NyLPC_TDhcpHeader*)i_buf; + if(i_info->size<sizeof(struct NyLPC_TDhcpHeader)+1){ + return NyLPC_TBool_FALSE;//DROP + } + switch(inst->_status) + { + case TcDhcpSock_ST_WAIT_ACK: + if(dnsh->op!=NyLPC_TDhcpHeader_BOOTREPLY){ + return NyLPC_TBool_FALSE; + } + if(!getUInt8Option(i_buf,i_info->size,DHCP_OPT_ID_MESSAGETYPE,&mt)){ + return NyLPC_TBool_FALSE; + } + if(mt!=DHCP_OPT_ID_MESSAGETYPE_ACK){ + return NyLPC_TBool_FALSE; + } + if(!NyLPC_TDhcpHeader_parseDHCPACK(i_buf,i_info->size,inst->txid,inst->_result)){ + return NyLPC_TBool_FALSE; + } + inst->_status=TcDhcpSock_ST_WAIT_ACK_OK; + break; + case TcDhcpSock_ST_WAIT_OFFER: + if(dnsh->op!=NyLPC_TDhcpHeader_BOOTREPLY){ + return NyLPC_TBool_FALSE; + } + if(!getUInt8Option(i_buf,i_info->size,DHCP_OPT_ID_MESSAGETYPE,&mt)){ + return NyLPC_TBool_FALSE; + } + if(mt!=DHCP_OPT_ID_MESSAGETYPE_OFFER){ + return NyLPC_TBool_FALSE; + } + if(!NyLPC_TDhcpHeader_parseDHCPOFFER(i_buf,i_info->size,inst->txid,inst)){ + return NyLPC_TBool_FALSE; + } + inst->_status=TcDhcpSock_ST_WAIT_OFFER_OK; + break; + } + return NyLPC_TBool_FALSE; + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/dhcp/NyLPC_cDhcpClient.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,74 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011-2013 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + *********************************************************************************/ +#ifndef NYLPC_CDHCPCLIENT_H_ +#define NYLPC_CDHCPCLIENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +#include "NyLPC_stdlib.h" +#include "../NyLPC_iUdpSocket.h" +#include "../NyLPC_cIPv4Config.h" + +typedef struct NyLPC_TcDhcpClient NyLPC_TcDhcpClient_t; + +struct NyLPC_TcDhcpClient{ + NyLPC_TiUdpSocket_t* _socket; + NyLPC_TcIPv4Config_t* _result; + NyLPC_TUInt32 txid; + volatile NyLPC_TUInt16 _status; + //offer情報 + struct NyLPC_TIPv4Addr _offerserver; +}; + + +/** + * DHCPソケットを作成します。 + */ +NyLPC_TBool NyLPC_cDhcpClient_initialize(NyLPC_TcDhcpClient_t* i_inst); + +void NyLPC_cDhcpClient_finalize(NyLPC_TcDhcpClient_t* i_inst); + +/** + * NyLPC_TcIPv4Config_tをDHCPで更新します。 + * この関数をコールする時は、サービスは停止中でなければなりません。 + * @param i_cfg + * 更新するi_cfg構造体。 + * emac,default_mssは設定済である必要があります。他のフィールド値は不定で構いません。 + * 更新されるフィールドは、ip,netmast,default_rootの3つです。 + * @return + * 更新に成功した場合TRUE + */ +NyLPC_TBool NyLPC_cDhcpClient_requestAddr(NyLPC_TcDhcpClient_t* i_inst,NyLPC_TcIPv4Config_t* i_cfg,NyLPC_TInt16 i_repeat); + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cIPv4.c Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,541 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + * + * Parts of this file were leveraged from uIP: + * + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "NyLPC_cIPv4.h" +#include "NyLPC_stdlib.h" +#include "NyLPC_os.h" +#include "NyLPC_cIPv4Payload_protected.h" +#include "NyLPC_cMiMicIpTcpSocket_protected.h" +#include "NyLPC_cMiMicIpTcpListener_protected.h" +#include "NyLPC_cMiMicIpUdpSocket_protected.h" +#include "NyLPC_cIPv4IComp_protected.h" +#include "NyLPC_cMiMicIpNetIf_protected.h" +#include "NyLPC_cMiMicIpBaseSocket.h" + + + +/**************************************************** + * Socketテーブルに関する宣言 + ***************************************************/ + +#define cSocketTbl_initialize(i_inst,buf) NyLPC_cPtrTbl_initialize(i_inst,buf,NyLPC_cIPv4_MAX_SOCKET) +#define cSocketTbl_finalize(i_inst) + +/** + * 条件に一致する、アクティブなTCPソケットオブジェクトを取得します。 + * この関数は、ローカルIPが一致していると仮定して検索をします。 + * @param i_rip + * リモートIPアドレスを指定します。 + */ +static NyLPC_TcMiMicIpTcpSocket_t* cSocketTbl_getMatchTcpSocket( + NyLPC_TcPtrTbl_t* i_inst, + NyLPC_TUInt16 i_lport, + struct NyLPC_TIPv4Addr i_rip, + NyLPC_TUInt16 i_rport) +{ + NyLPC_TcMiMicIpBaseSocket_t** p=(NyLPC_TcMiMicIpBaseSocket_t**)(i_inst->buf); + NyLPC_TcMiMicIpTcpSocket_t* tp; + int i; + //一致するポートを検索 + for(i=i_inst->size-1;i>=0;i--){ + if(p[i]==NULL || p[i]->_typeid!=NyLPC_TcMiMicIpBaseSocket_TYPEID_TCP_SOCK){ + continue; + } + tp=(NyLPC_TcMiMicIpTcpSocket_t*)p[i]; + if(tp->tcpstateflags==UIP_CLOSED){ + continue; + } + //パラメータの一致チェック + if(i_lport!=tp->uip_connr.lport || i_rport!= tp->uip_connr.rport || i_rip.v!=tp->uip_connr.ripaddr.v) + { + continue; + } + return tp; + } + return NULL; +} +static NyLPC_TcMiMicIpUdpSocket_t* cSocketTbl_getMatchUdpSocket( + NyLPC_TcPtrTbl_t* i_inst, + NyLPC_TUInt16 i_lport) +{ + NyLPC_TcMiMicIpBaseSocket_t** p=(NyLPC_TcMiMicIpBaseSocket_t**)(i_inst->buf); + NyLPC_TcMiMicIpUdpSocket_t* tp; + int i; + //一致するポートを検索 + for(i=i_inst->size-1;i>=0;i--){ + if(p[i]==NULL || p[i]->_typeid!=NyLPC_TcMiMicIpBaseSocket_TYPEID_UDP_SOCK){ + continue; + } + tp=(NyLPC_TcMiMicIpUdpSocket_t*)p[i]; + //パラメータの一致チェック + if(i_lport==tp->uip_udp_conn.lport){ + //unicast + return tp; + } + } + return NULL; +} +static NyLPC_TcMiMicIpUdpSocket_t* cSocketTbl_getMatchMulticastUdpSocket( + NyLPC_TcPtrTbl_t* i_inst, + const struct NyLPC_TIPv4Addr* i_mcast_ip, + NyLPC_TUInt16 i_lport) +{ + NyLPC_TcMiMicIpBaseSocket_t** p=(NyLPC_TcMiMicIpBaseSocket_t**)(i_inst->buf); + NyLPC_TcMiMicIpUdpSocket_t* tp; + int i; + //一致するポートを検索 + for(i=i_inst->size-1;i>=0;i--){ + if(p[i]==NULL || p[i]->_typeid!=NyLPC_TcMiMicIpBaseSocket_TYPEID_UDP_SOCK){ + continue; + } + tp=(NyLPC_TcMiMicIpUdpSocket_t*)p[i]; + //パラメータの一致チェック + if(i_lport!=tp->uip_udp_conn.lport || (!NyLPC_TIPv4Addr_isEqual(i_mcast_ip,&(tp->uip_udp_conn.mcastaddr)))) + { + continue; + } + return tp; + } + return NULL; +} + +/** + * i_port番号に一致するリスナを返します。 + */ +static NyLPC_TcMiMicIpTcpListener_t* cSocketTbl_getListenerByPeerPort(NyLPC_TcPtrTbl_t* i_inst,NyLPC_TUInt16 i_port) +{ + NyLPC_TcMiMicIpBaseSocket_t** p=(NyLPC_TcMiMicIpBaseSocket_t**)(i_inst->buf); + NyLPC_TcMiMicIpTcpListener_t* lp; + int i; + //一致するポートを検索して、acceptをコールする。 + for(i=i_inst->size-1;i>=0;i--){ + if(p[i]==NULL || p[i]->_typeid!=NyLPC_TcMiMicIpBaseSocket_TYPEID_TCP_LISTENER){ + continue; + } + lp=(NyLPC_TcMiMicIpTcpListener_t*)p[i]; + if(lp->_port!=i_port){ + continue; + } + return lp; + } + return NULL; +} +/** + * 指定番号のTCPポートが未使用かを返す。 + * @return + * i_lport番のポートが未使用であればTRUE + */ +static NyLPC_TBool cSocketTbl_isClosedTcpPort( + NyLPC_TcPtrTbl_t* i_inst, + NyLPC_TUInt16 i_lport) +{ + NyLPC_TcMiMicIpBaseSocket_t** p=(NyLPC_TcMiMicIpBaseSocket_t**)(i_inst->buf); + NyLPC_TcMiMicIpTcpSocket_t* tp; + int i; + //一致するポートを検索 + for(i=i_inst->size-1;i>=0;i--){ + if(p[i]==NULL){ + continue; + } + if(p[i]->_typeid!=NyLPC_TcMiMicIpBaseSocket_TYPEID_TCP_SOCK){ + tp=((NyLPC_TcMiMicIpTcpSocket_t*)p[i]); + //TCPソケット && !クローズ && ポート一致なら使用中 + if((tp->tcpstateflags!=UIP_CLOSED) && tp->uip_connr.lport==i_lport){ + return NyLPC_TBool_FALSE; + } + } + if(p[i]->_typeid!=NyLPC_TcMiMicIpBaseSocket_TYPEID_TCP_LISTENER){ + //Listenerソケット && ポート一致なら使用中 + if(((NyLPC_TcMiMicIpTcpListener_t*)p[i])->_port==i_lport){ + return NyLPC_TBool_FALSE; + } + } + } + //未使用 + return NyLPC_TBool_TRUE; +} +/** + * テーブルにある有効なソケットのperiodicをすべて呼び出します。 + */ +static void cSocketTbl_callPeriodic( + NyLPC_TcPtrTbl_t* i_inst) +{ + NyLPC_TcMiMicIpBaseSocket_t** p=(NyLPC_TcMiMicIpBaseSocket_t**)(i_inst->buf); + int i; + for(i=i_inst->size-1;i>=0;i--){ + if(p[i]==NULL){ + continue; + } + switch(p[i]->_typeid){ + case NyLPC_TcMiMicIpBaseSocket_TYPEID_TCP_SOCK: + //downcast! + NyLPC_cMiMicIpTcpSocket_periodic((NyLPC_TcMiMicIpTcpSocket_t*)(p[i])); + break; + case NyLPC_TcMiMicIpBaseSocket_TYPEID_UDP_SOCK: + NyLPC_cMiMicIpUdpSocket_periodic((NyLPC_TcMiMicIpUdpSocket_t*)(p[i])); + break; + default: + continue; + } + } +} + +/** + * テーブルにある有効なソケットのstartを全て呼び出します。 + */ +static void cSocketTbl_callSocketStart( + NyLPC_TcPtrTbl_t* i_inst, + const NyLPC_TcIPv4Config_t* i_cfg) +{ + NyLPC_TcMiMicIpBaseSocket_t** p=(NyLPC_TcMiMicIpBaseSocket_t**)(i_inst->buf); + int i; + for(i=i_inst->size-1;i>=0;i--){ + if(p[i]==NULL){ + continue; + } + switch(p[i]->_typeid){ + case NyLPC_TcMiMicIpBaseSocket_TYPEID_UDP_SOCK: + NyLPC_cMiMicIpUdpSocket_startService((NyLPC_TcMiMicIpUdpSocket_t*)(p[i]),i_cfg); + break; + case NyLPC_TcMiMicIpBaseSocket_TYPEID_TCP_SOCK: + NyLPC_cMiMicIpTcpSocket_startService((NyLPC_TcMiMicIpTcpSocket_t*)(p[i]),i_cfg); + break; + default: + continue; + } + } +} +/** + * テーブルにある有効なソケットのstartを全て呼び出します。 + */ +static void cSocketTbl_callSocketStop( + NyLPC_TcPtrTbl_t* i_inst) +{ + NyLPC_TcMiMicIpBaseSocket_t** p=(NyLPC_TcMiMicIpBaseSocket_t**)(i_inst->buf); + int i; + for(i=i_inst->size-1;i>=0;i--){ + if(p[i]==NULL){ + continue; + } + switch(p[i]->_typeid){ + case NyLPC_TcMiMicIpBaseSocket_TYPEID_UDP_SOCK: + NyLPC_cMiMicIpUdpSocket_stopService((NyLPC_TcMiMicIpUdpSocket_t*)(p[i])); + break; + case NyLPC_TcMiMicIpBaseSocket_TYPEID_TCP_SOCK: + NyLPC_cMiMicIpTcpSocket_stopService((NyLPC_TcMiMicIpTcpSocket_t*)(p[i])); + break; + default: + continue; + } + } +} + +/**************************************************** + * NyLPC_cIPv4 + ***************************************************/ + +/** + * Static関数 + */ + +static void* tcp_rx( + NyLPC_TcIPv4_t* i_inst, + const NyLPC_TcIPv4Payload_t* i_ipp); + +static NyLPC_TBool udp_rx( + NyLPC_TcIPv4_t* i_inst, + NyLPC_TcIPv4Payload_t* i_ipp); + +/** + * See Header file. + */ +void NyLPC_cIPv4_initialize( + NyLPC_TcIPv4_t* i_inst) +{ + //IP制御パケットの為に40バイト以上のシステムTXメモリが必要。 + NyLPC_ArgAssert(NyLPC_cMiMicIpNetIf_SYS_TX_BUF_SIZE>40); + //内部テーブルの初期化 + cSocketTbl_initialize(&(i_inst->_socket_tbl),(void**)(i_inst->_socket_array_buf)); + //instanceの初期化 + NyLPC_cMutex_initialize(&(i_inst->_sock_mutex)); + NyLPC_cMutex_initialize(&(i_inst->_listener_mutex)); + i_inst->tcp_port_counter=0; + i_inst->_ref_config=NULL; + return; +} + +/** + * See header file. + */ +void NyLPC_cIPv4_finalize( + NyLPC_TcIPv4_t* i_inst) +{ + cSocketTbl_finalize(&(i_inst->_socket_tbl)); + NyLPC_cMutex_finalize(&(i_inst->_sock_mutex)); + NyLPC_cMutex_finalize(&(i_inst->_listener_mutex)); + return; +} + +/** + * See header file. + */ +void NyLPC_cIPv4_start( + NyLPC_TcIPv4_t* i_inst, + const NyLPC_TcIPv4Config_t* i_ref_configlation) +{ + NyLPC_ArgAssert(i_ref_configlation!=NULL); + //リストの初期化、ここでするべき?しないべき? + i_inst->_ref_config=i_ref_configlation; + //configulationのアップデートを登録されてるソケットに通知 + cSocketTbl_callSocketStart(&(i_inst->_socket_tbl),i_ref_configlation); + return; +} + +/** + * See header file. + */ +void NyLPC_cIPv4_stop( + NyLPC_TcIPv4_t* i_inst) +{ + cSocketTbl_callSocketStop(&(i_inst->_socket_tbl)); + i_inst->_ref_config=NULL; + return; +} + +/** + * See header file. + */ +NyLPC_TBool NyLPC_cIPv4_addSocket( + NyLPC_TcIPv4_t* i_inst, + NyLPC_TcMiMicIpBaseSocket_t* i_sock) +{ + //当面、stop中しか成功しない。 + NyLPC_Assert(!NyLPC_cMiMicIpNetIf_isRun()); + return NyLPC_cPtrTbl_add(&(i_inst->_socket_tbl),i_sock)>=0; +} + +/** + * See header file. + */ +NyLPC_TBool NyLPC_cIPv4_removeSocket( + NyLPC_TcIPv4_t* i_inst, + NyLPC_TcMiMicIpBaseSocket_t* i_sock) +{ + NyLPC_TInt16 i; + NyLPC_Assert(!NyLPC_cMiMicIpNetIf_isRun()); + i=NyLPC_cPtrTbl_getIndex(&(i_inst->_socket_tbl),i_sock); + if(i>=0){ + NyLPC_cPtrTbl_remove(&(i_inst->_socket_tbl),i); + return NyLPC_TBool_TRUE; + } + return NyLPC_TBool_FALSE; +} + + +#define IS_START(i_inst) ((i_inst)->_ref_config!=NULL) + +/** + * 稼動時に、1s置きに呼び出す関数です。 + */ +void NyLPC_cIPv4_periodec(NyLPC_TcIPv4_t* i_inst) +{ + cSocketTbl_callPeriodic(&(i_inst->_socket_tbl)); +} + + +/** + * IPv4ペイロードを処理する関数。 + * この関数は、パケット受信タスクから実行します。 + * @param i_rx + * 先頭ポインタ。 + * @return + * TRUEなら、i_rxに応答パケットをセットして返します。 + */ +void* NyLPC_cIPv4_rx(NyLPC_TcIPv4_t* i_inst,const void* i_rx,NyLPC_TUInt16 i_rx_size) +{ + NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; + NyLPC_TcIPv4Payload_t ipv4; + //NOT開始状態なら受け付けないよ。 + if(!IS_START(i_inst)){ + NyLPC_OnErrorGoto(ERROR_DROP); + } + + NyLPC_cIPv4Payload_initialize(&ipv4); + //IPフラグメントを読出し用にセットする。 + if(!NyLPC_cIPv4Payload_attachRxBuf(&ipv4,i_rx,i_rx_size)) + { + NyLPC_OnErrorGoto(ERROR_DROP); + } + switch(ipv4.header->proto) + { + case UIP_PROTO_TCP: + //TCP受信処理 + return tcp_rx(i_inst,&ipv4); + case UIP_PROTO_UDP: + //UDP処理 + udp_rx(i_inst,&ipv4);//r + return NyLPC_TBool_FALSE; + case UIP_PROTO_ICMP: + return NyLPC_cIPv4IComp_rx(&(inst->_icomp),&ipv4); + } + return NULL; +ERROR_DROP: + return NULL; +} + +NyLPC_TUInt16 NyLPC_cIPv4_getNewPortNumber(NyLPC_TcIPv4_t* i_inst) +{ + NyLPC_TUInt16 i,n; + for(i=0;i<0x0fff;i--){ + i_inst->tcp_port_counter=(i_inst->tcp_port_counter+1)%0x0fff; + n=i_inst->tcp_port_counter+49152; + if(cSocketTbl_isClosedTcpPort(&i_inst->_socket_tbl,n)) + { + return n; + } + } + return 0; +} + + +/********************************************************************** + * + * packet handler + * + **********************************************************************/ + + +static void* tcp_rx( + NyLPC_TcIPv4_t* i_inst, + const NyLPC_TcIPv4Payload_t* i_ipp) +{ + NyLPC_TcMiMicIpTcpSocket_t* sock; + NyLPC_TcMiMicIpTcpListener_t* listener; + + //自分自身のIPに対する呼び出し? + if(!NyLPC_TIPv4Addr_isEqual(&(i_ipp->header->destipaddr),&(i_inst->_ref_config->ip_addr))) + { + //自分以外のパケットはドロップ + goto DROP; + } + //チェックサムの計算 + if((NyLPC_TIPv4Header_makeTcpChecksum(i_ipp->header) != 0xffff)) + { + //受信エラーのあるパケットはドロップ + goto DROP; + } + //アクティブなTCPソケットを探す。 + sock=cSocketTbl_getMatchTcpSocket(&(i_inst->_socket_tbl),i_ipp->payload.tcp->destport,i_ipp->header->srcipaddr,i_ipp->payload.tcp->srcport); + if(sock!=NULL) + { + //既存の接続を処理 + return NyLPC_cMiMicIpTcpSocket_parseRx(sock,i_ipp); + } + + //未知の接続 + if(!NyLPC_cPtrTbl_hasEmpty(&(i_inst->_socket_tbl))){ + //ソケットテーブルが不十分。RST送信 + return NyLPC_cMiMicIpTcpSocket_allocTcpReverseRstAck(i_ipp); + } + //このポートに対応したListenerを得る。 + listener=cSocketTbl_getListenerByPeerPort(&(i_inst->_socket_tbl),i_ipp->payload.tcp->destport); + if(listener==NULL){ + //Listen対象ではない。RST送信 + return NyLPC_cMiMicIpTcpSocket_allocTcpReverseRstAck(i_ipp); + } + //リスナにソケットのバインドを依頼する。 + NyLPC_cMiMicIpTcpListener_synPacket(listener,i_ipp); + return NULL;//LISTEN成功。送信データなし +DROP: + return NULL; +} + + + +static NyLPC_TBool udp_rx( + NyLPC_TcIPv4_t* i_inst, + NyLPC_TcIPv4Payload_t* i_ipp) +{ + NyLPC_TcMiMicIpUdpSocket_t* sock=NULL; + if(!NyLPC_TIPv4Addr_isEqual(&(i_ipp->header->destipaddr),&(i_inst->_ref_config->ip_addr))) + { + sock=cSocketTbl_getMatchUdpSocket(&(i_inst->_socket_tbl),i_ipp->payload.udp->destport); + }else{ + if(NyLPC_TIPv4Addr_isEqualWithMask(&(i_ipp->header->destipaddr),&NyLPC_TIPv4Addr_MULTICAST,&NyLPC_TIPv4Addr_MULTICAST_MASK)){ + //MultiCast? + //マルチキャストに参加している&&portの一致するソケットを検索 + sock=cSocketTbl_getMatchMulticastUdpSocket(&(i_inst->_socket_tbl),&(i_ipp->header->destipaddr),i_ipp->payload.udp->destport); + }else if(!NyLPC_TIPv4Addr_isEqual(&(i_ipp->header->destipaddr),&NyLPC_TIPv4Addr_BROADCAST)){ + //Broadcast? + sock=cSocketTbl_getMatchUdpSocket(&(i_inst->_socket_tbl),i_ipp->payload.udp->destport); + } + } + if(sock==NULL) + { + goto DROP; + } + //パケットのエラーチェック + if((NyLPC_TIPv4Header_makeTcpChecksum(i_ipp->header) != 0xffff)) + { + //受信エラーのあるパケットはドロップ + goto DROP; + } + //既存の接続を処理 + return NyLPC_cMiMicIpUdpSocket_parseRx(sock,i_ipp); +DROP: + return NyLPC_TBool_FALSE; +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cIPv4.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,236 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + * + * Parts of this file were leveraged from uIP: + * + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/** + * @file + * このファイルは、NyLPC_cIPv4IPv4クラスを定義します。 + */ +#ifndef NYLPC_CIPV4TCP_H_ +#define NYLPC_CIPV4TCP_H_ + + + +#include "NyLPC_os.h" +#include "../NyLPC_NetIf_ip_types.h" +#include "../NyLPC_cIPv4Config.h" + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +/********************************************************************** + * + * Closs reference + * + **********************************************************************/ + +typedef struct NyLPC_TcMiMicIpBaseSocket NyLPC_TcMiMicIpBaseSocket_t; + + +/********************************************************************** + * + * class NyLPC_TcIPv4 + * + **********************************************************************/ +typedef struct NyLPC_TcIPv4 NyLPC_TcIPv4_t; + + + + +/** + * Socketの最大生成数 + * この値は、NyLPC_cTcpSocketクラス,NyLPC_cTcpListener,NyLPC_cUdpの最大生成数になります。 + */ +#define NyLPC_cIPv4_MAX_SOCKET 10 + + + +/** + * NyLPC_TcIPv4クラスの構造体です。 + */ +struct NyLPC_TcIPv4 +{ + /** 参照しているIPスタックの環境値です。この値は、start関数が設定します。*/ + const NyLPC_TcIPv4Config_t* _ref_config; + /** ソケットリソースの保護用。コールバック関数から呼び出されるソケット内部のリソース保護に使用する共通MUTEX*/ + NyLPC_TcMutex_t _sock_mutex; + /** リスナリソースの保護用。コールバック関数から呼び出されるソケット内部のリソース保護に使用する共通MUTEX*/ + NyLPC_TcMutex_t _listener_mutex; + /** NyLPC_cTcpSocketを管理するポインタリストです。*/ + NyLPC_TcPtrTbl_t _socket_tbl; + /** _socket_tblが使用するメモリ領域です。*/ + NyLPC_TcMiMicIpBaseSocket_t* _socket_array_buf[NyLPC_cIPv4_MAX_SOCKET]; + /** 0-0xfffまでを巡回するカウンタ*/ + NyLPC_TUInt16 tcp_port_counter; +}; + +/** + * コンストラクタです。インスタンスを初期化します。 + * @param i_inst + * 初期化するインスタンス + */ +void NyLPC_cIPv4_initialize( + NyLPC_TcIPv4_t* i_inst); + +/** + * デストラクタです。インスタンスを破棄して、確保している動的リソースを元に戻します。 + * @param i_inst + * 破棄するインスタンス + * initializeが成功したインスタンスだけが指定できます。 + */ +void NyLPC_cIPv4_finalize( + NyLPC_TcIPv4_t* i_inst); + +/** + * この関数は、インスタンスにTCP/IP処理の準備をするように伝えます。 + * @param i_inst + * 操作するインスタンス + * @param i_ref_configlation + * IPの環境値をセットしたオブジェクトを指定します。 + * この値は、stop関数を実行するまでの間、維持してください。 + */ +void NyLPC_cIPv4_start( + NyLPC_TcIPv4_t* i_inst, + const NyLPC_TcIPv4Config_t* i_ref_configlation); + +/** + * この関数はTCP/IP処理を停止することを伝えます。 + * @param i_inst + * 操作するインスタンス。 + * startで開始済みで無ければなりません。 + * @note + * 現在、接続中の接続に対する保障は未実装です。安全に使用することが出来ません。 + */ +void NyLPC_cIPv4_stop( + NyLPC_TcIPv4_t* i_inst); + +/** + * この関数は、NyLPC_TcBaseSocketオブジェクトを管理リストへ追加します。 + * @param i_inst + * 操作するインスタンス。 + * @param i_sock + * 追加するインスタンスのポインタ + * @return + * 追加が成功するとTRUEを返します。 + */ +NyLPC_TBool NyLPC_cIPv4_addSocket( + NyLPC_TcIPv4_t* i_inst, + NyLPC_TcMiMicIpBaseSocket_t* i_sock); + +/** + * この関数は、NyLPC_cTcpSocketオブジェクトを管理リストから除外します。 + * NyLPC_TcBaseSocketが使います。 + * @param i_inst + * 操作するインスタンス。 + * @param i_sock + * 削除するインスタンスのポインタ + * @return + * 削除が成功するとTRUEを返します。 + */ +NyLPC_TBool NyLPC_cIPv4_removeSocket( + NyLPC_TcIPv4_t* i_inst, + NyLPC_TcMiMicIpBaseSocket_t* i_sock); + + +/** + * この関数は、RxIPパケットを処理して、管理下のインスタンスに処理を依頼します。 + * 現在の関数は、i_rxに最大64バイトの応答パケットのイメージを格納することがあります。 + * 応答パケットは、RXに対するACKパケットです。 + * 格納の有無は戻り値を確認することで判ります。 + * この関数はstart-stopの間だけコールすることが出来ます。start,stopと非同期に実行しないでください。 + * @param i_inst + * 操作するインスタンスです。 + * @param i_rx + * RXパケットを格納したメモリアドレスです。 + * 最低でも、64バイト以上のサイズが必要です。 + * @param i_rx_size + * i_rxに格納したデータのサイズです。 + * @return + * 応答パケットを格納したメモリです。 + */ +void* NyLPC_cIPv4_rx(NyLPC_TcIPv4_t* i_inst,const void* i_rx,NyLPC_TUInt16 i_rx_size); +/** + * この関数は、定期的にインスタンスへ実行機会を与える関数です。 + * TCPの再送、無通信タイムアウトなどを処理します。 + * 約1秒おきに呼び出してください。 + * @param i_inst + * 操作するインスタンスです。 + */ +void NyLPC_cIPv4_periodec(NyLPC_TcIPv4_t* i_inst); + +/** + * ソケットリソースとコールバックの排他処理に使う共通MUTEXを返します。 + * このMutexはソケット同士の干渉が起こらない処理にだけ使ってください。 + */ +#define NyLPC_cIPv4_getSockMutex(i_inst) (&((i_inst)->_sock_mutex)) +/** + * リスナーリソースとコールバックの排他処理に使う共通MUTEXを返します。 + */ +#define NyLPC_cIPv4_getListenerMutex(i_inst) (&((i_inst)->_listener_mutex)) + +/** + * ポート0で使用するポート番号を返します。 + * @return + * 49152 - (49152+0x0ffff)番までのポートのうち、使用中でないポート番号を返します。 + * エラー時は0です。 + */ +NyLPC_TUInt16 NyLPC_cIPv4_getNewPortNumber(NyLPC_TcIPv4_t* i_inst); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cIPv4Arp.c Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,335 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + * + * Parts of this file were leveraged from uIP: + * + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "NyLPC_cIPv4Arp.h" +#include "../NyLPC_NetIf_ip_types.h" +#include "NyLPC_cMiMicIpNetIf_protected.h" +#include <string.h> + + +/** + * The maxium age of ARP table entries measured in 10ths of seconds. + * + * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD + * default). + */ +#define UIP_ARP_MAXAGE 120 + + +//static const struct NyLPC_TEthAddr broadcast_ethaddr = { { 0xff, 0xff, 0xff,0xff, 0xff, 0xff } }; +//static const struct NyLPC_TIPv4Addr broadcast_ipaddr = { 0xfffffff }; + + + + +static void uip_arp_update(NyLPC_TcIPv4Arp_t* i_inst,const struct NyLPC_TIPv4Addr* ipaddr,const struct NyLPC_TEthAddr *ethaddr); +/*-----------------------------------------------------------------------------------*/ +/** + * Initialize the ARP module. + * + */ +/*-----------------------------------------------------------------------------------*/ +void NyLPC_cIPv4Arp_initialize(NyLPC_TcIPv4Arp_t* i_inst,const NyLPC_TcIPv4Config_t* i_ref_config) +{ + int i; + struct NyLPC_TArpTableItem* tbl=i_inst->arp_table; + i_inst->_cfg = i_ref_config; + i_inst->arptime = 0; + i_inst->tmpage = 0; + for (i = 0; i < NyLPC_TcIPv4Arp_ARPTAB_SIZE; ++i) { + memset(&(tbl[i].ipaddr), 0, sizeof(struct NyLPC_TIPv4Addr)); + } +} +/*-----------------------------------------------------------------------------------*/ +/** + * Periodic ARP processing function. + * + * This function performs periodic timer processing in the ARP module + * and should be called at regular intervals. The recommended interval + * is 10 seconds between the calls. + * + */ +/*-----------------------------------------------------------------------------------*/ +void NyLPC_cIPv4Arp_periodic(NyLPC_TcIPv4Arp_t* i_inst) +{ + struct NyLPC_TArpTableItem* tbl=i_inst->arp_table; + struct NyLPC_TArpTableItem* tabptr; + int i; + i_inst->arptime++; + for (i = 0; i < NyLPC_TcIPv4Arp_ARPTAB_SIZE; ++i) { + tabptr = &tbl[i]; + if (tabptr->ipaddr.v != 0 && i_inst->arptime - tabptr->time >= UIP_ARP_MAXAGE) + { + tabptr->ipaddr.v = 0; + } + } + +} +/*-----------------------------------------------------------------------------------*/ +/** + * ARP processing for incoming IP packets + * + * This function should be called by the device driver when an IP + * packet has been received. The function will check if the address is + * in the ARP cache, and if so the ARP cache entry will be + * refreshed. If no ARP cache entry was found, a new one is created. + * + * This function expects an IP packet with a prepended Ethernet header + * in the uip_buf[] buffer, and the length of the packet in the global + * variable uip_len. + */ +/*-----------------------------------------------------------------------------------*/ +void NyLPC_cIPv4Arp_incomingIp(NyLPC_TcIPv4Arp_t* i_inst,const struct NyLPC_TEthernetIIHeader* i_eth,struct NyLPC_TIPv4Addr i_ip_src) +{ + //EtherとIPv4の値を読みだす。 + /* Only insert/update an entry if the source IP address of the + incoming IP packet comes from a host on the local network. */ + if ((i_ip_src.v & i_inst->_cfg->netmask.v) != (i_inst->_cfg->ip_addr.v & i_inst->_cfg->netmask.v)) { + return; + } + uip_arp_update(i_inst,&(i_ip_src), &(i_eth->src)); + return; +} +/** + * ARP processing for incoming ARP packets. + * + * This function should be called by the device driver when an ARP + * packet has been received. The function will act differently + * depending on the ARP packet type: if it is a reply for a request + * that we previously sent out, the ARP cache will be filled in with + * the values from the ARP reply. If the incoming ARP packet is an ARP + * request for our IP address, an ARP reply packet is created and put + * into the uip_buf[] buffer. + * + * When the function returns, the value of the global variable uip_len + * indicates whether the device driver should send out a packet or + * not. If uip_len is zero, no packet should be sent. If uip_len is + * non-zero, it contains the length of the outbound packet that is + * present in the uip_buf[] buffer. + * + * This function expects an ARP packet with a prepended Ethernet + * header in the uip_buf[] buffer, and the length of the packet in the + * global variable uip_len. + */ + + +/** + * ARPパケットの読出し用構造体 + */ +struct TArpPacketPtr +{ + struct NyLPC_TEthernetIIHeader header; + struct NyLPC_TArpHeader arp; +}PACK_STRUCT_END; + +/** + * arpパケットを処理します。 + */ +void* NyLPC_cIPv4Arp_rx(NyLPC_TcIPv4Arp_t* i_inst,const struct NyLPC_TArpHeader* i_arp, NyLPC_TUInt16 i_len, NyLPC_TUInt16* o_tx_len) +{ + struct NyLPC_TArpHeader* arp_tx; + if (i_len < sizeof(struct NyLPC_TArpHeader)) { + return NULL; + } + const NyLPC_TcIPv4Config_t* cfg=i_inst->_cfg; + switch (i_arp->opcode) { + case NyLPC_HTONS(ARP_REQUEST): + /* ARP request. If it asked for our address, we send out a reply. */ + if (NyLPC_TIPv4Addr_isEqual(&(i_arp->dipaddr), &(cfg->ip_addr))) { + /* First, we register the one who made the request in our ARP + table, since it is likely that we will do more communication + with this host in the future. */ + uip_arp_update(i_inst,&(i_arp->sipaddr), &i_arp->shwaddr); + //イーサネットヘッダもいじくるから + arp_tx=(struct NyLPC_TArpHeader*)NyLPC_cMiMicIpNetIf_allocSysTxBuf(); + + /* The reply opcode is 2. */ + arp_tx->hwtype =i_arp->hwtype; + arp_tx->protocol =i_arp->protocol; + arp_tx->hwlen =i_arp->hwlen; + arp_tx->protolen =i_arp->protolen; + arp_tx->opcode = NyLPC_HTONS(2); + memcpy(arp_tx->dhwaddr.addr, i_arp->shwaddr.addr, 6); + memcpy(arp_tx->shwaddr.addr, cfg->eth_mac.addr, 6); + arp_tx->dipaddr = i_arp->sipaddr; + arp_tx->sipaddr = cfg->ip_addr; + *o_tx_len=NyLPC_TEthernetIIHeader_setArpTx((((struct NyLPC_TEthernetIIHeader*)arp_tx)-1),&(i_inst->_cfg->eth_mac)); + +// /* The reply opcode is 2. */ +// i_arp->opcode = NyLPC_HTONS(2); +// +// memcpy(i_arp->dhwaddr.addr, i_arp->shwaddr.addr, 6); +// memcpy(i_arp->shwaddr.addr, cfg->eth_mac.addr, 6); +// +// i_arp->dipaddr = i_arp->sipaddr; +// i_arp->sipaddr = cfg->ip_addr; + return arp_tx; + } + break; + case NyLPC_HTONS(ARP_REPLY): + // ARP reply. We insert or update the ARP table if it was meant for us. + if (NyLPC_TIPv4Addr_isEqual(&(i_arp->dipaddr),&(cfg->ip_addr))) { + uip_arp_update(i_inst,&(i_arp->sipaddr), &i_arp->shwaddr); + } + break; + } + return NULL; +} +/** + * Prepend Ethernet header to an outbound IP packet and see if we need + * to send out an ARP request. + * + * This function should be called before sending out an IP packet. The + * function checks the destination IP address of the IP packet to see + * what Ethernet MAC address that should be used as a destination MAC + * address on the Ethernet. + * + * If the destination IP address is in the local network (determined + * by logical ANDing of netmask and our IP address), the function + * checks the ARP cache to see if an entry for the destination IP + * address is found. If so, an Ethernet header is prepended and the + * function returns. If no ARP cache entry is found for the + * destination IP address, the packet in the uip_buf[] is replaced by + * an ARP request packet for the IP address. The IP packet is dropped + * and it is assumed that they higher level protocols (e.g., TCP) + * eventually will retransmit the dropped packet. + * + * If the destination IP address is not on the local network, the IP + * address of the default router is used instead. + * + * When the function returns, a packet is present in the uip_buf[] + * buffer, and the length of the packet is in the global variable + * uip_len. + */ + +/** + * IPアドレス-MACアドレス交換 + */ +const struct NyLPC_TEthAddr* NyLPC_cIPv4Arp_IPv4toEthAddr(NyLPC_TcIPv4Arp_t* i_inst,const struct NyLPC_TIPv4Addr i_ip_addr) +{ + int i; + struct NyLPC_TArpTableItem *tabptr; + //ARPテーブルから検索 + for (i = NyLPC_TcIPv4Arp_ARPTAB_SIZE - 1; i >= 0; i--) { + tabptr = &i_inst->arp_table[i]; + if (NyLPC_TIPv4Addr_isEqual(&i_ip_addr,&(tabptr->ipaddr))) { + return &tabptr->ethaddr; + } + } + return NULL; +} + + + + + + + +static void uip_arp_update(NyLPC_TcIPv4Arp_t* i_inst,const struct NyLPC_TIPv4Addr* ipaddr,const struct NyLPC_TEthAddr *ethaddr) +{ + register struct NyLPC_TArpTableItem *tabptr; + int i,c; + /* Walk through the ARP mapping table and try to find an entry to + update. If none is found, the IP -> MAC address mapping is + inserted in the ARP table. */ + for (i = 0; i < NyLPC_TcIPv4Arp_ARPTAB_SIZE; ++i) { + tabptr = &i_inst->arp_table[i]; + /* Only check those entries that are actually in use. */ + if (tabptr->ipaddr.v != 0) { + /* Check if the source IP address of the incoming packet matches + the IP address in this ARP table entry. */ + if (ipaddr->v == tabptr->ipaddr.v) { + /* An old entry found, update this and return. */ + memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); + tabptr->time = i_inst->arptime; + + return; + } + } + } + + /* If we get here, no existing ARP table entry was found, so we + create one. */ + /* First, we try to find an unused entry in the ARP table. */ + for (i = 0; i < NyLPC_TcIPv4Arp_ARPTAB_SIZE; ++i) { + tabptr = &i_inst->arp_table[i]; + if (tabptr->ipaddr.v == 0) { + break; + } + } + + /* If no unused entry is found, we try to find the oldest entry and + throw it away. */ + if (i == NyLPC_TcIPv4Arp_ARPTAB_SIZE) { + i_inst->tmpage = 0; + c = 0; + for (i = 0; i < NyLPC_TcIPv4Arp_ARPTAB_SIZE; ++i) { + tabptr = &i_inst->arp_table[i]; + if (i_inst->arptime - tabptr->time > i_inst->tmpage) { + i_inst->tmpage = i_inst->arptime - tabptr->time; + c = i; + } + } + i = c; + tabptr = &i_inst->arp_table[i]; + } + + /* Now, i is the ARP table entry which we will fill with the new information. */ + tabptr->ipaddr = *ipaddr; + memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); + tabptr->time = i_inst->arptime; +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cIPv4Arp.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,116 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + * + * Parts of this file were leveraged from uIP: + * + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef NYLPC_CIPV4ARP_H_ +#define NYLPC_CIPV4ARP_H_ +#include "../NyLPC_cIPv4Config.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +struct NyLPC_TArpTableItem +{ + struct NyLPC_TIPv4Addr ipaddr; + struct NyLPC_TEthAddr ethaddr; + NyLPC_TUInt8 time; +}; + +/********************************************************************** + * + * class NyLPC_TcIPv4Config + * + **********************************************************************/ + + +#define NyLPC_TcIPv4Arp_ARPTAB_SIZE 8 + + +typedef struct NyLPC_TcIPv4Arp NyLPC_TcIPv4Arp_t; + +/** + * NyLPC_TcIPv4クラスの構造体です。 + */ +struct NyLPC_TcIPv4Arp +{ + const NyLPC_TcIPv4Config_t* _cfg; + NyLPC_TUInt8 arptime; + NyLPC_TUInt8 tmpage; + struct NyLPC_TArpTableItem arp_table[NyLPC_TcIPv4Arp_ARPTAB_SIZE]; +}; + +void NyLPC_cIPv4Arp_initialize(NyLPC_TcIPv4Arp_t* i_inst,const NyLPC_TcIPv4Config_t* i_ref_config); +#define NyLPC_cIPv4Arp_finalize(i_inst) +void NyLPC_cIPv4Arp_periodic(NyLPC_TcIPv4Arp_t* i_inst); +void NyLPC_cIPv4Arp_incomingIp(NyLPC_TcIPv4Arp_t* i_inst,const struct NyLPC_TEthernetIIHeader* i_eth,struct NyLPC_TIPv4Addr i_ip_src); +/** + * ARPメッセージを処理します。 + * @param o_tx_len + * 戻り値がある場合そのサイズ + * @return + * 応答パケットを格納したcUipService_allocBufで確保したメモリ + */ +void* NyLPC_cIPv4Arp_rx(NyLPC_TcIPv4Arp_t* i_inst,const struct NyLPC_TArpHeader* i_arp, NyLPC_TUInt16 i_len, NyLPC_TUInt16* o_tx_len); +const struct NyLPC_TEthAddr* NyLPC_cIPv4Arp_IPv4toEthAddr(NyLPC_TcIPv4Arp_t* i_inst,const struct NyLPC_TIPv4Addr i_ip_addr); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + + +#endif /* NYLPC_CIPV4ARP_H_ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cIPv4IComp.c Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,149 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + * + * Parts of this file were leveraged from uIP: + * + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "NyLPC_cIPv4IComp_protected.h" +#include "NyLPC_cMiMicIpNetIf_protected.h" +#define ICMP_ECHO_REPLY 0 +#define ICMP_ECHO 8 + + + +NyLPC_TBool NyLPC_cIPv4IComp_initialize( + NyLPC_TcIPv4IComp_t* i_inst, + const NyLPC_TcIPv4Config_t* i_ref_config) +{ + i_inst->_ref_config=i_ref_config; + return NyLPC_TBool_TRUE; +} +void NyLPC_cIPv4IComp_finalize( + NyLPC_TcIPv4IComp_t* i_inst) +{ + return; +} +/** + * ヘッダブロックの後ろにあるIPペイロードのアドレスを返します。 + */ +#define NyLPC_TIPv4Header_getHeaderSize(i) (((i)->vhl & 0x0f)*4) + +void* NyLPC_cIPv4IComp_rx( + const NyLPC_TcIPv4IComp_t* i_inst, + const NyLPC_TcIPv4Payload_t* i_ipp) +{ + NyLPC_TUInt16 tx_size; + struct NyLPC_TIPv4Header* tx; + struct NyLPC_TIcmpHeader* payload; + const struct NyLPC_TIPv4Addr* my_ip=&(i_inst->_ref_config->ip_addr); + + if (NyLPC_TIPv4Addr_isEqual(&(i_inst->_ref_config->ip_addr),&NyLPC_TIPv4Addr_ZERO)) + { + /* If we are configured to use ping IP address configuration and + hasn't been assigned an IP address yet, we accept all ICMP + packets. */ + } else { + /* Check if the packet is destined for our IP address. */ + if (!NyLPC_TIPv4Addr_isEqual(&(i_ipp->header->destipaddr),my_ip)) + { + return NyLPC_TBool_FALSE; + } + } + // ICMP echo (i.e., ping) processing. This is simple, we only change the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP checksum before we return the packet. + if (i_ipp->payload.icmp->type != ICMP_ECHO) + { + return NyLPC_TBool_FALSE; + } + //返送パケットの取得 + tx=(struct NyLPC_TIPv4Header*)NyLPC_cMiMicIpNetIf_allocTxBuf(NyLPC_NTOHS(i_ipp->header->len16),&tx_size); + if(tx==NULL){ + return NyLPC_TBool_FALSE; + } + //パケットサイズのチェック + if(tx_size<NyLPC_NTOHS(i_ipp->header->len16)){ + NyLPC_cMiMicIpNetIf_releaseTxBuf(tx); + return NyLPC_TBool_FALSE; + } + //返送パケットの構築 + ; + + //複製 + memcpy(tx,i_ipp->header,NyLPC_NTOHS(i_ipp->header->len16)); + + //ペイロードの編集 + payload=(struct NyLPC_TIcmpHeader*)(((NyLPC_TUInt8*)tx)+NyLPC_TIPv4Header_getHeaderSize(tx)); + payload->type = ICMP_ECHO_REPLY; + //update checksum + if (payload->icmpchksum >= NyLPC_HTONS(0xffff - (ICMP_ECHO << 8))) { + payload->icmpchksum += NyLPC_HTONS(ICMP_ECHO << 8) + 1; + } else { + payload->icmpchksum += NyLPC_HTONS(ICMP_ECHO << 8); + } + //IPヘッダの編集 + tx->destipaddr=tx->srcipaddr; + tx->srcipaddr=*my_ip; +/* + + //チェックサムの再計算 + i_ipp->payload.icmp->type = ICMP_ECHO_REPLY; + if (i_ipp->payload.icmp->icmpchksum >= NyLPC_HTONS(0xffff - (ICMP_ECHO << 8))) { + i_ipp->payload.icmp->icmpchksum += NyLPC_HTONS(ICMP_ECHO << 8) + 1; + } else { + i_ipp->payload.icmp->icmpchksum += NyLPC_HTONS(ICMP_ECHO << 8); + } + //OUT/INアドレスの反転 + i_ipp->header->destipaddr=i_ipp->header->srcipaddr; + i_ipp->header->srcipaddr=*my_ip; +*/ + return tx; + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cIPv4IComp.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,73 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + * + * Parts of this file were leveraged from uIP: + * + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef NYLPC_CIPV4ICOMP_H_ +#define NYLPC_CIPV4ICOMP_H_ +#include "../NyLPC_cIPv4Config.h" +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct NyLPC_TcIPv4IComp NyLPC_TcIPv4IComp_t; +struct NyLPC_TcIPv4IComp +{ + const NyLPC_TcIPv4Config_t* _ref_config; +}; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* NYLPC_CIPV4ICOMP_H_ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cIPv4IComp_protected.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,88 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + * + * Parts of this file were leveraged from uIP: + * + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef NYLPC_NyLPC_cIPv4IComp_protected_H_ +#define NYLPC_NyLPC_cIPv4IComp_protected_H_ + +#include "NyLPC_cIPv4Payload_protected.h" +#include "../NyLPC_NetIf_ip_types.h" +#include "NyLPC_cIPv4IComp.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +NyLPC_TBool NyLPC_cIPv4IComp_initialize( + NyLPC_TcIPv4IComp_t* i_inst, + const NyLPC_TcIPv4Config_t* i_ref_config); + +void NyLPC_cIPv4IComp_finalize( + NyLPC_TcIPv4IComp_t* i_inst); + +/** + * この関数は、ICOMP IPv4パケットを処理します。 + * @return + * イーサネットパケットを格納したメモリを返します。 + * このメモリはNyLPC_cUipService_allocTxBufで取得されたメモリです。 + */ +void* NyLPC_cIPv4IComp_rx( + const NyLPC_TcIPv4IComp_t* i_inst, + const NyLPC_TcIPv4Payload_t* i_ipp); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cIPv4Payload.c Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,144 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + * + * Parts of this file were leveraged from uIP: + * + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "NyLPC_cIPv4Payload_protected.h" + + + + + +/********************************************************************************* + * public 関数 + *********************************************************************************/ + + + + +void NyLPC_cIPv4Payload_initialize(NyLPC_TcIPv4Payload_t* i_inst) +{ + return; +} + +/** + * IPパケットを格納したバッファをセットして、ペイロードのポインタを返します。 + * 失敗時はFALSE + */ +NyLPC_TBool NyLPC_cIPv4Payload_attachRxBuf(NyLPC_TcIPv4Payload_t* i_inst,const void* i_buf,NyLPC_TUInt16 i_flagment_size) +{ + i_inst->header=(const struct NyLPC_TIPv4Header*)i_buf; + i_inst->payload.rawbuf=(const NyLPC_TUInt8*)i_buf+(i_inst->header->vhl & 0x0f)*4; + //IPパケットのバージョンチェック + if((i_inst->header->vhl & 0xf0)!=0x40){ + NyLPC_OnErrorGoto(Error); + } + //IPフレームサイズの調整 + if(NyLPC_ntohs(i_inst->header->len16)>i_flagment_size){ + NyLPC_OnErrorGoto(Error); + } + //フラグメントは許可しない。 + if ((NyLPC_ntohs(i_inst->header->ipoffset) & 0x3fff) != 0){ + NyLPC_OnErrorGoto(Error); + } + //IPv4ヘッダのチェックサムを確認 + if(!NyLPC_TIPv4Header_isCorrectIpCheckSum(i_inst->header)) + { + NyLPC_OnErrorGoto(Error); + } + return NyLPC_TBool_TRUE; +Error: + return NyLPC_TBool_FALSE; +} + +/* + * TcpIpのRxバッファをセットします。 + * @todo いらない? + */ +/* +void* NyLPC_cIPv4Payload_setTcpRxBuf(NyLPC_TcIPv4Payload_t* i_inst,void* i_buf,NyLPC_TUInt16 i_flagment_size) +{ + if(!NyLPC_cIPv4Payload_setRxBuf(i_inst,i_buf,i_flagment_size)){ + return NULL; + } + i_inst->header=(struct NyLPC_TIPv4Header*)i_buf; + return i_inst->payload.rawbuf+(i_inst->payload.tcp->tcpoffset>>4)*4; +} +*/ + + +const void* NyLPC_cIPv4Payload_detachBuf(NyLPC_TcIPv4Payload_t* i_inst) +{ + const void* r=i_inst->header; + NyLPC_ArgAssert(r!=NULL); + i_inst->header=NULL; + return r; +} +/* なんだっけっこれ? +//1の補数v1にv2を加算する。 +static NyLPC_TUInt16 add16c(NyLPC_TUInt16 i_v1,NyLPC_TUInt16 i_v2) +{ + NyLPC_TUInt16 t; + t=i_v1+i_v2; + return (t>i_v1)?t:t+1; +} +//1の補数v1から、v2を減算する。 +static NyLPC_TUInt16 sub16c(NyLPC_TUInt16 i_v1,NyLPC_TUInt16 i_v2) +{ + NyLPC_TUInt16 t; + t=i_v1-i_v2; + return (t<i_v1)?t:t-1; +} +*/ + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cIPv4Payload.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,96 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + * + * Parts of this file were leveraged from uIP: + * + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "../NyLPC_NetIf_ip_types.h" + +#ifndef NyLPC_cIPv4Payload_h +#define NyLPC_cIPv4Payload_h +typedef struct NyLPC_TcIPv4Payload NyLPC_TcIPv4Payload_t; + + + +/********************************************************************** + * + * NyLPC_TcIPv4Payload + * + **********************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +struct NyLPC_TcIPv4Payload +{ + //IPヘッダへのポインタです。バッファの先頭アドレスと同一です。 + const struct NyLPC_TIPv4Header* header; + union{ + //IPヘッダ終了位置のポインタです。 + const NyLPC_TUInt8* rawbuf; + const struct NyLPC_TIcmpHeader* icmp; + const struct NyLPC_TTcpHeader* tcp; + const struct NyLPC_TUdpHeader* udp; + }payload; +// NyLPC_TUInt16 buf_len; +}; + + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cIPv4Payload_protected.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,122 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + * + * Parts of this file were leveraged from uIP: + * + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef NYLPC_CIPV4PAYLOAD_PROTECTED_H_ +#define NYLPC_CIPV4PAYLOAD_PROTECTED_H_ + +#include "NyLPC_cIPv4Payload.h" +#include "NyLPC_cIPv4.h" +#include "NyLPC_cMiMicIpUdpSocket.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define TCP_FIN 0x01 +#define TCP_SYN 0x02 +#define TCP_RST 0x04 +#define TCP_PSH 0x08 +#define TCP_ACK 0x10 +#define TCP_URG 0x20 +#define TCP_CTL 0x3f + + + + +void NyLPC_cIPv4Payload_initialize(NyLPC_TcIPv4Payload_t* i_inst); +#define NyLPC_cIPv4Payload_finalize(i) + +/** + * アタッチされているバッファを返します。 + */ +#define NyLPC_cIPv4Payload_getBuf(i) ((i)->header) + + + +void NyLPC_cIPv4Payload_attachTxBuf(NyLPC_TcIPv4Payload_t* i_inst,void* i_buf); +const void* NyLPC_cIPv4Payload_detachBuf(NyLPC_TcIPv4Payload_t* i_inst); + +NyLPC_TBool NyLPC_cIPv4Payload_attachRxBuf(NyLPC_TcIPv4Payload_t* i_inst,const void* i_buf,NyLPC_TUInt16 i_flagment_size); +void NyLPC_cIPv4Payload_setTcpReverseRstAck( + NyLPC_TcIPv4Payload_t* i_inst); +void NyLPC_cIPv4Payload_setTcpReverseRstAck2( + NyLPC_TcIPv4Payload_t* i_inst, + const NyLPC_TcIPv4Payload_t* i_src); + + + + +/** + * UDPの送信バッファを初期化します。 + */ +void* NyLPC_cIPv4Payload_initUdpTx(NyLPC_TcIPv4Payload_t* i_inst,NyLPC_TUInt8 i_iph_word,NyLPC_TUInt16 i_tcp_payload_size); +/** + * UDPの送信情報を設定します。 + */ +void NyLPC_cIPv4Payload_setUdpTxHeaderByConnection(NyLPC_TcIPv4Payload_t* i_inst,const struct uip_udp_conn* i_conn,const struct NyLPC_TIPv4Addr* i_dest_ip,NyLPC_TUInt16 i_dest_port); + +void NyLPC_cIPv4Payload_closeUdpTxPacket( + NyLPC_TcIPv4Payload_t* i_inst); + + +void NyLPC_TcIPv4TxPacket_initialize_icomp(NyLPC_TcIPv4Payload_t* i_inst,void* i_buf,NyLPC_TUInt8 i_iph_word,NyLPC_TUInt16 i_tcp_payload_size); + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* NYLPC_CIPV4PAYLOAD_PROTECTED_H_ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cMiMicIpBaseSocket.c Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,11 @@ +#include "NyLPC_cMiMicIpBaseSocket.h" +#include "NyLPC_cMiMicIpNetIf_protected.h" + + +void NyLPC_cMiMicIpBaseSocket_initialize(NyLPC_TcMiMicIpBaseSocket_t* i_inst,NyLPC_TUInt8 i_typeid) +{ + NyLPC_TcMiMicIpNetIf_t* srv=_NyLPC_TcMiMicIpNetIf_inst; + i_inst->_typeid=i_typeid; + i_inst->_parent_ipv4=&(srv->_tcpv4); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cMiMicIpBaseSocket.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,72 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + *********************************************************************************/ +#ifndef NYLPC_CMIMICIPBASESOCKET_H_ +#define NYLPC_CMIMICIPBASESOCKET_H_ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "NyLPC_stdlib.h" +#include "NyLPC_cIPv4.h" +#include "../NyLPC_iTcpSocket.h" +#include "../NyLPC_iUdpSocket.h" +#include "../NyLPC_iTcpListener.h" + +/** + * Base socket class + * cIPv4 classが管理するソケットオブジェクトのベースクラスです。 + */ +typedef struct NyLPC_TcMiMicIpBaseSocket NyLPC_TcMiMicIpBaseSocket_t; + +#define NyLPC_TcMiMicIpBaseSocket_TYPEID_UDP_SOCK 1 +#define NyLPC_TcMiMicIpBaseSocket_TYPEID_TCP_SOCK 2 +#define NyLPC_TcMiMicIpBaseSocket_TYPEID_TCP_LISTENER 3 + +struct NyLPC_TcMiMicIpBaseSocket +{ + union{ + struct NyLPC_TiUdpSocket udp_sock; + struct NyLPC_TiTcpSocket tcp_sock; + struct NyLPC_TiTcpListener tcp_listener; + }_super; + /**タイプID 継承クラスのinitializerで設定。 */ + NyLPC_TUInt8 _typeid; + NyLPC_TUInt8 _padding8; + NyLPC_TUInt16 _padding16; + /** 所属してるIPv4コンローラ*/ + NyLPC_TcIPv4_t* _parent_ipv4; +}; +void NyLPC_cMiMicIpBaseSocket_initialize(NyLPC_TcMiMicIpBaseSocket_t* i_inst,NyLPC_TUInt8 i_typeid); +#define NyLPC_cMiMicIpBaseSocket_finalize(i_inst) + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* NYLPC_CBASESOCKET_H_ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cMiMicIpNetIf.c Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,774 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + * + * Parts of this file were leveraged from uIP: + * + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +//#include "NyLPC_cIPv4IComp_protected.h" +//#include "NyLPC_cTcpListener_protected.h" +#include "NyLPC_cMiMicIpNetIf_protected.h" +#include "NyLPC_stdlib.h" +#include "../NyLPC_NetIf_ip_types.h" +#include "NyLPC_cIPv4IComp_protected.h" +#include "NyLPC_cMiMicIpTcpSocket.h" +#include "NyLPC_cMiMicIpUdpSocket.h" +#include "NyLPC_cMiMicIpTcpListener.h" + + + + + +/**************************************************** + * UipServiceに関する宣言:その他 + ***************************************************/ +/** + * イーサネットフレームの読み出し構造体 + */ +struct TEthPacket +{ + struct NyLPC_TEthernetIIHeader header; + union{ + struct NyLPC_TArpHeader arp; + struct NyLPC_TIPv4Header ipv4; + }data; +}PACK_STRUCT_END; + + + +/** + * サービスインスタンスのポインタ。サービスが稼働中はインスタンスのポインタが有効です。 + */ +NyLPC_TcMiMicIpNetIf_t* _NyLPC_TcMiMicIpNetIf_inst=NULL; + + + +/** + * uipタスク + */ +static int uipTask(void *pvParameters); + +/** イーサネットドライバからのハンドラ*/ +static void ethernet_handler(void* i_param,NyLPC_TiEthernetDevice_EVENT i_type); + +//-------------------------------------------------------------- + + +static NyLPC_TBool sendIPv4Tx(struct TEthPacket* i_eth_buf); + +//static void sendArpReqest(const struct TEthPacket* i_eth_packet); +static void sendRawEthFrameNL(void* i_buf,NyLPC_TUInt16 i_len); +static void releaseTxBufNL(void* i_buf); + +/**メッセージなし*/ +#define TTaskMessage_MSG_NULL 0x0000 +/**uipコアタスクに、開始要求する*/ +#define TTaskMessage_MSG_RUN 0x0001 +/**uipコアタスクに、停止要求する*/ +#define TTaskMessage_MSG_STOP 0x0002 + + +static NyLPC_TcThread_t th; + + + +NyLPC_TBool NyLPC_cMiMicIpNetIf_initialize(NyLPC_TcMiMicIpNetIf_t* i_inst) +{ + //サービスは停止している事。 - Service must be uninitialized. + NyLPC_Assert(!NyLPC_cMiMicIpNetIf_isInitService()); + //IP処理部分の初期化 + NyLPC_cIPv4_initialize(&(i_inst->_tcpv4)); + //EMAC割込セマフォ + NyLPC_cSemaphore_initialize(&i_inst->_emac_semapho); + + i_inst->_status=0x00; + NyLPC_cStopwatch_initialize(&(i_inst->_arp_sw)); + NyLPC_cStopwatch_initialize(&(i_inst->_periodic_sw)); + NyLPC_cIPv4_initialize(&(i_inst->_tcpv4)); + NyLPC_AbortIfNot(NyLPC_cMutex_initialize(&(i_inst->_mutex))); + + _NyLPC_TcMiMicIpNetIf_inst=i_inst; + //タスク起動 + NyLPC_cThread_initialize(&th,NyLPC_cMiMicIpNetIf_config_STACK_SIZE,NyLPC_TcThread_PRIORITY_SERVICE); + NyLPC_cThread_start(&th,uipTask,NULL); + return NyLPC_TBool_TRUE; +} + + + + + + + +/** + * UIP処理を開始します。 + * この関数はリエントラントではありません。複数のタスクから共有するときには、排他ロックを掛けてください。 + * @param i_ref_config + * このコンフィギュレーションは、stopを実行するまでの間、インスタンスから参照します。外部で保持してください。 + */ +void NyLPC_cMiMicIpNetIf_start(const NyLPC_TcIPv4Config_t* i_ref_config) +{ + NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; + NyLPC_Assert(NyLPC_cMiMicIpNetIf_isInitService()); + if(!NyLPC_cMiMicIpNetIf_isRun()) + { + //はじめて起動するときに1度だけデバイス取得(タスクスイッチが動いてないと動かないからここで。) + if(inst->_ethif==NULL){ + inst->_ethif=getEthernetDevicePnP(); + } + //コンフィグレーションセット + inst->_netinfo.current_config=i_ref_config; + //開始要求セット + NyLPC_TUInt16_setBit(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_START); + //Order実行待ち + while(NyLPC_TUInt16_isBitOn(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_START)){ + NyLPC_cThread_sleep(10); + } + //デバイス情報の追記 + inst->_netinfo.device_name=NyLPC_iEthernetDevice_getDevicName(inst->_ethif); + } + return; +} +/** + * UIP処理を停止します。 + * この関数はリエントラントではありません。複数のタスクから共有するときには、排他ロックを掛けてください。 + * いまのところ、ストップシーケンスの実装は良くありません。 + * 再設計が必要。 + */ +void NyLPC_cMiMicIpNetIf_stop(void) +{ + NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; + NyLPC_Assert(NyLPC_cMiMicIpNetIf_isInitService()); + if(NyLPC_cMiMicIpNetIf_isRun()) + { + NyLPC_TUInt16_setBit(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_STOP); + //Order実行待ち + while(NyLPC_TUInt16_isBitOn(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_STOP)){ + NyLPC_cThread_sleep(10); + } + } + return; +} + +static const struct NyLPC_TNetInterfaceInfo* NyLPC_cMiMicIpNetIf_getInterfaceInfo(void) +{ + NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; + return &inst->_netinfo; +} + +/********************************************************************** + * + * </HWコールバックに関わる宣言> + * + *********************************************************************/ + + +//PERIODIC rate +#define PERIODIC_TIMER (1*200) +#define ARP_TIMER (60*1000*10) + + + +/** + * 操作キューを確認して、タスクのステータスをアップデートします。 + * 高速化のため、Proc-Callerを使用していません。複雑なタスク操作をするときには、書き換えてください。 + * @return + * UIPタスクの実行状態 + */ +static NyLPC_TBool updateTaskStatus() +{ + NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; + if(NyLPC_cMiMicIpNetIf_isRun()){ + //開始状態 + if(NyLPC_TUInt16_isBitOn(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_STOP)) + { + //停止操作 + NyLPC_iEthernetDevice_stop(inst->_ethif); + NyLPC_cIPv4_stop(&(inst->_tcpv4)); + NyLPC_cIPv4IComp_finalize(&(inst->_icomp)); + NyLPC_cIPv4Arp_finalize(&(inst->_arp)); +// inst->_ref_config=NULL; + NyLPC_TUInt16_unsetBit(inst->_status,NyLPC_TcMiMicIpNetIf_STATUSBIT_IS_RUNNING); + NyLPC_TUInt16_unsetBit(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_STOP); + return NyLPC_TBool_FALSE; + } + return NyLPC_TBool_TRUE; + }else{ + //停止状態 + if(NyLPC_TUInt16_isBitOn(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_START)) + { + //TCP,ICOMPの初期化 + NyLPC_cIPv4_start(&(inst->_tcpv4),inst->_netinfo.current_config); + NyLPC_cIPv4IComp_initialize(&(inst->_icomp),inst->_netinfo.current_config); + //uip_arp_init(msg->start.ref_config); + NyLPC_cIPv4Arp_initialize(&(inst->_arp),inst->_netinfo.current_config); + NyLPC_cStopwatch_startExpire(&(inst->_arp_sw),1);//1度ARPを起動するため。 + NyLPC_cStopwatch_startExpire(&(inst->_periodic_sw),PERIODIC_TIMER); + //EtherNETデバイス初期化 + while(!NyLPC_iEthernetDevice_start(inst->_ethif,&(inst->_netinfo.current_config->eth_mac),ethernet_handler,inst)); + NyLPC_TUInt16_setBit(inst->_status,NyLPC_TcMiMicIpNetIf_STATUSBIT_IS_RUNNING); + NyLPC_TUInt16_unsetBit(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_START); + return NyLPC_TBool_TRUE; + } + return NyLPC_TBool_FALSE; + } +} + +/** + * uipタスクのメインループ + */ +static int uipTask(void *pvParameters) +{ + NyLPC_TUInt16 rx_len,tx_len; + struct TEthPacket* ethbuf; + NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; + void* r; + (void)pvParameters; + for( ;; ) + { + //タスク状態の更新 + if(!updateTaskStatus()) + { + //RUNステータス以外の時は、ここで終了する。 + NyLPC_cThread_sleep(50); + continue; + } + //イーサネットフレームの取得 + //Ethernet Device Lock(ARPを含む) + NyLPC_cMutex_lock(&(inst->_mutex)); + ethbuf= (struct TEthPacket*)NyLPC_iEthernetDevice_getRxEthFrame(inst->_ethif,&rx_len); + tx_len=0; + while(ethbuf != NULL){ + if(rx_len>0) + { + //ペイロードサイズを計算 + rx_len-=sizeof(struct NyLPC_TEthernetIIHeader); + switch(ethbuf->header.type) + { + case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_IP): + //ARPテーブルの更新 + //uip_arp_ipin(&(ethbuf->header),ethbuf->data.ipv4.srcipaddr); + NyLPC_cIPv4Arp_incomingIp(&inst->_arp,&(ethbuf->header),ethbuf->data.ipv4.srcipaddr); + //Ethernet Device UnLock(NyLPC_cIPv4_rxがallocをコールする可能性があるので一時的にロック解除) + NyLPC_cMutex_unlock(&(inst->_mutex)); + //IPパケットの処理 + r=NyLPC_cIPv4_rx(&(inst->_tcpv4),&(ethbuf->data.ipv4),rx_len); + if(r!=NULL){ + //IPパケットとして送信 + NyLPC_cMiMicIpNetIf_sendIPv4Tx(r); + } + //ロックの復帰 + NyLPC_cMutex_lock(&(inst->_mutex)); + if(r!=NULL){ + releaseTxBufNL(r); + } + break; + case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_ARP): + //Ethernet Device UnLock(NyLPC_cIPv4_rxがallocをコールする可能性があるので一時的にロック解除) + NyLPC_cMutex_unlock(&(inst->_mutex)); + r=NyLPC_cIPv4Arp_rx(&inst->_arp,&(ethbuf->data.arp),rx_len,&tx_len); + NyLPC_cMutex_lock(&(inst->_mutex)); + if(r!=NULL){ + sendRawEthFrameNL(r,tx_len); + releaseTxBufNL(r); + } + break; + case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_IPV6): + //uip_process_ipv6(); + break; + default: + break; + } + } + //受信キューを進行。 + NyLPC_iEthernetDevice_nextRxEthFrame(inst->_ethif); + //受信処理 + ethbuf= (struct TEthPacket*)NyLPC_iEthernetDevice_getRxEthFrame(inst->_ethif,&rx_len); + } + //データが無い。 + if(NyLPC_cStopwatch_isExpired(&(inst->_arp_sw))){ + //uip_arp_timer(); + NyLPC_cIPv4Arp_periodic(&inst->_arp); + NyLPC_cStopwatch_startExpire(&(inst->_arp_sw),ARP_TIMER); + } + if(NyLPC_cStopwatch_isExpired(&(inst->_periodic_sw))){ + NyLPC_cMutex_unlock(&(inst->_mutex)); + NyLPC_cIPv4_periodec(&(inst->_tcpv4)); + NyLPC_cMutex_lock(&(inst->_mutex)); + NyLPC_cStopwatch_startExpire(&(inst->_periodic_sw),PERIODIC_TIMER); + } + //リソースロックの解除 + NyLPC_cMutex_unlock(&(inst->_mutex)); + //割込によるセマフォの解除か、タイムアウトで再開する。(タイムアウト値は周期関数の実行レート以下にすること。) + NyLPC_cSemaphore_take(&(_NyLPC_TcMiMicIpNetIf_inst->_emac_semapho),PERIODIC_TIMER); + } + return 0; +} + + +/** + * イーサネットドライバからのハンドラ + */ +static void ethernet_handler(void* i_param,NyLPC_TiEthernetDevice_EVENT i_type) +{ + switch(i_type){ + case NyLPC_TiEthernetDevice_EVENT_ON_RX: + //受信系のセマフォブロックの解除 + NyLPC_cSemaphore_giveFromISR(&(((NyLPC_TcMiMicIpNetIf_t*)i_param)->_emac_semapho)); + break; + default: + break; + } +} + +/** + * IPv4パケットのpeerIPを問い合わせるARPパケットを送信します。 + * allocを中でコールするから要UNLOCK状態 + */ +void NyLPC_cMiMicIpNetIf_sendArpRequest(const struct NyLPC_TIPv4Addr* i_addr) +{ + NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; + void* p; + NyLPC_TUInt16 tx_len; + struct TEthPacket* ethbuf; + //システムTxBufを得る + ethbuf=(struct TEthPacket*)NyLPC_cMiMicIpNetIf_allocSysTxBuf(); + //ARPパケットを作る。 + NyLPC_TArpHeader_setArpRequest(&(ethbuf->data.arp),inst->_netinfo.current_config->ip_addr,&(inst->_netinfo.current_config->eth_mac),i_addr); + tx_len=NyLPC_TEthernetIIHeader_setArpTx(&(ethbuf->header),&(inst->_netinfo.current_config->eth_mac)); + //送信 + p=((struct NyLPC_TEthernetIIHeader*)ethbuf)-1; + + NyLPC_cMutex_lock(&(inst->_mutex)); + NyLPC_iEthernetDevice_sendTxEthFrame(inst->_ethif,p,tx_len); + NyLPC_iEthernetDevice_releaseTxBuf(inst->_ethif,p); + NyLPC_cMutex_unlock(&(inst->_mutex)); +} + + + + +/** + * allocTxBufで取得したペイロードメモリを"IPパケットとして"送信します。 + * @param i_eth_payload + * [NyLPC_TEthernetIIHeader][payload]メモリの、[payload]のアドレスを指定します。 + * 通常は、NyLPC_cUipService_allocTxBufの返却したメモリを指定します。 + */ + +void NyLPC_cMiMicIpNetIf_sendIPv4Tx(void* i_eth_payload) +{ + NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; + void* p=((struct NyLPC_TEthernetIIHeader*)i_eth_payload)-1; + NyLPC_cMutex_lock(&(inst->_mutex)); + //IPパケットの送信を試行 + if(sendIPv4Tx((struct TEthPacket*)p)){ + NyLPC_cMutex_unlock(&(inst->_mutex)); + return; + } + NyLPC_cMutex_unlock(&(inst->_mutex)); + //ARPリクエストを代わりに送信 + NyLPC_cMiMicIpNetIf_sendArpRequest(&((struct NyLPC_TIPv4Header*)i_eth_payload)->destipaddr); + return; +} + + +/** + * ARPテーブルに指定したIPがあるかを返します。 + */ +NyLPC_TBool NyLPC_cMiMicIpNetIf_hasArpInfo(const struct NyLPC_TIPv4Addr* i_addr) +{ + NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; + return NyLPC_cIPv4Arp_IPv4toEthAddr(&inst->_arp,*i_addr)!=NULL; +} + +/** + * システム用の送信ペイロードを返します。 + * 関数は必ず成功します。 + */ +void* NyLPC_cMiMicIpNetIf_allocSysTxBuf(void) +{ + NyLPC_TUInt16 s; + NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; + struct TEthPacket* ethbuf; + //排他処理をして、メモリを取得する。SYSTEMメモリはEthernetドライバの解放待ちのみなのでまとめてLOCKしておk + NyLPC_cMutex_lock(&(inst->_mutex)); + for(;;){ + ethbuf=(struct TEthPacket*)NyLPC_iEthernetDevice_allocTxBuf(inst->_ethif,NyLPC_TcEthernetMM_HINT_CTRL_PACKET,&s); + if(ethbuf==NULL){ + NyLPC_cThread_yield(); + continue; + } + break; + } + NyLPC_cMutex_unlock(&(inst->_mutex)); + //イーサネットバッファのアドレスを計算 + return &(ethbuf->data); +} + + + +void* NyLPC_cMiMicIpNetIf_allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size) +{ + NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; + struct TEthPacket* ethbuf; + //排他処理をして、メモリを取得する。 + NyLPC_cMutex_lock(&(inst->_mutex)); + ethbuf=(struct TEthPacket*)NyLPC_iEthernetDevice_allocTxBuf(inst->_ethif,i_hint+sizeof(struct NyLPC_TEthernetIIHeader),o_size); + NyLPC_cMutex_unlock(&(inst->_mutex)); + if(ethbuf==NULL){ + return NULL; + } + //イーサネットバッファのサイズを計算 + *o_size-=sizeof(struct NyLPC_TEthernetIIHeader); + //イーサネットバッファのアドレスを計算 + return &(ethbuf->data); +} + + +void* NyLPC_cMiMicIpNetIf_releaseTxBuf(void* i_buf) +{ + //排他処理をして、メモリを開放する。 + NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; + NyLPC_cMutex_lock(&(inst->_mutex)); + //ペイロードの位置から、メモリブロックを再生。 + NyLPC_iEthernetDevice_releaseTxBuf(inst->_ethif,((struct NyLPC_TEthernetIIHeader*)i_buf)-1); + NyLPC_cMutex_unlock(&(inst->_mutex)); + return NULL; +} + + + + + + + + + +/** + * イーサネットフレームを送信します。 + * この関数はiptaskで実行される関数からのみ使用てください。 + * @i_buf + * イーサネットフレームを格納したメモリです。 + * @i_len + * イーサネットペイロードのサイズです。 + */ +static void sendRawEthFrameNL(void* i_buf,NyLPC_TUInt16 i_len) +{ + NyLPC_iEthernetDevice_sendTxEthFrame( + _NyLPC_TcMiMicIpNetIf_inst->_ethif, + ((struct NyLPC_TEthernetIIHeader*)i_buf)-1, + i_len); + return; +} +/** + * ロック状態で使用できるreleaseTxBuf。 + * この関数はiptaskで実行される関数からのみ使用してください。 + */ +static void releaseTxBufNL(void* i_buf) +{ + //ペイロードの位置から、メモリブロックを再生。 + NyLPC_iEthernetDevice_releaseTxBuf( + _NyLPC_TcMiMicIpNetIf_inst->_ethif, + ((struct NyLPC_TEthernetIIHeader*)i_buf)-1); + return; +} +/** + * マルチキャスとアドレスへ変換する。 + */ +static void ip2MulticastEmacAddr(const struct NyLPC_TIPv4Addr* i_addr,struct NyLPC_TEthAddr* o_emac) +{ + NyLPC_TUInt32 n=NyLPC_htonl(i_addr->v); + o_emac->addr[0]=0x01; + o_emac->addr[1]=0x00; + o_emac->addr[2]=0x5E; + o_emac->addr[3]=((n>>16) & 0x7f); + o_emac->addr[4]=((n>> 8) & 0xff); + o_emac->addr[5]=(n & 0xff); + return; +}; + +/** + * ペイロードをIPパケットとしてネットワークへ送出します。 + * コール前に、必ずロックしてから呼び出してください。 + * @param i_eth_payload + * allocTxBufで確保したメモリを指定してください。 + * ペイロードには、TCP/IPパケットを格納します。 + */ +static NyLPC_TBool sendIPv4Tx(struct TEthPacket* i_eth_buf) +{ + NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; + struct NyLPC_TEthAddr emac; + NyLPC_TUInt16 tx_len; + const struct NyLPC_TEthAddr* eth_dest; + //ペイロードのアドレスから、イーサネットフレームバッファのアドレスを復元 + + if(NyLPC_TIPv4Addr_isEqual(&(i_eth_buf->data.ipv4.destipaddr),&NyLPC_TIPv4Addr_BROADCAST)) { + //ブロードキャストならそのまま + eth_dest=&NyLPC_TEthAddr_BROADCAST; + }else if(NyLPC_TIPv4Addr_isEqualWithMask(&(i_eth_buf->data.ipv4.destipaddr),&NyLPC_TIPv4Addr_MULTICAST,&NyLPC_TIPv4Addr_MULTICAST_MASK)){ + //マルチキャスト + ip2MulticastEmacAddr(&(i_eth_buf->data.ipv4.destipaddr),&emac); + eth_dest=&emac; + }else{ + //LocalIP以外ならdefaultRootへ変換 + eth_dest=NyLPC_cIPv4Arp_IPv4toEthAddr( + &inst->_arp, + NyLPC_cIPv4Config_isLocalIP(inst->_netinfo.current_config, &(i_eth_buf->data.ipv4.destipaddr))?(i_eth_buf->data.ipv4.destipaddr):(inst->_netinfo.current_config->dr_addr)); + //IP->MAC変換をテスト。 + if(eth_dest==NULL){ + return NyLPC_TBool_FALSE; + } + } + //変換可能なら、イーサネットヘッダを更新して、送信処理へ。 + tx_len=NyLPC_TEthernetIIHeader_setIPv4Tx(&(i_eth_buf->header),&(inst->_netinfo.current_config->eth_mac),eth_dest); + NyLPC_iEthernetDevice_sendTxEthFrame(inst->_ethif,i_eth_buf,tx_len); + return NyLPC_TBool_TRUE; +} + +static NyLPC_TBool isInitService(void) +{ + return _NyLPC_TcMiMicIpNetIf_inst!=NULL; +} + +//-------------------------------------------------------------------------------- +// +// NetIF Interface +// +//-------------------------------------------------------------------------------- + + +//-------------------------------------------------------------------------------- +// フラグ +static NyLPC_TUInt8 socket_flags[ + NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX+ + NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX+ + NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX+ + NyLPC_cMiMicIpNetIf_config_TCPLISTENER_MAX]; + +#define FLAGS_USED 0x01 +#define TCP_SOCK_FLSGS(i) (socket_flags[(i)]) +#define UDP_SOCK_FLSGS(i) (socket_flags[(i)+NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX]) +#define UDP_NB_SOCK_FLSGS(i) (socket_flags[(i)+NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX+NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX]) +#define TCP_LISTENER_FLSGS(i) (socket_flags[(i)+NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX+NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX+NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX]) + + +//-------------------------------------------------------------------------------- +// SOCKETインスタンスのメモリブロック +static NyLPC_TUInt8 socket_memblock[ + sizeof(NyLPC_TcMiMicIpTcpSocket_t)*NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX + + sizeof(NyLPC_TcMiMicIpUdpSocket_t)*NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX + + sizeof(NyLPC_TcMiMicIpUdpSocket_t)*NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX+ + sizeof(NyLPC_TcMiMicIpTcpListener_t)*NyLPC_cMiMicIpNetIf_config_TCPLISTENER_MAX]; + +#define TCP_SOCK_TBL(i) (((NyLPC_TcMiMicIpTcpSocket_t*)socket_memblock)+i) +#define UDP_SOCK_TBL(i) (((NyLPC_TcMiMicIpUdpSocket_t*)(TCP_SOCK_TBL(NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX)))+i) +#define UDP_NB_SOCK_TBL(i) (((NyLPC_TcMiMicIpUdpSocket_t*)(UDP_SOCK_TBL(NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX)))+i) +#define TCP_LISTENER_TBL(i) (((NyLPC_TcMiMicIpTcpListener_t*)(UDP_NB_SOCK_TBL(NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX)))+i) + + +//-------------------------------------------------------------------------------- +// ソケットのメモリ + +static NyLPC_TUInt8 socket_buffer[ + NyLPC_cMiMicIpNetIf_config_TCPSOCKET_RX_BUFFER_SIZE*NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX+ + NyLPC_cMiMicIpNetIf_config_UDPSOCKET_RX_BUFFER_SIZE*NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX]; + +#define TCP_SOCK_BUF(i) (socket_buffer+(i)*NyLPC_cMiMicIpNetIf_config_TCPSOCKET_RX_BUFFER_SIZE) +#define UDP_SOCK_BUF(i) (TCP_SOCK_BUF(NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX)+(i)*NyLPC_cMiMicIpNetIf_config_UDPSOCKET_RX_BUFFER_SIZE) + +//-------------------------------------------------------------------------------- +// インタフェイス関数 + +static NyLPC_TiTcpSocket_t* createTcpSocetEx(NyLPC_TSocketType i_socktype) +{ + NyLPC_TUInt16 i; + switch(i_socktype){ + case NyLPC_TSocketType_TCP_HTTP: + case NyLPC_TSocketType_TCP_NORMAL: + //空きソケットの探索 + for(i=0;i<NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX;i++){ + //未使用なソケットを得る + if((TCP_SOCK_FLSGS(i)&FLAGS_USED)==0){ + if(!NyLPC_cMiMicIpTcpSocket_initialize(TCP_SOCK_TBL(i),TCP_SOCK_BUF(i),NyLPC_cMiMicIpNetIf_config_TCPSOCKET_RX_BUFFER_SIZE)){ + return NULL; + } + //ソケットを使用中に + TCP_SOCK_FLSGS(i)|=FLAGS_USED; + return &(TCP_SOCK_TBL(i)->_super._super.tcp_sock); + } + } + break; + default: + break; + } + return NULL; +} + +static NyLPC_TiUdpSocket_t* createUdpSocetEx(NyLPC_TUInt16 i_port,NyLPC_TSocketType i_socktype) +{ + NyLPC_TUInt16 i; + switch(i_socktype){ + case NyLPC_TSocketType_UDP_NORMAL: + //空きソケットの探索 + for(i=0;i<NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX;i++){ + //未使用なソケットを得る + if((UDP_SOCK_FLSGS(i)&FLAGS_USED)==0){ + if(!NyLPC_cMiMicIpUdpSocket_initialize(UDP_SOCK_TBL(i),i_port,UDP_SOCK_BUF(i),NyLPC_cMiMicIpNetIf_config_UDPSOCKET_RX_BUFFER_SIZE)){ + return NULL; + } + UDP_SOCK_FLSGS(i)|=FLAGS_USED; + return &(UDP_SOCK_TBL(i)->_super._super.udp_sock); + } + } + break; + case NyLPC_TSocketType_UDP_NOBUF: + //空きソケットの探索 + for(i=0;i<NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX;i++){ + //未使用なソケットを得る + if((UDP_NB_SOCK_FLSGS(i)&FLAGS_USED)==0){ + if(!NyLPC_cMiMicIpUdpSocket_initialize(UDP_NB_SOCK_TBL(i),i_port,NULL,0)){ + return NULL; + } + UDP_NB_SOCK_FLSGS(i)|=FLAGS_USED; + return &(UDP_NB_SOCK_TBL(i)->_super._super.udp_sock); + } + } + break; + default: + break; + } + return NULL; +} +static NyLPC_TiTcpListener_t* createTcpListener(NyLPC_TUInt16 i_port) +{ + NyLPC_TUInt16 i; + //空きソケットの探索 + for(i=0;i<NyLPC_cMiMicIpNetIf_config_TCPLISTENER_MAX;i++){ + //未使用なソケットを得る + if((TCP_LISTENER_FLSGS(i)&FLAGS_USED)==0){ + if(!NyLPC_cMiMicIpTcpListener_initialize(TCP_LISTENER_TBL(i),i_port)){ + return NULL; + } + //ソケットを使用中に + TCP_LISTENER_FLSGS(i)|=FLAGS_USED; + return &(TCP_LISTENER_TBL(i)->_super._super.tcp_listener); + } + } + return NULL; +} + + +static const struct NyLPC_TiNetInterface_Interface _interface= +{ + createTcpSocetEx, + createUdpSocetEx, + createTcpListener, + NyLPC_cMiMicIpNetIf_start, + NyLPC_cMiMicIpNetIf_stop, + NyLPC_cMiMicIpNetIf_sendArpRequest, + NyLPC_cMiMicIpNetIf_hasArpInfo, + isInitService,//NyLPC_TiNetInterface_isInitService isinitservice; + NyLPC_cMiMicIpNetIf_getInterfaceInfo +}; +//-------------------------------------------------------------------------------- +// インスタンスのリリース(protected) + +void NyLPC_cMiMicIpNetIf_releaseTcpSocketMemory(const NyLPC_TcMiMicIpTcpSocket_t* i_inst) +{ + NyLPC_TUInt16 i; + //空きソケットの探索 + for(i=0;i<NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX;i++){ + if((TCP_SOCK_TBL(i))==i_inst){ + TCP_SOCK_FLSGS(i)&=~FLAGS_USED; + return; + } + } + return; +} +void NyLPC_cMiMicIpNetIf_releaseUdpSocketMemory(const NyLPC_TcMiMicIpUdpSocket_t* i_inst) +{ + NyLPC_TUInt16 i; + for(i=0;i<NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX;i++){ + if((UDP_SOCK_TBL(i))==i_inst){ + UDP_SOCK_FLSGS(i)&=~FLAGS_USED; + return; + } + } + for(i=0;i<NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX;i++){ + if((UDP_NB_SOCK_TBL(i))==i_inst){ + UDP_NB_SOCK_FLSGS(i)&=~FLAGS_USED; + return; + } + } + return; +} +void NyLPC_cMiMicIpNetIf_releaseTcpListenerMemory(const NyLPC_TcMiMicIpTcpListener_t* i_inst) +{ + NyLPC_TUInt16 i; + //空きソケットの探索 + for(i=0;i<NyLPC_cMiMicIpNetIf_config_TCPLISTENER_MAX;i++){ + if((TCP_LISTENER_TBL(i))==i_inst){ + TCP_LISTENER_FLSGS(i)&=~FLAGS_USED; + return; + } + } + return; +} + +static NyLPC_TcMiMicIpNetIf_t _netif; + +const struct NyLPC_TiNetInterface_Interface* NyLPC_cMiMicIpNetIf_getNetInterface(void) +{ + NyLPC_cMiMicIpNetIf_initialize(&_netif); + return &_interface; +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cMiMicIpNetIf.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,132 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + * + * Parts of this file were leveraged from uIP: + * + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef NyLPC_TcMiMicIpNetIf_H_ +#define NyLPC_TcMiMicIpNetIf_H_ +#include "NyLPC_config.h" +#include "NyLPC_stdlib.h" +#include "../NyLPC_iNetInterface.h" +#include "../NyLPC_cIPv4Config.h" +/********************************************************************** + * Heder files + **********************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/********************************************************************** + * + * NyLPC_TcUipService class + * + **********************************************************************/ +/** + * uipタスクを管理する、サービスクラスです。 + */ +typedef struct NyLPC_TcMiMicIpNetIf NyLPC_TcMiMicIpNetIf_t; + + +/** サービスタスクスタックサイズ + * mdns 256+96(MIN) + * upnp 256+160(MIN) + * mbedのExportしたのをLPCXpressoでコンパイルするときは+192しないと落ちる。 + */ +#ifndef NyLPC_cMiMicIpNetIf_config_STACK_SIZE +# define NyLPC_cMiMicIpNetIf_config_STACK_SIZE (256+192+192) +#endif + +/** + * SOCKETリソースの最大数とRXメモリサイズ + */ + +#ifndef NyLPC_cMiMicIpNetIf_config_TCPLISTENER_MAX +# define NyLPC_cMiMicIpNetIf_config_TCPLISTENER_MAX 2 +#endif +#ifndef NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX +# define NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX 3 +#endif +#ifndef NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX +# define NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX 1 +#endif +#ifndef NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX +# define NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX 2 +#endif +#ifndef NyLPC_cMiMicIpNetIf_config_TCPSOCKET_RX_BUFFER_SIZE +# define NyLPC_cMiMicIpNetIf_config_TCPSOCKET_RX_BUFFER_SIZE 512 +#endif +#ifndef NyLPC_cMiMicIpNetIf_config_UDPSOCKET_RX_BUFFER_SIZE +# define NyLPC_cMiMicIpNetIf_config_UDPSOCKET_RX_BUFFER_SIZE 512 +#endif + + +/** + * @param i_mac_addr + * システムで唯一のUIPサービスを初期化します。1度だけ実行できます。 + */ +NyLPC_TBool NyLPC_cMiMicIpNetIf_initialize(NyLPC_TcMiMicIpNetIf_t* i_inst); + + + + +//const NyLPC_TcIPv4Config_t* NyLPC_cUipService_refCurrentConfig(void); +const struct NyLPC_TiNetInterface_Interface* NyLPC_cMiMicIpNetIf_getNetInterface(void); + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cMiMicIpNetIf_protected.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,171 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + *********************************************************************************/ + +#ifndef NyLPC_MiMicIpNetIf_protected_H +#define NyLPC_MiMicIpNetIf_protected_H +#include "NyLPC_cMiMicIpNetIf.h" +#include "NyLPC_os.h" +#include "NyLPC_cIPv4Arp.h" +#include "NyLPC_cIPv4.h" +#include "NyLPC_cIPv4IComp.h" +#include "../driver/ethernet/EthDev.h" +#include "NyLPC_cMiMicIpTcpSocket.h" +#include "NyLPC_cMiMicIpUdpSocket.h" +#include "NyLPC_cMiMicIpTcpListener.h" + +/********************************************************************** + * + * NyLPC_TcUipService_t + * + **********************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +//#define NyLPC_TcUipService_SIZE_OF_REPLY_BUF 128 + + + +struct NyLPC_TcMiMicIpNetIf +{ + volatile NyLPC_TUInt16 _status; /**< ステータスビット*/ + NyLPC_TcSemaphore_t _emac_semapho; /** EMACの制御用セマフォです。*/ + NyLPC_TcStopwatch_t _arp_sw; /**<ARP用のストップウォッチ*/ + NyLPC_TcStopwatch_t _periodic_sw; /**<周期実行用のストップウォッチ*/ + /** ARP処理インスタンス*/ + NyLPC_TcIPv4Arp_t _arp; + /** TCPv4処理インスタンス*/ + NyLPC_TcIPv4_t _tcpv4; + /** ICOMP処理インスタンス*/ + NyLPC_TcIPv4IComp_t _icomp; + /** (Ethernetメモリ排他制御用)*/ + NyLPC_TcMutex_t _mutex; + const struct TiEthernetDevice* _ethif; + struct NyLPC_TNetInterfaceInfo _netinfo; +}; + + +/** 唯一のサービスインスタンス - Single service instance*/ +extern NyLPC_TcMiMicIpNetIf_t* _NyLPC_TcMiMicIpNetIf_inst; + +/** + * サービスが初期化済みならtrueです。 - true if service was initialized. + */ +#define NyLPC_cMiMicIpNetIf_isInitService() (_NyLPC_TcMiMicIpNetIf_inst!=NULL) +/** + * サービスが稼働中か返します。 + */ +#define NyLPC_cMiMicIpNetIf_isRun() NyLPC_TUInt16_isBitOn(_NyLPC_TcMiMicIpNetIf_inst->_status,NyLPC_TcMiMicIpNetIf_STATUSBIT_IS_RUNNING) + + +/********************************************************************** + * コントロールビットの定義 + **********************************************************************/ +//サービスが実行中の場合1 +#define NyLPC_TcMiMicIpNetIf_STATUSBIT_IS_RUNNING 0 +#define NyLPC_TcMiMicIpNetIf_ORDER_START 1 +#define NyLPC_TcMiMicIpNetIf_ORDER_STOP 2 + + + +#define INST_TYPE_NyLPC_Unknown 0 +#define INST_TYPE_NyLPC_TcTcpListener 1 +#define INST_TYPE_NyLPC_TcTcpSocket 2 + + +/********************************************************************** + * + * IPスタックからコールする関数群 + * + **********************************************************************/ + +/** + * NyLPC_cUipService_allocTxBufが返却するメモリサイズ。 + * + */ +#define NyLPC_cMiMicIpNetIf_SYS_TX_BUF_SIZE (64-sizeof(struct NyLPC_TEthernetIIHeader)) + + +/** + * IPv4パケットをネットワークに送信します。 + * この関数は、リエントラントを許容します。 + * @param i_eth_payload + * NyLPC_cUipService_getTxFrame、または、NyLPC_cUipService_recvIPv4Rxで得たバッファに、 + * IPv4パケットを書きこんだものを指定してください。 + */ +void NyLPC_cMiMicIpNetIf_sendIPv4Tx(void* i_eth_payload); + +/** + * 送信ペイロードメモリを返します。 + * この関数は、リエントラントを許容します。 + * @param i_hint + * 取得したいメモリサイズを指定します。(このサイズは、イーサネットヘッダのサイズを含みません。) + * このサイズよりも小さなサイズが割り当てられることがあります。 + * @param o_size + * 取得メモリのイーサネットヘッダを除いたペイロード部分の長さ + * @return + * 成功:IPペイロードのためのメモリブロックを返します。/失敗:NULL + * メモリは、[TEthPacket][payload]の構造で返されます。 + */ +void* NyLPC_cMiMicIpNetIf_allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size); + +/** + * システム用の小さな送信ペイロードメモリを返します。 + * この関数は、リエントラントを許容します。 + * 返却するメモリブロックのサイズが小さいこと、メモリが確実に返される点がNyLPC_cUipService_allocTxBufと異なります。 + * この関数が返すメモリのサイズは、NyLPC_cUipService_SYS_TX_BUF_SIZEの値です。 + * 関数を使用するコードでは開始時に1度だけNyLPC_cUipService_SYS_TX_BUF_SIZEの値を確認して下さい。 + */ +void* NyLPC_cMiMicIpNetIf_allocSysTxBuf(void); + +/** + * allocTxbufで確保したメモリを開放します。 + */ +void* NyLPC_cMiMicIpNetIf_releaseTxBuf(void* i_buf); + +/** + * 指定したIPアドレスを要求するARPリクエストを発行します。 + */ +void NyLPC_cMiMicIpNetIf_sendArpRequest(const struct NyLPC_TIPv4Addr* i_addr); + +/** + * ARPテーブルに指定したIPがあるかを返します。 + */ +NyLPC_TBool NyLPC_cMiMicIpNetIf_hasArpInfo(const struct NyLPC_TIPv4Addr* i_addr); + + +void NyLPC_cMiMicIpNetIf_releaseTcpSocketMemory(const NyLPC_TcMiMicIpTcpSocket_t* i_inst); +void NyLPC_cMiMicIpNetIf_releaseUdpSocketMemory(const NyLPC_TcMiMicIpUdpSocket_t* i_inst); +void NyLPC_cMiMicIpNetIf_releaseTcpListenerMemory(const NyLPC_TcMiMicIpTcpListener_t* i_inst); + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cMiMicIpTcpListener.c Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,227 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + *********************************************************************************/ +#include "NyLPC_cMiMicIpTcpListener_protected.h" +#include "NyLPC_cMiMicIpTcpSocket_protected.h" +#include "NyLPC_cMiMicIpNetIf_protected.h" +#include "../NyLPC_iTcpListener.h" +#include "NyLPC_cIPv4.h" +#include "NyLPC_stdlib.h" + +/** + * NyLPC_TTcpListenerListenQ + */ + +void NyLPC_TTcpListenerListenQ_init(struct NyLPC_TTcpListenerListenQ* i_struct) +{ + i_struct->wp=0; + int i; + for(i=NyLPC_TcMiMicIpTcpListener_NUMBER_OF_Q-1;i>=0;i--){ + i_struct->item[i].rport=0; + } +} + +/** + * ListenQへSYNパケットの情報を追加する。 + */ +void NyLPC_TTcpListenerListenQ_add(struct NyLPC_TTcpListenerListenQ* i_struct,const NyLPC_TcIPv4Payload_t* i_payload) +{ + struct NyLPC_TTcpSocketSynParam* item=&i_struct->item[i_struct->wp]; + //未処理のものがあれば登録しない。 + if(item->rport!=0){ + return; + } + + //SYNリングバッファにセット + item->rport = i_payload->payload.tcp->srcport; + item->srcaddr=i_payload->header->srcipaddr; + item->rcv_nxt32=NyLPC_ntohl(i_payload->payload.tcp->seqno32)+1; + //MSSの設定 + if(!NyLPC_TTcpHeader_getTcpMmsOpt(i_payload->payload.tcp,&item->mss)){ + item->mss=0; + } + //書込み位置の進行 + i_struct->wp=(i_struct->wp+1)%NyLPC_TcMiMicIpTcpListener_NUMBER_OF_Q; +} + +/** + * 最も古いSYNパケット情報のインデクスをキューから返す。 + * @return + * 見つからない場合-1である。 + */ +int NyLPC_TTcpListenerListenQ_getLastIndex(struct NyLPC_TTcpListenerListenQ* i_struct) +{ + int i,t; + //古いものから順に返す + for(i=1;i<=NyLPC_TcMiMicIpTcpListener_NUMBER_OF_Q;i++){ + t=(i_struct->wp+i)%NyLPC_TcMiMicIpTcpListener_NUMBER_OF_Q; + //有効なデータ? + if(i_struct->item[t].rport!=0){ + return t; + } + } + return -1; +} + +/** + * ListenQのN番目を削除する。 + */ +void NyLPC_TTcpListenerListenQ_remove(struct NyLPC_TTcpListenerListenQ* i_struct,int i_idx) +{ + i_struct->item[i_idx].rport=0; + return; +} + + + + + + +//#define lockResource(i_inst) NyLPC_cMutex_lock(((i_inst)->_mutex)) +//#define unlockResource(i_inst) NyLPC_cMutex_unlock(((i_inst)->_mutex)) +#define lockResource(i_inst) NyLPC_cMutex_lock(NyLPC_cIPv4_getListenerMutex(((i_inst)->_super._parent_ipv4))) +#define unlockResource(i_inst) NyLPC_cMutex_unlock(NyLPC_cIPv4_getListenerMutex(((i_inst)->_super._parent_ipv4))) + + +static NyLPC_TBool listen(NyLPC_TiTcpListener_t* i_inst,NyLPC_TiTcpSocket_t* i_sock,NyLPC_TUInt32 i_wait_msec); +static void finaize(NyLPC_TiTcpListener_t* i_inst); + +const static struct NyLPC_TiTcpListener_Interface interface= +{ + listen, + finaize +}; + +/** + * uipサービスが稼働中にのみ機能します。 + */ +NyLPC_TBool NyLPC_cMiMicIpTcpListener_initialize(NyLPC_TcMiMicIpTcpListener_t* i_inst,NyLPC_TUInt16 i_port) +{ + NyLPC_TcMiMicIpNetIf_t* srv=_NyLPC_TcMiMicIpNetIf_inst; + i_inst->_super._super.tcp_listener._interface=&interface; + NyLPC_cMiMicIpBaseSocket_initialize(&(i_inst->_super),NyLPC_TcMiMicIpBaseSocket_TYPEID_TCP_LISTENER); + NyLPC_TTcpListenerListenQ_init(&i_inst->_listen_q); + //uipサービスは初期化済であること。 + NyLPC_Assert(NyLPC_cMiMicIpNetIf_isInitService()); + //初期化 +// // NyLPC_cMutex_initialize(&(i_inst->_mutex)); +// i_inst->_mutex=NyLPC_cIPv4_getListenerMutex(&srv->_tcpv4);// NyLPC_cMutex_initialize(&(i_inst->_mutex)); + i_inst->_port=NyLPC_htons(i_port); + //管理リストへ登録。 + return NyLPC_cIPv4_addSocket(&(srv->_tcpv4),&(i_inst->_super)); +} + + + +static void finaize(NyLPC_TiTcpListener_t* i_inst) +{ + NyLPC_TcMiMicIpNetIf_t* srv=_NyLPC_TcMiMicIpNetIf_inst; + NyLPC_Assert(NyLPC_cMiMicIpNetIf_isInitService()); + //uipサービスは初期化済であること。 + if(!NyLPC_cIPv4_removeSocket(&(srv->_tcpv4),&(((NyLPC_TcMiMicIpTcpListener_t*)i_inst)->_super))){ + //削除失敗、それは死を意味する。 + NyLPC_Abort(); + } + NyLPC_cMiMicIpBaseSocket_finalize(&(((NyLPC_TcMiMicIpTcpListener_t*)i_inst)->_super)); + NyLPC_cMiMicIpNetIf_releaseTcpListenerMemory((NyLPC_TcMiMicIpTcpListener_t*)i_inst); + return; +} + + +static NyLPC_TBool listen(NyLPC_TiTcpListener_t* i_inst,NyLPC_TiTcpSocket_t* i_sock,NyLPC_TUInt32 i_wait_msec) +{ + int qi; + NyLPC_TcMiMicIpTcpListener_t* inst=(NyLPC_TcMiMicIpTcpListener_t*)i_inst; + NyLPC_TcStopwatch_t sw; + NyLPC_TBool ret=NyLPC_TBool_FALSE; + //サービスは稼働中であること。 + NyLPC_Assert(NyLPC_cMiMicIpNetIf_isRun()); + + //入力ソケットはCLOSEDであること。 + if(((NyLPC_TcMiMicIpTcpSocket_t*)i_sock)->tcpstateflags!=UIP_CLOSED){ + return NyLPC_TBool_FALSE; + } + + //ストップウォッチを起動 + NyLPC_cStopwatch_initialize(&sw); + NyLPC_cStopwatch_setNow(&sw); + + + //Listenerのリソースロック + lockResource(inst); + + while(NyLPC_cStopwatch_elapseInMsec(&sw)<i_wait_msec){ + qi=NyLPC_TTcpListenerListenQ_getLastIndex(&inst->_listen_q); + if(qi>=0){ + //SYN処理要求がある + if(!NyLPC_cMiMicIpTcpSocket_listenSyn(((NyLPC_TcMiMicIpTcpSocket_t*)i_sock),&inst->_listen_q.item[qi],inst->_port)){ + ret=NyLPC_TBool_FALSE; + }else{ + //成功 + ret=NyLPC_TBool_TRUE; + } + //処理したSYNの削除 + NyLPC_TTcpListenerListenQ_remove(&inst->_listen_q,qi); + break; + }else{ + //SYN処理要求は無い(しばらくまつ) + unlockResource(inst); + NyLPC_cThread_yield(); + lockResource(inst); + } + } + //タイムアウト + unlockResource(inst); + NyLPC_cStopwatch_finalize(&sw); + return ret; +} + +/** + * この関数は、Uip受信タスクから実行します。 + */ +NyLPC_TBool NyLPC_cMiMicIpTcpListener_synPacket(NyLPC_TcMiMicIpTcpListener_t* i_inst,const NyLPC_TcIPv4Payload_t* i_payload) +{ + //パケットチェック。SYN設定されてる? + if(!(i_payload->payload.tcp->flags & TCP_SYN)){ + //SYNない + return NyLPC_TBool_FALSE; + } + //peer port==0は受け取らない。 + if(i_payload->payload.tcp->srcport==0){ + return NyLPC_TBool_FALSE; + } + //Listenerのリソースロック + lockResource(i_inst); + //ListenQへ追加 + NyLPC_TTcpListenerListenQ_add(&(i_inst->_listen_q),i_payload); + //Listenerのリソースアンロック + unlockResource(i_inst); + return NyLPC_TBool_TRUE; +} + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cMiMicIpTcpListener.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,98 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + *********************************************************************************/ +#ifndef NYLPC_CTCPLISTENER_H_ +#define NYLPC_CTCPLISTENER_H_ + + +#include "NyLPC_stdlib.h" +#include "NyLPC_os.h" +#include "NyLPC_cMiMicIpBaseSocket.h" +#include "NyLPC_cMiMicIpTcpSocket.h" +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct NyLPC_TcMiMicIpTcpListener NyLPC_TcMiMicIpTcpListener_t; + +/********************************************************************** + * + * NyLPC_TTcpListenerListenQ struct + * + **********************************************************************/ + +#define NyLPC_TcMiMicIpTcpListener_NUMBER_OF_Q 10 + +struct NyLPC_TTcpListenerListenQ +{ + struct NyLPC_TTcpSocketSynParam item[NyLPC_TcMiMicIpTcpListener_NUMBER_OF_Q]; + NyLPC_TUInt16 wp; +}; + + +/********************************************************************** + * + * NyLPC_TcTcpListener class + * + **********************************************************************/ + +/** + * TCP listenerクラス型です。 + */ +struct NyLPC_TcMiMicIpTcpListener +{ + NyLPC_TcMiMicIpBaseSocket_t _super; + NyLPC_TUInt16 _port; /**<ネットワークオーダーのポート番号*/ +// /** +// * タスク間の調停用Mutex +// * Listener用の共通Mutexポインタ +// */ +// NyLPC_TcMutex_t* _mutex; + /** + * SYNパケットのキュー + */ + struct NyLPC_TTcpListenerListenQ _listen_q; +}; +/** + * この関数は、TCPのリスナーを初期化します。 + * 初期化したリスナーをサービスに登録することにより、listen関数を使用できるようになります。 + * サービスへの登録は、NyLPC_cUipService_addListenerを使います。 + * @param i_port + * ポート番号。host orderです。 + */ +NyLPC_TBool NyLPC_cMiMicIpTcpListener_initialize(NyLPC_TcMiMicIpTcpListener_t* i_inst,NyLPC_TUInt16 i_port); + +/** + * この関数は、一定時間i_sockに接続を受け付けます。 + */ +NyLPC_TBool NyLPC_cMiMicIpTcpListener_listen(NyLPC_TcMiMicIpTcpListener_t* i_inst,NyLPC_TcMiMicIpTcpSocket_t* i_sock,NyLPC_TUInt32 i_wait_msec); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* NYLPC_CTCPLISTENER_H_ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cMiMicIpTcpListener_protected.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,49 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + *********************************************************************************/ +#ifndef NYLPC_CTCPLISTENER_PROTECTED_H_ +#define NYLPC_CTCPLISTENER_PROTECTED_H_ +#include "NyLPC_cMiMicIpTcpListener.h" +#include "NyLPC_cMiMicIpNetIf_protected.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + + +/** + * ListenerへSYNパケットを通知します。 + * @return + * 常にTRUE + */ +NyLPC_TBool NyLPC_cMiMicIpTcpListener_synPacket(NyLPC_TcMiMicIpTcpListener_t* i_inst,const NyLPC_TcIPv4Payload_t* i_payload); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* NYLPC_CTCPLISTENER_PROTECTED_H_ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cMiMicIpTcpSocket.c Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,1548 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + *********************************************************************************/ +#include "NyLPC_cMiMicIpTcpSocket_protected.h" +#include "NyLPC_stdlib.h" +#include "NyLPC_cMiMicIpNetIf_protected.h" + + +static NyLPC_TUInt32 iss32=3939; +#define SIZE_OF_IPv4_TCPIP_HEADER 40 + +/** + * TCPのRTOの最大値。 + * ms単位である。 + * defaultは64SEC + */ +#define UIP_IP_RTO_MAX_RTO 64000 +/** + * TCPのRTOの初期値。 + * ms単位である。 + * 伝送路の特性に合わせて調整すること。 + */ +#define UIP_TCP_RTO_INITIAL 3000 + +/** + * CONNECTION時のRTO + */ +#define UIP_TCP_RTO_CONNECTION_INITIAL 200 + +/** + * 下限値 + */ +#define UIP_TCP_RTO_MINIMUM 100 + + +/** + * for Debug + * RTOの情報をログ領域に取る。 + */ +#ifdef RTO_LOG + NyLPC_TUInt32 rto_log[256]; + int rto_log_st=0; + #define DEBUG_RTO_LOG(i_inst) if(rto_log_st<256){rto_log[rto_log_st++]=i_inst->uip_connr.current_rto32;}; +#else + #define DEBUG_RTO_LOG(i_inst) +#endif + +//#define lockResource(i_inst) NyLPC_cMutex_lock(&((i_inst)->_smutex)) +//#define unlockResource(i_inst) NyLPC_cMutex_unlock(&((i_inst)->_smutex)) +#define lockResource(i_inst) NyLPC_cMutex_lock(NyLPC_cIPv4_getSockMutex(((i_inst)->_super._parent_ipv4))) +#define unlockResource(i_inst) NyLPC_cMutex_unlock(NyLPC_cIPv4_getSockMutex(((i_inst)->_super._parent_ipv4))) + +static void sendRst(NyLPC_TcMiMicIpTcpSocket_t* i_inst); + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Packet writer +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + + +/** + * TCPヘッダに値をセットする。checksum,wndは0初期化する。 + */ +static void setTcpTxHeader(struct NyLPC_TTcpHeader* i_struct,NyLPC_TUInt8 i_flag,const struct uip_conn* i_conn) +{ + i_struct->flags = i_flag; + //sorce & destination port + i_struct->srcport = i_conn->lport; + i_struct->destport = i_conn->rport; + //ACK number + i_struct->ackno32 = NyLPC_htonl(i_conn->rcv_nxt32); + //Seq Number + i_struct->seqno32 = NyLPC_htonl(i_conn->snd_nxt32); + //uip_func_tcp_send_noconn(BUF); + i_struct->urgp[0] = i_struct->urgp[1] = 0; + i_struct->tcpchksum= 0; +} + +static void setTxPacket(const NyLPC_TcMiMicIpTcpSocket_t* i_inst,void* i_tx_buf,NyLPC_TUInt8 i_tcpf,const void* i_buf,NyLPC_TUInt16 i_len) +{ + struct NyLPC_TIPv4Header* iph; + struct NyLPC_TTcpHeader* tcph; + NyLPC_TUInt8 iph_word=0x05; + NyLPC_TUInt8 tcph_word=(UIP_TCPH_LEN) / 4; + //IPヘッダの更新 + iph=(struct NyLPC_TIPv4Header*)i_tx_buf; + iph->vhl=0x40|(0x0f&iph_word); + iph->destipaddr=i_inst->uip_connr.ripaddr; + iph->srcipaddr =*(i_inst->uip_connr.lipaddr); + NyLPC_TIPv4Header_writeTxIpHeader(iph,UIP_PROTO_TCP); + //TCPヘッダの更新 + tcph=(struct NyLPC_TTcpHeader*)(((NyLPC_TUInt8*)i_tx_buf)+NyLPC_TIPv4Header_getHeaderLength(iph)); + + + //SYNが有るならMSSの書き込み + if((TCP_SYN & i_tcpf)){ + tcph_word+=((TCP_OPT_MSS_LEN) / 4); + NyLPC_TTcpHeader_setMmsOpt(((NyLPC_TUInt8*)(tcph+1)),i_inst->uip_connr.default_mss); + } + tcph->tcpoffset=(tcph_word<<4); + setTcpTxHeader(tcph,i_tcpf,&(i_inst->uip_connr)); + + //最終的なパケットサイズと必要ならペイロードを書き込み + if(i_buf!=NULL){ + iph->len16=NyLPC_htons(i_len+(iph_word+tcph_word)*4); + memcpy(((NyLPC_TUInt8*)i_tx_buf)+((iph_word+tcph_word)*4),i_buf,i_len); + }else{ + iph->len16=NyLPC_htons((iph_word+tcph_word)*4); + } + //WND設定 + tcph->wnd16=NyLPC_htons(NyLPC_cFifoBuffer_getSpace(&(i_inst->rxbuf))); + //Checksumの生成 + tcph->tcpchksum=~(NyLPC_TIPv4Header_makeTcpChecksum(iph)); + iph->ipchksum = ~(NyLPC_TIPv4Header_makeIpChecksum(iph)); + return; +} + +/** + * IP/TCPヘッダが40バイト固定として、i_tx_buf+40の位置にあるペイロードに対するIP/TCPヘッダを書き込みます。 + */ +static void setTxPacketHeader(const NyLPC_TcMiMicIpTcpSocket_t* i_inst,void* i_tx_buf,NyLPC_TUInt8 i_tcpf,NyLPC_TUInt16 i_len) +{ + struct NyLPC_TIPv4Header* iph; + struct NyLPC_TTcpHeader* tcph; + NyLPC_TUInt8 iph_word=0x05; + NyLPC_TUInt8 tcph_word=(UIP_TCPH_LEN) / 4; + //IPヘッダの更新 + iph=(struct NyLPC_TIPv4Header*)i_tx_buf; + iph->vhl=0x40|(0x0f&iph_word); + iph->destipaddr=i_inst->uip_connr.ripaddr; + iph->srcipaddr =*(i_inst->uip_connr.lipaddr); + NyLPC_TIPv4Header_writeTxIpHeader(iph,UIP_PROTO_TCP); + + //TCPヘッダの更新 + tcph=(struct NyLPC_TTcpHeader*)(((NyLPC_TUInt8*)i_tx_buf)+NyLPC_TIPv4Header_getHeaderLength(iph)); + tcph->tcpoffset=(tcph_word<<4); + setTcpTxHeader(tcph,i_tcpf,&(i_inst->uip_connr)); + + //最終的なパケットサイズと必要ならペイロードを書き込み + iph->len16=NyLPC_htons(i_len+(iph_word+tcph_word)*4); + //WND設定 + tcph->wnd16=NyLPC_htons(NyLPC_cFifoBuffer_getSpace(&(i_inst->rxbuf))); + //Checksumの生成 + tcph->tcpchksum=~(NyLPC_TIPv4Header_makeTcpChecksum(iph)); + iph->ipchksum = ~(NyLPC_TIPv4Header_makeIpChecksum(iph)); + return; +} + + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Mainclass::private +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * ACK番号を更新する。 + * @param i_ackno + * ネットワークオーダーのACK番号 + */ +static void updateAckNo(void* i_tx_buf,NyLPC_TUInt32 i_ackno) +{ + struct NyLPC_TIPv4Header* iph=(struct NyLPC_TIPv4Header*)i_tx_buf; + struct NyLPC_TTcpHeader* tcph=(struct NyLPC_TTcpHeader*)(((NyLPC_TUInt8*)i_tx_buf)+NyLPC_TIPv4Header_getHeaderLength(iph)); + +/* union{ + NyLPC_TUInt32 l; + NyLPC_TUInt8 b[4]; + }old_ack,new_ack; + NyLPC_TUInt16 v1; + //checksumの計算 + old_ack.l=i_inst->payload.tcp->ackno32;//古いACK番号 + new_ack.l=i_ackno;//新しいACK番号 + v1=NyLPC_ntohs(~(i_inst->payload.tcp->tcpchksum));//1の補数を取って、ホストオーダーに戻す。 + //減算 + v1=sub16c(v1,(old_ack.b[0]<<8)+old_ack.b[1]); + v1=sub16c(v1,(old_ack.b[2]<<8)+old_ack.b[3]); + //加算 + v1=add16c(v1,(new_ack.b[0]<<8)+new_ack.b[1]); + v1=add16c(v1,(new_ack.b[2]<<8)+new_ack.b[3]); + v1=~NyLPC_htons(v1);*/ +NyLPC_Trace(); + tcph->ackno32=i_ackno; +NyLPC_Trace(); + tcph->tcpchksum = 0; +NyLPC_Trace(); + tcph->tcpchksum = ~(NyLPC_TIPv4Header_makeTcpChecksum(iph)); +NyLPC_Trace(); + +/* + if((i_inst->payload.tcp->tcpchksum!=v1)){ + NyLPC_Warning(); + }*/ +} + + + +/** + * 指定した送信パケットがACK済であるか調べる。 + */ +static NyLPC_TBool isPacketAcked(NyLPC_TcMiMicIpTcpSocket_t* i_inst,NyLPC_TUInt32 i_sq) +{ + int rp; + struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; + rp=i_inst->txbuf.rp; + while(rp!=i_inst->txbuf.wp){ + if(q[rp].ackno==i_sq){ + return NyLPC_TBool_FALSE; + } + rp=(rp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; + } + return NyLPC_TBool_TRUE; +} +/** + * 送信キューからi_sq以前に送信したパケットを除外して、残り個数を返却する。 + */ +static int getNumOfSending(NyLPC_TcMiMicIpTcpSocket_t* i_inst,NyLPC_TUInt32 i_sq) +{ + int rp,n; + struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; + rp=i_inst->txbuf.rp; + n=0; + while(rp!=i_inst->txbuf.wp){ + if(q[rp].ackno==i_sq){ + return n; + } + n++; + rp=(rp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; + } + return n; +} +/** + * この関数は、コネクションをリセットします。 + * ロック状態でコールしてください。 + * 関数は、現在バッファにある再送信待ちデータを開放します。 + */ +static void resetTxQWithUnlock(NyLPC_TcMiMicIpTcpSocket_t* i_inst) +{ + int i,l; + struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; + void* dlist[NyLPC_TcTcpSocket_NUMBER_OF_TXQ]; + + l=0; + while(i_inst->txbuf.rp!=i_inst->txbuf.wp){ + dlist[l]=q[i_inst->txbuf.rp].packet; + l++; + i_inst->txbuf.rp=(i_inst->txbuf.rp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; + } + i_inst->txbuf.rp=i_inst->txbuf.wp=0; + //ロック解除 + unlockResource(i_inst); + //セーブしたバッファを開放 + for(i=0;i<l;i++){ + NyLPC_cMiMicIpNetIf_releaseTxBuf(dlist[i]); + } + return; +} +/** + * TXバッファの再送パケットのACK番号を更新します。 + * ロックして実行してください。 + * @param i_ackno + * ネットワークオーダーのACK番号 + */ +static void updateTxAck(NyLPC_TcMiMicIpTcpSocket_t* i_inst,NyLPC_TUInt32 i_ackno) +{ + NyLPC_TUInt8 rp; + struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; + NyLPC_ArgAssert(i_inst!=NULL); + rp=i_inst->txbuf.rp; + while(rp!=i_inst->txbuf.wp){ + updateAckNo(q[rp].packet,i_ackno); + rp=(rp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; + } +} + +/** + * RTOの予測関数 + */ +static void estimateRTO(NyLPC_TcMiMicIpTcpSocket_t* i_inst,int s,int n) +{ + NyLPC_TcStopwatch_t sw; + NyLPC_TUInt32 cr_rtt_min,cr_rtt_max,sk_rto,new_rto,w; + int i; + struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; + NyLPC_cStopwatch_initialize(&sw); + + sk_rto=i_inst->uip_connr.current_rto32; + //ACKされたパケットの個数は? + switch(n){ + case 1: + NyLPC_cStopwatch_set(&sw,q[s].tick_of_sent); + cr_rtt_min=NyLPC_cStopwatch_elapseInMsec(&sw); + if(sk_rto<cr_rtt_min){ + //現在のRTOよりも大きい→再送があった。(再送の理由が回線遅延によるものかわからないので、基本RTOを25%増やす。) + new_rto=sk_rto*10/8; + }else if(sk_rto/4<cr_rtt_min){ + //現在のRTOの1/4< n < 現在のRTO 想定内の変動。1/8 + new_rto=(sk_rto+(cr_rtt_min*3*7))/8; + }else{ + //現在の1/4以下。RTOを再計算。 RTOが大きすぎるので再計算。(計測値を優先した現在値との平均値) + new_rto=(sk_rto+(cr_rtt_min*3*3))/4; + } + break; + default: + //複数のパケットなら、最大と最小の時刻を得る。 + NyLPC_cStopwatch_set(&sw,q[s].tick_of_sent); + cr_rtt_min=cr_rtt_max=NyLPC_cStopwatch_elapseInMsec(&sw); + for(i=1;i<n;i++){ + NyLPC_cStopwatch_set(&sw,q[(s+i)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ].tick_of_sent); + w=NyLPC_cStopwatch_elapseInMsec(&sw); + if(cr_rtt_min>w){ + cr_rtt_min=w; + } + if(cr_rtt_max<w){ + cr_rtt_max=w; + } + } + if(sk_rto<cr_rtt_min && sk_rto<cr_rtt_max){ + //最大値,最小値とも現在のRTTより大きい→低速な回線を検出。 + new_rto=cr_rtt_max*10/8;//最大経過時間の25%増しの時間を設定。 + }else if(sk_rto/4<cr_rtt_min){ + //現在のRTOの1/4< n < 現在のRTO 想定範囲内。1/8の加重平均で速度計算。 + new_rto=(sk_rto+(cr_rtt_min*3*7))/8; + }else{ + //現在の1/4以下。RTOが大きすぎるので再計算。(計測値を優先した加重平均) + new_rto=(sk_rto+(cr_rtt_min*3*3))/4; + } + break; + } + NyLPC_cStopwatch_finalize(&sw); + if(new_rto<UIP_TCP_RTO_MINIMUM){ + new_rto=UIP_TCP_RTO_MINIMUM; + } + i_inst->uip_connr.current_rto32=new_rto; +} + +/** + * TXキューから、入力されたシーケンス番号より前のパケットを除外します。 + * リングバッファのrp->wp-1までをチェックして、sqに等しいi_sq以前のパケットバッファをo_dlistへ返します。 + * + */ +static int updateTxQByIndex(NyLPC_TcMiMicIpTcpSocket_t* i_inst,NyLPC_TUInt32 i_sq,void* o_dlist[]) +{ + int rp,n; + struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; + //ロック状態なう + rp=i_inst->txbuf.rp; + n=0; + //This is debug + DEBUG_RTO_LOG(i_inst); + + while(rp!=i_inst->txbuf.wp){ + o_dlist[n]=q[rp].packet; + if(q[rp].ackno==i_sq){ + //i_inst->txbuf.rp->rpのパケットのRTOからbaseRTOの値を再計算。 + estimateRTO(i_inst,i_inst->txbuf.rp,n+1); + i_inst->txbuf.rp=(rp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; + return n+1; + } + n++; + rp=(rp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; + } + return 0; +} + + + +/** + * 空きキューを1個返します。 + * 空きキューの + */ +static struct NyLPC_TcTcpSocket_TxQItem* getTxQ(NyLPC_TcMiMicIpTcpSocket_t* i_inst,NyLPC_TcStopwatch_t* i_timer) +{ + int i; + struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; + do{ + //クローズドに遷移してしまったら、エラーである。 + if(i_inst->tcpstateflags==UIP_CLOSED){ + return NULL; + } + //キューの空きをチェック。wp+1==rpなら、キューがいっぱい。rp==wpなら、キューが空。 + if(((i_inst->txbuf.wp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ)==i_inst->txbuf.rp){ + //一時的なアンロック + unlockResource(i_inst); + //タスクスイッチ + NyLPC_cThread_yield(); + //ロック + lockResource(i_inst); + continue; + } + i=i_inst->txbuf.wp; + i_inst->txbuf.wp=(i+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; + return &(q[i]); + }while(!NyLPC_cStopwatch_isExpired(i_timer)); + //失敗。タイムアウト。 + return NULL; +} + + + + + + +/********************************************************************** + * public 関数 + **********************************************************************/ +static const struct NyLPC_TIPv4Addr* getPeerAddr(const NyLPC_TiTcpSocket_t* i_inst); +static NyLPC_TUInt16 getPeerPort(const NyLPC_TiTcpSocket_t* i_inst); +static NyLPC_TBool accept(NyLPC_TiTcpSocket_t* i_inst,NyLPC_TUInt32 i_wait_in_msec); +static NyLPC_TInt32 precv(NyLPC_TiTcpSocket_t* i_inst,const void** o_buf_ptr,NyLPC_TUInt32 i_wait_msec); +static void pseek(NyLPC_TiTcpSocket_t* i_inst,NyLPC_TUInt16 i_seek); +static NyLPC_TInt32 send(NyLPC_TiTcpSocket_t* i_inst,const void* i_buf_ptr,NyLPC_TInt32 i_len,NyLPC_TUInt32 i_wait_in_msec); +static void close(NyLPC_TiTcpSocket_t* i_inst,NyLPC_TUInt32 i_wait_in_msec); +static void* allocSendBuf(NyLPC_TiTcpSocket_t* i_inst,NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_buf_size,NyLPC_TUInt32 i_wait_in_msec); +static void releaseSendBuf(NyLPC_TiTcpSocket_t* i_inst,void* i_buf_ptr); +static NyLPC_TBool psend(NyLPC_TiTcpSocket_t* i_inst,void* i_buf_ptr,int i_len,NyLPC_TUInt32 i_wait_in_msec); +static NyLPC_TBool connect(NyLPC_TiTcpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_peer_port,NyLPC_TUInt32 i_wait_in_msec); +static void finalize(NyLPC_TiTcpSocket_t* i_inst); + +const static struct NyLPC_TiTcpSocket_Interface _interface= +{ + getPeerAddr, + getPeerPort, + accept, + precv, + pseek, + send, + close, + allocSendBuf, + releaseSendBuf, + psend, + connect, + finalize +}; + +static const struct NyLPC_TIPv4Addr* getPeerAddr(const NyLPC_TiTcpSocket_t* i_inst) +{ + const NyLPC_TcMiMicIpTcpSocket_t* inst=(const NyLPC_TcMiMicIpTcpSocket_t*)i_inst; + return &inst->uip_connr.ripaddr; +} +static NyLPC_TUInt16 getPeerPort(const NyLPC_TiTcpSocket_t* i_inst) +{ + const NyLPC_TcMiMicIpTcpSocket_t* inst=(const NyLPC_TcMiMicIpTcpSocket_t*)i_inst; + return inst->uip_connr.rport; +} + + + + +NyLPC_TBool NyLPC_cMiMicIpTcpSocket_initialize(NyLPC_TcMiMicIpTcpSocket_t* i_inst,void* i_rbuf,NyLPC_TUInt16 i_rbuf_len) +{ + int i; + NyLPC_TcMiMicIpNetIf_t* srv=_NyLPC_TcMiMicIpNetIf_inst; + i_inst->_super._super.tcp_sock._interface=&_interface; + NyLPC_cMiMicIpBaseSocket_initialize(&(i_inst->_super),NyLPC_TcMiMicIpBaseSocket_TYPEID_TCP_SOCK); + //uipサービスは初期化済であること。 + NyLPC_Assert(NyLPC_cMiMicIpNetIf_isInitService()); + + NyLPC_cFifoBuffer_initialize(&(i_inst->rxbuf),i_rbuf,i_rbuf_len); + // NyLPC_AbortIfNot(NyLPC_cMutex_initialize(&(i_inst->_smutex)));//個別Mutex +// i_inst->_smutex=NyLPC_cIPv4_getSockMutex(&(srv->_tcpv4));//共有Mutex + i_inst->tcpstateflags=UIP_CLOSED; + i_inst->txbuf.rp=i_inst->txbuf.wp=0; + for(i=0;i<NyLPC_TcTcpSocket_NUMBER_OF_TXQ;i++){ + i_inst->txbuf.txq[i].packet=NULL; + } + //管理リストへ登録。 + return NyLPC_cIPv4_addSocket(&(srv->_tcpv4),&(i_inst->_super)); +} + + + +NyLPC_TBool NyLPC_cMiMicIpTcpSocket_listenSyn(NyLPC_TcMiMicIpTcpSocket_t* i_inst,const struct NyLPC_TTcpSocketSynParam* i_lq,NyLPC_TUInt16 i_lport) +{ +// NyLPC_Assert(NyLPC_cMutex_isLocked(i_inst->_smutex)); + lockResource(i_inst); + //ソケットが無効であること。 + if(i_inst->tcpstateflags==UIP_CLOSED) + { + //localipとdefault_mmsは別枠で設定 + /* Fill in the necessary fields for the new connection. */ + i_inst->uip_connr.current_rto32 = UIP_TCP_RTO_INITIAL; + i_inst->uip_connr.lport = i_lport; + i_inst->uip_connr.rport = i_lq->rport; + i_inst->uip_connr.ripaddr=i_lq->srcaddr; + i_inst->uip_connr.snd_nxt32=iss32; + /* rcv_nxt should be the seqno from the incoming packet + 1. */ + i_inst->uip_connr.rcv_nxt32= i_lq->rcv_nxt32; + //MSSの設定 + i_inst->uip_connr.peer_mss=(i_lq->mss!=0)?i_lq->mss:i_inst->uip_connr.default_mss; + i_inst->uip_connr.peer_win=0; + NyLPC_cFifoBuffer_clear(&(i_inst->rxbuf)); + //ここでステータスがかわる。 + i_inst->tcpstateflags = UIP_SYN_RCVD; + //前回のデータが残っていた場合の保険 + if(i_inst->txbuf.rp!=i_inst->txbuf.wp){ + resetTxQWithUnlock(i_inst); + }else{ + unlockResource(i_inst); + } + return NyLPC_TBool_TRUE; + } + unlockResource(i_inst); + return NyLPC_TBool_FALSE; +} + + +/** + * sq番のTxがキューから消え去るのを待ちます。 + * この関数は、アンロック状態でコールしてください。 + * <div> + * パケットがキューからなくなる条件は、以下の2つです。 + * <ul> + * <li>ACKを受信してパケットキューが更新された。</li> + * <li>RSTを受信して(CLOSEDに遷移して)、キューがクリアされた。</li> + * <li>送信タイムアウトで関数が(CLOSEDに遷移させて)キューをクリアした。</li> + * </ul> + * </div> + * @param i_wait_msec + * @return + * 1番目の条件でパケットが消失したときのみ、TRUEを返します。 + * 失敗した場合、TCPステータスがCLOSEDでなければ、RSTを送信してステータスをCLOSEDにします。 + */ +static NyLPC_TBool waitForTxRemove(NyLPC_TcMiMicIpTcpSocket_t* i_inst,NyLPC_TUInt32 i_sq,NyLPC_TcStopwatch_t* i_timer) +{ + NyLPC_TUInt8 f; + lockResource(i_inst); + do{ + //パケットが送信中か調べる。 + if(!isPacketAcked(i_inst,i_sq)){ + //まだある場合は、タスクスイッチを繰り返して消失を待つ。 + unlockResource(i_inst); + NyLPC_cThread_yield(); + lockResource(i_inst); + continue; + } + //なくなった場合は、原因を調べる。 + f=i_inst->tcpstateflags; + unlockResource(i_inst); + return (f==UIP_CLOSED)?NyLPC_TBool_FALSE:NyLPC_TBool_TRUE; + }while(!NyLPC_cStopwatch_isExpired(i_timer)); + unlockResource(i_inst); + return NyLPC_TBool_FALSE; +} + + +/** + * 再送信処理をセットして、パケットを送信します。 + * この関数は「アンロック状態で」実行してください。 + * @param i_len + * 送信データサイズを指定します。 + * この番号は、シーケンス番号の加算値ではありませんので、注意をしてください。 + * @return + * <ul> + * <li>n=-1:送信キューへの投入に失敗した。</li> + * <li>n>=0:nバイトのデータを送信キューへの投入することに成功した。</li> + * </ul> + * 送信キューに失敗する理由は2つあります。1つは、TXバッファがフルでタイムアウト。もうひとつは、非同期なコネクリョンのリセットです。 + * 失敗した場合、TCPステータスがCLOSEDでなければ、RSTを送信してステータスをCLOSEDにします。 + */ +static NyLPC_TInt32 sendWithRetransmit(NyLPC_TcMiMicIpTcpSocket_t* i_inst,NyLPC_TUInt8 i_tcpf,const void* i_buf,NyLPC_TUInt16 i_len,NyLPC_TcStopwatch_t* i_timer,NyLPC_TUInt32* o_ack) +{ + struct NyLPC_TcTcpSocket_TxQItem* txq; + NyLPC_TUInt16 s; + void* buf; + NyLPC_TUInt32 next_ack; + //送信バッファを取得 + //@bug オブションパケット送信時に4バイト足りないメモリ要求しない?問題になってないけど。 + for(;;){ + buf=NyLPC_cMiMicIpNetIf_allocTxBuf(i_len+(SIZE_OF_IPv4_TCPIP_HEADER),&s); + if(buf!=NULL){ + break; + } + //タイムアウト確認 + if(NyLPC_cStopwatch_isExpired(i_timer)){ + return -1; + } + }; + lockResource(i_inst); + //ペイロードがある場合のみ、相手のwindowサイズが0以上になるのを待つ。 + if(i_len>0){ + while(i_inst->uip_connr.peer_win==0){ + unlockResource(i_inst); + //時間切れならエラー。 + if(NyLPC_cStopwatch_isExpired(i_timer)){ + return -1; + } + NyLPC_cThread_yield(); + lockResource(i_inst); + } + } + //送信キューの取得 + txq=getTxQ(i_inst,i_timer); + //送信キューが取れなかった。 + if(txq==NULL){ + //シーケンス番号をロールバックできないので、エラーとする。 + unlockResource(i_inst); + NyLPC_cMiMicIpNetIf_releaseTxBuf(buf); + return -1; + } + + //送信バッファを基準とした送信サイズを計算 + s-=SIZE_OF_IPv4_TCPIP_HEADER; + //送信サイズよりMMSが小さければ、送信サイズを修正 + if(i_inst->uip_connr.peer_mss<s){ + s=i_inst->uip_connr.peer_mss; + } + //送信サイズよりpeerのウインドウサイズが小さければ修正 + if(i_inst->uip_connr.peer_win<s){ + s=i_inst->uip_connr.peer_win; + } + //送信サイズより、データサイズが小さければ、送信サイズを修正 + if(i_len<s){ + s=i_len; + } + //ACK番号の計算 + next_ack=i_inst->uip_connr.snd_nxt32+s+(((i_tcpf&(TCP_FIN|TCP_SYN))!=0x00)?1:0); + txq->rto32=i_inst->uip_connr.current_rto32; + txq->tick_of_sent=NyLPC_cStopwatch_now(); + + //パケットの書き込み + setTxPacket(i_inst,buf,i_tcpf,i_buf,s); + txq->packet=buf; + + //シーケンス番号の更新 + i_inst->uip_connr.snd_nxt32=next_ack; + //Peerのウインドウサイズを更新 + i_inst->uip_connr.peer_win-=s; + //ACK番号の返却 + *o_ack=txq->ackno=NyLPC_HTONL(next_ack); + unlockResource(i_inst); + NyLPC_cMiMicIpNetIf_sendIPv4Tx(buf); + return s; +} +/** + * RSTを1フレームだけ送信します。 + * この関数は、クローズドステータスのソケットにしてからコールします。 + * この関数は、アンロック状態でコールしてね。 + */ +static void sendRst(NyLPC_TcMiMicIpTcpSocket_t* i_inst) +{ + void* buf; + + NyLPC_Assert(i_inst->tcpstateflags==UIP_CLOSED); + //ペイロードライタの初期化 + + //@bug バッファが取れるまで通信がブロックするの。ここはなんとかしないと。 + buf=NyLPC_cMiMicIpNetIf_allocSysTxBuf(); + lockResource(i_inst); + i_inst->uip_connr.snd_nxt32++; + unlockResource(i_inst); + setTxPacket(i_inst,buf,TCP_RST|TCP_ACK,NULL,0); + NyLPC_cMiMicIpNetIf_sendIPv4Tx(buf); + NyLPC_cMiMicIpNetIf_releaseTxBuf(buf); + NyLPC_cIPv4Payload_finalize(&ipv4); + return; +} + + + +/** + * 受信データをバッファに書き込む。 + * 十分な空き領域がない場合、失敗する。 + * この関数は、ロックして実行してください。 + */ +static NyLPC_TBool addRecvData(NyLPC_TcMiMicIpTcpSocket_t* i_inst,const void* i_data,NyLPC_TUInt16 i_data_size) +{ + //受信データサイズを確認 + if(NyLPC_cFifoBuffer_getSpace(&(i_inst->rxbuf))>=i_data_size){ + //バッファに格納可能なら、格納。 + NyLPC_cFifoBuffer_push(&(i_inst->rxbuf),i_data,i_data_size); + }else{ + //エラー:ドロップする。 + return NyLPC_TBool_FALSE; + } + + return NyLPC_TBool_TRUE; +} + + + + + +/** + * Public function + */ +static void finalize(NyLPC_TiTcpSocket_t* i_inst) +{ + int i; + NyLPC_TcMiMicIpTcpSocket_t* inst=(NyLPC_TcMiMicIpTcpSocket_t*)i_inst; + NyLPC_Assert(NyLPC_cMiMicIpNetIf_isInitService()); + //uipサービスは初期化済であること。 + if(!NyLPC_cIPv4_removeSocket(&(_NyLPC_TcMiMicIpNetIf_inst->_tcpv4),&(inst->_super))){ + //削除失敗、それは死を意味する。 + NyLPC_Abort(); + } + //開放漏れの保険 + if(inst->txbuf.rp!=inst->txbuf.wp){ + lockResource(inst); + resetTxQWithUnlock(inst); + } + for(i=0;i<NyLPC_TcTcpSocket_NUMBER_OF_TXQ;i++){ + inst->txbuf.txq[i].packet=NULL; + } + NyLPC_cFifoBuffer_finalize(&(inst->rxbuf)); +// NyLPC_cMutex_finalize(&(i_inst->_smutex)); + NyLPC_cMiMicIpBaseSocket_finalize(&(inst->_super)); + NyLPC_cMiMicIpNetIf_releaseTcpSocketMemory(inst); + + return; +} + +static NyLPC_TBool connect(NyLPC_TiTcpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_peer_port,NyLPC_TUInt32 i_wait_in_msec) +{ + volatile NyLPC_TUInt8 f; + NyLPC_TcMiMicIpTcpSocket_t* inst=(NyLPC_TcMiMicIpTcpSocket_t*)i_inst; + NyLPC_TUInt32 sq; + NyLPC_TcStopwatch_t sw; + NyLPC_TUInt16 lport; + lockResource(inst); + //ソケットが無効であること。 + if(inst->tcpstateflags!=UIP_CLOSED) + { + NyLPC_OnErrorGoto(Error); + } + //ポート番号の取得(lockResourceが他のソケットと共有なので、重複ポートの割当は起こりえない。でもちょっと注意して) + lport=NyLPC_htons(NyLPC_cIPv4_getNewPortNumber(inst->_super._parent_ipv4)); + if(lport==0){ + NyLPC_OnErrorGoto(Error); + } + //connectの為の準備 + + //localipとdefault_mmsは別枠で設定 + /* Fill in the necessary fields for the new connection. */ + inst->uip_connr.current_rto32 = UIP_TCP_RTO_CONNECTION_INITIAL;//RTOを短くしてARP発行時の再接続短縮を期待する。 + inst->uip_connr.lport = lport; + inst->uip_connr.rport = NyLPC_htons(i_peer_port); + inst->uip_connr.ripaddr=*i_addr; + inst->uip_connr.snd_nxt32=iss32;//should be random + /* rcv_nxt should be the seqno from the incoming packet + 1. */ + inst->uip_connr.rcv_nxt32=0; + //MSSの設定 + inst->uip_connr.peer_mss=inst->uip_connr.default_mss; + inst->uip_connr.peer_win=1;//periodicの再送信を期待するために相手のWindowサイズは1と仮定する。 + NyLPC_cFifoBuffer_clear(&(inst->rxbuf)); + //ここでステータスがかわる。 + inst->tcpstateflags = UIP_SYN_SENT; + //前回のデータが残っていた場合の保険 + if(inst->txbuf.rp!=inst->txbuf.wp){ + resetTxQWithUnlock(inst); + }else{ + unlockResource(inst); + } + + NyLPC_cStopwatch_initialize(&sw); + + NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec); + if(sendWithRetransmit(inst,TCP_SYN,NULL,0,&sw,&sq)==0){ + //ちょっと待つ。 + NyLPC_cThread_yield(); + //キューにあるTXが消えるのを待つ。 + if(waitForTxRemove(inst,sq,&sw)){ + //ACK受信に成功して、TXが消失 + NyLPC_cStopwatch_finalize(&sw); + return NyLPC_TBool_TRUE; + } + } + //ロックして、強制的なステータス遷移 + lockResource(inst); + f=inst->tcpstateflags; + if(f!=UIP_CLOSED){ + //もし、強制CLOSE遷移であれば、RSTも送信。 + inst->tcpstateflags=UIP_CLOSED; + unlockResource(inst); + sendRst(inst); + }else{ + unlockResource(inst); + } + return NyLPC_TBool_FALSE; +Error: + unlockResource(inst); + return NyLPC_TBool_FALSE; +} + +/** + * この関数は、UIP_SYN_RCVDステータスのソケットを、ESTABLISHEDへ遷移させます。 + * cTcpListener_listen関数を通過したインスタンスに実行してください。 + * この関数は、アプリケーションが呼び出します。 + * @return + * + */ +static NyLPC_TBool accept(NyLPC_TiTcpSocket_t* i_inst,NyLPC_TUInt32 i_wait_in_msec) +{ + volatile NyLPC_TUInt8 f; + NyLPC_TcMiMicIpTcpSocket_t* inst=(NyLPC_TcMiMicIpTcpSocket_t*)i_inst; + NyLPC_TUInt32 sq; + NyLPC_TcStopwatch_t sw; + + NyLPC_cStopwatch_initialize(&sw); + //ステータスチェック + f=inst->tcpstateflags; + switch(f) + { + case UIP_ESTABLISHED: + return NyLPC_TBool_TRUE; + case UIP_SYN_RCVD: + //処理対象 + break; + default: + return NyLPC_TBool_FALSE; + } + NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec); + if(sendWithRetransmit(inst,TCP_SYN|TCP_ACK,NULL,0,&sw,&sq)==0){ + //ちょっと待つ。 + NyLPC_cThread_yield(); + //キューにあるTXが消えるのを待つ。 + if(waitForTxRemove(inst,sq,&sw)){ + //ACK受信に成功して、TXが消失 + NyLPC_cStopwatch_finalize(&sw); + return NyLPC_TBool_TRUE; + } + } + //ロックして、強制的なステータス遷移 + lockResource(inst); + f=inst->tcpstateflags; + if(f!=UIP_CLOSED){ + //もし、強制CLOSE遷移であれば、RSTも送信。 + inst->tcpstateflags=UIP_CLOSED; + unlockResource(inst); + sendRst(inst); + }else{ + unlockResource(inst); + } + return NyLPC_TBool_FALSE; +} + + +/** + * この関数は、ソケットの受信バッファの読み取り位置と、読み出せるデータサイズを返却します。 + * 関数はポインターを返却するだけで、バッファの読み取り位置をシークしません。 + * シークするにはNyLPC_cTcpSocket_pseekを使います。 + */ +static NyLPC_TInt32 precv(NyLPC_TiTcpSocket_t* i_inst,const void** o_buf_ptr,NyLPC_TUInt32 i_wait_msec) +{ + NyLPC_TcMiMicIpTcpSocket_t* inst=(NyLPC_TcMiMicIpTcpSocket_t*)i_inst; + volatile NyLPC_TUInt8 st; + NyLPC_TUInt16 rlen; + //タイマを生成 + NyLPC_TcStopwatch_t sw; + NyLPC_cStopwatch_initialize(&sw); + + //ESTABLISHED以外の場合は、エラー。 + NyLPC_cStopwatch_setNow(&sw); + do{ + //読み出しバッファ情報のコピー + //MUTEX LOCK + lockResource(inst); + st=inst->tcpstateflags; + rlen=NyLPC_cFifoBuffer_getLength(&(inst->rxbuf)); + *o_buf_ptr=NyLPC_cFifoBuffer_getPtr(&(inst->rxbuf)); + //MUTEX UNLOCK + unlockResource(inst); + + //バッファが空の場合は、ステータスチェック。ESTABLISHEDでなければ、エラー(PASVCLOSE等の場合) + switch(st){ + case UIP_ESTABLISHED: + if(rlen>0){ + //バッファにパケットがあれば返却 + NyLPC_cStopwatch_finalize(&sw); + return rlen; + } + break; + case UIP_CLOSE_WAIT: + if(rlen>0){ + //バッファにパケットがあれば返却 + NyLPC_cStopwatch_finalize(&sw); + return rlen; + } + //引き続きエラー処理 + default: + //他の場合はエラー + NyLPC_cStopwatch_finalize(&sw); + return -1; + } + //タスクスイッチ + NyLPC_cThread_yield(); + }while(NyLPC_cStopwatch_elapseInMsec(&sw)<i_wait_msec); + //規定時間内に受信が成功しなかった。 + NyLPC_cStopwatch_finalize(&sw); + return 0; +} +/** + * 受信バッファをシークします。 + * シーク後に、遅延ACKを送出します。 + */ +static void pseek(NyLPC_TiTcpSocket_t* i_inst,NyLPC_TUInt16 i_seek) +{ + void* buf; + NyLPC_TcMiMicIpTcpSocket_t* inst=(NyLPC_TcMiMicIpTcpSocket_t*)i_inst; + + NyLPC_ArgAssert(i_seek<=NyLPC_cFifoBuffer_getLength(&(inst->rxbuf))); + if(i_seek==0){ + return; + } + + //ACK送信バッファの取得 + buf=NyLPC_cMiMicIpNetIf_allocSysTxBuf(); + + //MUTEX LOCK + lockResource(inst); + + //受信バッファを読み出しシーク + NyLPC_cFifoBuffer_pop(&(inst->rxbuf),i_seek); + //ACKパケットの生成 + setTxPacket(inst,buf,TCP_ACK,NULL,0); + unlockResource(inst); + //ACK送信 + NyLPC_cMiMicIpNetIf_sendIPv4Tx(buf); + NyLPC_cMiMicIpNetIf_releaseTxBuf(buf); + +} + +/** + * See header file. + */ +static void* allocSendBuf(NyLPC_TiTcpSocket_t* i_inst,NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_buf_size,NyLPC_TUInt32 i_wait_in_msec) +{ + NyLPC_TcMiMicIpTcpSocket_t* inst=(NyLPC_TcMiMicIpTcpSocket_t*)i_inst; + + NyLPC_TUInt16 s; + void* buf; + NyLPC_TcStopwatch_t sw; + + NyLPC_cStopwatch_initialize(&sw); + NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec); + + //送信バッファを取得 + //@bug バッファが取れるまで通信がブロックするの。ここはなんとかしないと。 + for(;;){ + //ESTABLISHED以外に非同期遷移 + if(inst->tcpstateflags!=UIP_ESTABLISHED){ + NyLPC_cStopwatch_finalize(&sw); + return NULL; + } + buf=NyLPC_cMiMicIpNetIf_allocTxBuf(i_hint+(SIZE_OF_IPv4_TCPIP_HEADER),&s); + if(buf!=NULL){ + break; + } + //タイムアウト時もエラー + if(NyLPC_cStopwatch_isExpired(&sw)){ + NyLPC_cStopwatch_finalize(&sw); + return NULL; + } + } + +//@todo 前段処理と順番を入れ替えて、要求サイズとpeerのwinのうち、小さいほうを割り当てたほうが良くない? +//ここで相手のwin待ちをする理由は、相手に確実に受け取れるサイズを決定する為。 + lockResource(inst); + //ペイロードがある場合のみ、相手のwindowサイズが0以上になるのを待つ。 + while(inst->uip_connr.peer_win==0){ + unlockResource(inst); + //ESTABLISHED以外に非同期遷移 orタイムアウト確認 + if(NyLPC_cStopwatch_isExpired(&sw)||(inst->tcpstateflags!=UIP_ESTABLISHED)){ + NyLPC_cMiMicIpNetIf_releaseTxBuf(buf); + NyLPC_cStopwatch_finalize(&sw); + return NULL; + } + NyLPC_cThread_yield(); + lockResource(inst); + } + //送信バッファを基準とした送信サイズを計算 + s-=SIZE_OF_IPv4_TCPIP_HEADER; + //送信サイズよりMMSが小さければ、送信サイズを修正 + if(inst->uip_connr.peer_mss<s){ + s=inst->uip_connr.peer_mss; + } + //送信サイズよりpeerのウインドウサイズが小さければ修正 + if(inst->uip_connr.peer_win<s){ + s=inst->uip_connr.peer_win; + } + unlockResource(inst); + //バッファサイズ確定。 + *o_buf_size=s; + NyLPC_cStopwatch_finalize(&sw); + return (NyLPC_TUInt8*)buf+SIZE_OF_IPv4_TCPIP_HEADER; +} +/** + * See Header file. + */ +static void releaseSendBuf(NyLPC_TiTcpSocket_t* i_inst,void* i_buf_ptr) +{ + NyLPC_cMiMicIpNetIf_releaseTxBuf((NyLPC_TUInt8*)i_buf_ptr-SIZE_OF_IPv4_TCPIP_HEADER); +} + + +/** + * 事前にAllocしたTxパケットを送信します。 + * このAPIはゼロコピー送信をサポートするためのものです。 + * @param i_buf_ptr + * allocSendBufで取得したメモリを指定します。 + * @return + * 関数が失敗した場合、i_buf_ptrは「開放されません。」 + */ +static NyLPC_TBool psend(NyLPC_TiTcpSocket_t* i_inst,void* i_buf_ptr,int i_len,NyLPC_TUInt32 i_wait_in_msec) +{ + NyLPC_TcMiMicIpTcpSocket_t* inst=(NyLPC_TcMiMicIpTcpSocket_t*)i_inst; + struct NyLPC_TcTcpSocket_TxQItem* txq; + void* buf; + NyLPC_TcStopwatch_t sw; + //ESTABLISHEDでなければエラー + if(inst->tcpstateflags!=UIP_ESTABLISHED){ + //ESTABLISHEDでなければエラー + return NyLPC_TBool_FALSE; + } + //送信データ0なら何もしない。 + if(i_len<1){ + releaseSendBuf(i_inst,i_buf_ptr); + return NyLPC_TBool_TRUE; + } + NyLPC_cStopwatch_initialize(&sw); + NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec); + + //先頭ポインタは、i_buf-sizeof(SIZE_OF_IPv4_TCPIP_HEADER)固定 + buf=(NyLPC_TUInt8*)i_buf_ptr-SIZE_OF_IPv4_TCPIP_HEADER; + lockResource(inst); + //送信キューの取得 + txq=getTxQ(inst,&sw); + //送信キューが取れなかった。 + if(txq==NULL){ + //シーケンス番号をロールバックできないので、エラーとする。 + unlockResource(inst); + NyLPC_cStopwatch_finalize(&sw); + return NyLPC_TBool_FALSE; + } + //ここから先はi_bufの所有権はインスタンスになってる。 + + //IPv4ペイロードの書き込み + + //allocをした時点でwin,mssは考慮されているので、そのままそうしんしる。 + + //ACK番号の計算 + txq->rto32=inst->uip_connr.current_rto32; + txq->tick_of_sent=NyLPC_cStopwatch_now(); + //パケットヘッダの生成(ヘッダ長はpreadで定義した値(4+6)*4=40です。) + setTxPacketHeader(inst,buf,TCP_ACK|TCP_PSH,i_len); + txq->packet=buf; + + //シーケンス番号の更新 + inst->uip_connr.snd_nxt32=inst->uip_connr.snd_nxt32+i_len; + //Peerのウインドウサイズを更新 + inst->uip_connr.peer_win-=i_len; + //ACK番号の返却 + txq->ackno=NyLPC_HTONL(inst->uip_connr.snd_nxt32); + unlockResource(inst); + NyLPC_cMiMicIpNetIf_sendIPv4Tx(buf); + NyLPC_cStopwatch_finalize(&sw); + return NyLPC_TBool_TRUE; +} + +/** + * See header file. + */ +static NyLPC_TInt32 send(NyLPC_TiTcpSocket_t* i_inst,const void* i_buf_ptr,NyLPC_TInt32 i_len,NyLPC_TUInt32 i_wait_in_msec) +{ + NyLPC_TInt16 hint; + NyLPC_TUInt16 s; + void* buf; + if(i_len<1){ + return 0; + } + hint=(i_len>32767)?32767:i_len; + buf=allocSendBuf(i_inst,hint,&s,i_wait_in_msec); + if(buf==NULL){ + return -1; + } + //送信サイズの計算 + s=((NyLPC_TInt32)s<i_len)?s:(NyLPC_TUInt16)i_len; + memcpy(buf,i_buf_ptr,s); + if(!psend(i_inst,buf,s,i_wait_in_msec)){ + releaseSendBuf(i_inst,buf); + return -1;//error + } + return s; +} + + +static void close(NyLPC_TiTcpSocket_t* i_inst,NyLPC_TUInt32 i_wait_in_msec) +{ + NyLPC_TcMiMicIpTcpSocket_t* inst=(NyLPC_TcMiMicIpTcpSocket_t*)i_inst; + NyLPC_TcStopwatch_t sw; + volatile NyLPC_TUInt8 f; + NyLPC_TUInt32 sq; + NyLPC_cStopwatch_initialize(&sw); + NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec); + lockResource(inst); + + f=inst->tcpstateflags; + //ステータスチェック + switch(f) + { + case UIP_CLOSED: + //閉じている。 + goto ReturnWithUnlock; + case UIP_ESTABLISHED: + //アクティブクローズ。 + inst->tcpstateflags=UIP_FIN_WAIT_1; + //送信のために一旦解除 + unlockResource(inst); + //FINの送信 + if(sendWithRetransmit(inst,TCP_FIN|TCP_ACK,NULL,0,&sw,&sq)==0){ + //ちょっと待つ。 + NyLPC_cThread_yield(); + //TXの消去待ち + if(waitForTxRemove(inst,sq,&sw)){ + //再ロック + lockResource(inst); + //タイムアウトするか、UIP_CLOSED、もしくはTIME_WAITに遷移するのを待つ。(遷移はRxprocで自動的に実行。) + do{ + switch(inst->tcpstateflags) + { + case UIP_TIME_WAIT: + inst->tcpstateflags=UIP_CLOSED; + case UIP_CLOSED: + NyLPC_Assert(inst->txbuf.rp==inst->txbuf.wp); + //成功。 + goto ReturnWithUnlock; + case UIP_FIN_WAIT_1: + case UIP_FIN_WAIT_2: + case UIP_CLOSING: + //一時的なアンロック + unlockResource(inst); + NyLPC_cThread_yield(); + lockResource(inst); + default: + break; + } + }while(!NyLPC_cStopwatch_isExpired(&sw)); + unlockResource(inst); + } + } + break; + case UIP_CLOSE_WAIT: + //LAST_ACKへ遷移 + inst->tcpstateflags=UIP_LAST_ACK; + //送信のために一旦解除 + unlockResource(inst); + if(sendWithRetransmit(inst,TCP_FIN|TCP_ACK,NULL,0,&sw,&sq)==0){ + //ちょっと待つ。 + NyLPC_cThread_yield(); + //TXの消去待ち + if(waitForTxRemove(inst,sq,&sw)){ + //再ロック + lockResource(inst); + //TX消去後にCLOSEDに遷移していればOK + if(inst->tcpstateflags==UIP_CLOSED) + { + NyLPC_Assert(inst->txbuf.rp==inst->txbuf.wp); + goto ReturnWithUnlock; + } + unlockResource(inst); + } + } + //エラー。RSTで切断。 + break; + default: + unlockResource(inst); + NyLPC_Warning(); + break; + } +// if(i_inst->_smutex._lock_count>0){ +// NyLPC_Warning(); +// } + //このパスに到達するのは、FIN送信/ACKに成功したにも拘らず、規定時間内にCLOSEDに遷移しなかった場合。 + //コネクションを強制遷移して、RST + lockResource(inst); + f=inst->tcpstateflags; + if(f!=UIP_CLOSED){ + //もし、強制CLOSE遷移であれば、RSTも送信。 + inst->tcpstateflags=UIP_CLOSED; + unlockResource(inst); + sendRst(inst); + }else{ + unlockResource(inst); + } + NyLPC_cStopwatch_finalize(&sw); + return; +ReturnWithUnlock: + unlockResource(inst); + NyLPC_cStopwatch_finalize(&sw); + return; +} + +/** + * uipサービスタスクが実行する関数です。 + * 定期的に実行する関数。最低でも1s単位で実行してください。 + */ +void NyLPC_cMiMicIpTcpSocket_periodic( + NyLPC_TcMiMicIpTcpSocket_t* i_inst) +{ + int i; + struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; + NyLPC_TcStopwatch_t sw; + NyLPC_TUInt32 now; + int rp; + NyLPC_cStopwatch_initialize(&sw); + now=NyLPC_cStopwatch_now(); + //MUTEX LOCK + lockResource(i_inst); + if(i_inst->tcpstateflags==UIP_CLOSED) + { + //CLOSEDなら、バッファ開放。 + resetTxQWithUnlock(i_inst); + }else if(i_inst->txbuf.rp==i_inst->txbuf.wp){ + //再送信パケットがなければ何もしないよ。 + unlockResource(i_inst); + }else if(i_inst->uip_connr.peer_win==0){ + //peer_winが0の場合は何もしない。 + unlockResource(i_inst); + }else{ + //再送信処理 + rp=i_inst->txbuf.rp; + NyLPC_cStopwatch_set(&sw,q[rp].tick_of_sent); + if(NyLPC_cStopwatch_elapseInMsec(&sw)>q[rp].rto32){ + //最古のパケットの送信時間をチェックして、タイムアウトが発生したら、再送時間と送信時刻をセット + //最古パケットRTOを2倍。 + q[rp].rto32*=2; + for(i=rp;i!=i_inst->txbuf.wp;i=(i+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ){ + q[i].tick_of_sent=now; + } + if(q[rp].rto32>UIP_IP_RTO_MAX_RTO){ + //最古のRTOが64秒を超えたら、CLOSED + i_inst->tcpstateflags =UIP_CLOSED; + resetTxQWithUnlock(i_inst); + sendRst(i_inst); + }else{ + //規定時間内なら、再送処理 + for(i=rp;i!=i_inst->txbuf.wp;i=(i+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ){ +// NyLPC_cUipService_sendIPv4Tx(NyLPC_cIPv4Payload_getBuf(&(q[i].data))); + NyLPC_cMiMicIpNetIf_sendIPv4Tx(q[i].packet); + } + unlockResource(i_inst); + } + }else{ + unlockResource(i_inst); + } + } + NyLPC_cStopwatch_finalize(&sw); + return; +} +/** + * uipサービスタスクが実行する関数です。 + * サービスの開始を通知します。 + */ +void NyLPC_cMiMicIpTcpSocket_startService(NyLPC_TcMiMicIpTcpSocket_t* i_inst,const NyLPC_TcIPv4Config_t* i_config) +{ + NyLPC_Assert(i_inst->tcpstateflags==UIP_CLOSED);//閉じてなければおかしい。 + i_inst->uip_connr.lipaddr=&(i_config->ip_addr); + i_inst->uip_connr.default_mss=i_config->default_mss; + //NyLPC_cTcpSocket_setSynPayload関数でも実行するけど、IFのリセット時なのでここでもやる。 + NyLPC_cFifoBuffer_clear(&(i_inst->rxbuf)); + return; +} +/** + * uipサービスタスクが実行する関数です。 + * サービスの停止を通知します。 + */ +void NyLPC_cMiMicIpTcpSocket_stopService(NyLPC_TcMiMicIpTcpSocket_t* i_inst) +{ + lockResource(i_inst); + if(i_inst->tcpstateflags==UIP_CLOSED) + { + unlockResource(i_inst); + }else{ + i_inst->tcpstateflags=UIP_CLOSED; + resetTxQWithUnlock(i_inst); + sendRst(i_inst); + } + return; +} + + +void* NyLPC_cMiMicIpTcpSocket_parseRx( + NyLPC_TcMiMicIpTcpSocket_t* i_inst, + const NyLPC_TcIPv4Payload_t* i_ipp) +{ + int i,s; + NyLPC_TUInt16 tmp16; + NyLPC_TUInt16 data_size; + NyLPC_TUInt8 in_tcpflag=i_ipp->payload.tcp->flags; + const void* tcp_data_offset; + NyLPC_TBool is_new_packet; + int num_of_noack; + void* dlist[NyLPC_TcTcpSocket_NUMBER_OF_TXQ]; + void* ret; + + //パラメータの計算 + + tmp16=NyLPC_TTcpHeader_getHeaderLength(i_ipp->payload.tcp); + //TCPペイロードの長さは、IPパケットの長さ-(IPヘッダ+TCPヘッダ) + data_size=NyLPC_TIPv4Header_getPacketLength(i_ipp->header)-NyLPC_TIPv4Header_getHeaderLength(i_ipp->header)-tmp16; + //TCPデータオフセット + tcp_data_offset=i_ipp->payload.rawbuf+tmp16; + + //インスタンスをロックする。 + lockResource(i_inst); + + //RSTのチェック。RST受信時は、状態にかかわらず、CLOSEDステータスに移行する。 + if (in_tcpflag & TCP_RST) + { + i_inst->tcpstateflags =UIP_CLOSED; + goto DROP; + } + + + is_new_packet=NyLPC_ntohl(i_ipp->payload.tcp->seqno32)==i_inst->uip_connr.rcv_nxt32; + + + //OPTIONの反映 + + //MSSの取得 + if(NyLPC_TTcpHeader_getTcpMmsOpt(i_ipp->payload.tcp,&tmp16)){ + //取得で着たら更新 + i_inst->uip_connr.peer_mss=tmp16; + } + //受信パケットを元に、未ACKパケットの数を計算 + num_of_noack=getNumOfSending(i_inst,i_ipp->payload.tcp->ackno32);//i_inst->txbuf.num_of_txq; + + //ステータス毎のACK応答 + switch(i_inst->tcpstateflags) + { + case UIP_SYN_RCVD: + //ACKを受信したら、ESTABLISHEDへ。 + //すべてのパケットをACKしたかで判定。() + if(num_of_noack==0){ + i_inst->tcpstateflags=UIP_ESTABLISHED; + }else{ + //それ以外のパケットはドロップする。 + break;//goto DROP; + } + //新しいパケットがなければ、無応答 + if(!is_new_packet){ + break;//goto DROP; + } + //引き続き、ESTABLISHEDの処理へ。 + case UIP_ESTABLISHED: + if(data_size>0){ + if(is_new_packet){ + if(addRecvData(i_inst,tcp_data_offset,data_size)){ + //通常のACK返却 + i_inst->uip_connr.rcv_nxt32+=data_size; + }else{ + //失敗したときは必要に応じて単純ACK + } + } + } + //どちらにしろ、ACK送信 + if(is_new_packet && (in_tcpflag & TCP_FIN)){ + //FINがあるときは、ステータスをCLOSE_WAITへセットして、ACKを返す。 + i_inst->tcpstateflags = UIP_CLOSE_WAIT; + i_inst->uip_connr.rcv_nxt32++; + } + break; + case UIP_CLOSE_WAIT: + //必要に応じたACK応答 + break; + case UIP_LAST_ACK: + //ACK(by FIN)が得られたなら、CLOSEDへ。 + if(num_of_noack==0){ + i_inst->tcpstateflags=UIP_CLOSED; + } + //必要に応じたACK応答 + break; + case UIP_FIN_WAIT_1: + //FIN受信->CLOSINGへ + if(is_new_packet){ + i_inst->uip_connr.rcv_nxt32+=data_size; + if(in_tcpflag & TCP_FIN){ + i_inst->uip_connr.rcv_nxt32++; + if(num_of_noack==0){ + //FINとACKを受信 + i_inst->tcpstateflags=UIP_TIME_WAIT; + }else{ + //FINのみ + i_inst->tcpstateflags=UIP_CLOSING; + } + } + }else if(num_of_noack==0){ + //ACKのみ + i_inst->tcpstateflags=UIP_FIN_WAIT_2; + } + //必要に応じたACK応答 + break; + case UIP_FIN_WAIT_2: + //FIN受信->TIME_WAITへ(pureACK) + if(is_new_packet && (in_tcpflag & TCP_FIN)){ + i_inst->uip_connr.rcv_nxt32++; + i_inst->tcpstateflags=UIP_TIME_WAIT; + } + break; + case UIP_CLOSING: + //ACK受信したら、TIME_WAITへ + if(num_of_noack==0){ + i_inst->tcpstateflags=UIP_TIME_WAIT; + } + break; + case UIP_CLOSED: + //何もできない。何もしない。 + break; + case UIP_TIME_WAIT: + //最終ACKを送り続ける。 + break; + case UIP_SYN_SENT: + //connect関数実行中しか起動しないステータス + if(num_of_noack==0){ + i_inst->tcpstateflags=UIP_ESTABLISHED; + i_inst->uip_connr.rcv_nxt32=NyLPC_ntohl(i_ipp->payload.tcp->seqno32)+1; + }else{ + //それ以外のパケットはドロップする。 + break;//goto DROP; + } + //ACKを送る。 + break; + default: + goto DROP; + } + //ウインドウサイズを更新 + i_inst->uip_connr.peer_win=NyLPC_ntohs(i_ipp->payload.tcp->wnd16); + + //送信キューから、Peerが受信したデータを削除する。 + if(in_tcpflag & TCP_ACK){ + //再送パケットキューから送信済みのデータを回収(後で開放) + NyLPC_Trace(); + s=updateTxQByIndex(i_inst,i_ipp->payload.tcp->ackno32,dlist); + NyLPC_Trace(); + }else{ + s=0; + } + //新しいパケットがきた場合は、再送キューのACKを更新する。 + if(is_new_packet){ + //再送キューのACKを更新 + updateTxAck(i_inst,NyLPC_htonl(i_inst->uip_connr.rcv_nxt32)); + } + + //送信キューのない + if(((in_tcpflag&(TCP_FIN|TCP_SYN))!=0x00) || + ((!is_new_packet) && (data_size>0))) + { + //ソケットからPureACKを生成 as setPacket(i_inst,i_ipp,TCP_ACK,NULL,0); + ret=NyLPC_cMiMicIpNetIf_allocSysTxBuf(); + setTxPacket(i_inst,ret,TCP_ACK,NULL,0); + }else{ + ret=NULL; + } + unlockResource(i_inst); + //取り外したTXメモリの開放 + for(i=0;i<s;i++){ + //取り外したTXメモリを開放 + NyLPC_cMiMicIpNetIf_releaseTxBuf(dlist[i]); + } +NyLPC_Trace(); + return ret; +DROP: + //ACKしたパケットを送信キューから削除 + unlockResource(i_inst); +NyLPC_Trace(); + return NULL; +} + + +/** + * 入力されたパケットからRSTパケットを生成して返す。 + */ +void* NyLPC_cMiMicIpTcpSocket_allocTcpReverseRstAck( + const NyLPC_TcIPv4Payload_t* i_src) +{ + struct NyLPC_TIPv4Header* iph; + struct NyLPC_TTcpHeader* tcph; + NyLPC_TUInt8 iph_word=0x05; + NyLPC_TUInt8 tcph_word=(UIP_TCPH_LEN) / 4; + void* txb=NyLPC_cMiMicIpNetIf_allocSysTxBuf(); + //IPヘッダの更新 + iph=(struct NyLPC_TIPv4Header*)txb; + iph->vhl=0x40|(0x0f&iph_word); + iph->destipaddr=i_src->header->srcipaddr; + iph->srcipaddr =i_src->header->destipaddr; + NyLPC_TIPv4Header_writeTxIpHeader(iph,UIP_PROTO_TCP); + + //TCPヘッダの更新 + tcph=(struct NyLPC_TTcpHeader*)(((NyLPC_TUInt8*)txb)+NyLPC_TIPv4Header_getHeaderLength(iph)); + + tcph->tcpoffset=(tcph_word<<4); + + tcph->flags = TCP_RST | TCP_ACK; + //sorce & destination port + tcph->srcport = i_src->payload.tcp->destport; + tcph->destport = i_src->payload.tcp->srcport; + //ACK number + tcph->ackno32 = NyLPC_htonl(NyLPC_ntohl(i_src->payload.tcp->seqno32)+1); + //Seq Number + tcph->seqno32 = i_src->payload.tcp->ackno32; + //uip_func_tcp_send_noconn(BUF); + tcph->urgp[0] = tcph->urgp[1] = 0; + tcph->tcpchksum= 0; + + + //最終的なパケットサイズと必要ならペイロードを書き込み + iph->len16=NyLPC_htons((iph_word+tcph_word)*4); + //WND設定 + tcph->wnd16=0; + //Checksumの生成 + tcph->tcpchksum=~(NyLPC_TIPv4Header_makeTcpChecksum(iph)); + iph->ipchksum = ~(NyLPC_TIPv4Header_makeIpChecksum(iph)); + return txb; +} + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cMiMicIpTcpSocket.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,152 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + *********************************************************************************/ +#ifndef NYLPC_CMIMICIPTCPSOCKET_H_ +#define NYLPC_CMIMICIPTCPSOCKET_H_ + + + +#include "NyLPC_os.h" +#include "../NyLPC_NetIf_ip_types.h" +#include "NyLPC_cIPv4Payload.h" +#include "NyLPC_cMiMicIpBaseSocket.h" + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +typedef struct NyLPC_TcMiMicIpTcpSocket NyLPC_TcMiMicIpTcpSocket_t; + + +/********************************************************************** + * + * NyLPC_TTcpListenerSynInfo struct + * + **********************************************************************/ + + +struct NyLPC_TTcpSocketSynParam +{ + struct NyLPC_TIPv4Addr srcaddr; + NyLPC_TUInt16 rport; + NyLPC_TUInt16 mss; + NyLPC_TUInt32 rcv_nxt32; +}; + + +/********************************************************************** + * + * NyLPC_TcTcpSocket_TxQItem struct + * + **********************************************************************/ + +/** + * TXキューの数。この値は8未満にしてください。 + */ +#define NyLPC_TcTcpSocket_NUMBER_OF_TXQ 4 + +struct NyLPC_TcTcpSocket_TxQItem +{ + //最終更新時刻 + NyLPC_TUInt32 tick_of_sent; + //このパケットのRTO(秒間隔) + NyLPC_TUInt32 rto32; + void* packet; + //パケットのACK番号。この番号を受信できれば、再送パケットは消去可能である。 + NyLPC_TUInt32 ackno; +}; + +/********************************************************************** + * + * uip_conn struct + * + **********************************************************************/ + +struct uip_conn +{ + struct NyLPC_TIPv4Addr ripaddr; /**< The IP address of the remote host. */ + const struct NyLPC_TIPv4Addr* lipaddr; /**< ローカルIP*/ + NyLPC_TUInt16 lport; /**< The local TCP port, in network byte order. */ + NyLPC_TUInt16 rport; /**< The local remote TCP port, in network byte order. */ + NyLPC_TUInt32 rcv_nxt32; /**< The sequence number that we expect to receive next. */ + NyLPC_TUInt32 snd_nxt32; /**< 送信用sqカウンター*/ + NyLPC_TUInt16 peer_mss; /**< PeerのMSS*/ + NyLPC_TUInt16 default_mss; /**< Peerの初期MMS*/ + /**Peerのウインドウサイズ*/ + NyLPC_TUInt16 peer_win; + NyLPC_TUInt16 _padding; + /**現在ソケットのRTO*/ + NyLPC_TUInt32 current_rto32; +}; + + + + + + + + +/********************************************************************** + * + * NyLPC_TcTcpSocket class + * + **********************************************************************/ + +/** + * uipサービスを使用したTCPソケットクラスです。 + * この関数は2つのタスクから呼び出されます。 + * [uipTask] -> [cTcpSocket] <- [Application] + * ApplicationとuipTaskとの間での排他処理はインスタンスで制御されています。 + * Application側からのコールは内部でuipTaskとの間で排他処理を実行します。 + * Application側からのコールはリエントラントではありません。 + */ + +struct NyLPC_TcMiMicIpTcpSocket +{ + /** Base class*/ + NyLPC_TcMiMicIpBaseSocket_t _super; + //この変数は、uipタスクの実行する関数のみが変更する。 + struct uip_conn uip_connr; + NyLPC_TcFifoBuffer_t rxbuf; + struct{ + NyLPC_TUInt8 rp; + NyLPC_TUInt8 wp; + //送信キュー + struct NyLPC_TcTcpSocket_TxQItem txq[NyLPC_TcTcpSocket_NUMBER_OF_TXQ]; + }txbuf; + volatile NyLPC_TUInt8 tcpstateflags; /**< TCP state and flags. */ +}; + +NyLPC_TBool NyLPC_cMiMicIpTcpSocket_initialize(NyLPC_TcMiMicIpTcpSocket_t* i_inst,void* i_rbuf,NyLPC_TUInt16 i_rbuf_len); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* NYLPC_CTCPSOCKET_H_ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cMiMicIpTcpSocket_protected.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,114 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + *********************************************************************************/ + +#ifndef NYLPC_CMIMICIPTCPSOCKET_PROTECTED_H_ +#define NYLPC_CMIMICIPTCPSOCKET_PROTECTED_H_ +#include "NyLPC_cIPv4.h" +#include "NyLPC_cMiMicIpTcpSocket.h" +#include "../NyLPC_cIPv4Config.h" +#include "NyLPC_cIPv4Payload_protected.h" +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/********************************************************************** + * ステータス値の定義 + **********************************************************************/ +#define UIP_CLOSED 0 +#define UIP_SYN_RCVD 1 +#define UIP_SYN_SENT 2 +#define UIP_ESTABLISHED 3 +#define UIP_FIN_WAIT_1 4 +#define UIP_FIN_WAIT_2 5 +#define UIP_CLOSING 6 +#define UIP_TIME_WAIT 7 +#define UIP_CLOSE_WAIT 8 +#define UIP_LAST_ACK 9 + + + + + + + + +/** + * パース結果をもとに、ソケットのuipconnectionを初期化します。 + * この関数は、cUipServiceからのみコールできます。 + */ +void NyLPC_cMiMicIpTcpSocket_initConnection(NyLPC_TcMiMicIpTcpSocket_t* i_inst,const NyLPC_TcIPv4Config_t* i_config,const NyLPC_TcIPv4Payload_t* i_ipp); + +/** + * TCPペイロードを処理して、応答パケットをペイロードに返します。 + * uipサービスタスクが実行する関数です。 + * @return + * 応答パケットを格納したメモリブロックを返します。 + * このメモリは、NyLPC_cUipService_allocSysTxBuf関数で確保されたメモリです。 + */ +void* NyLPC_cMiMicIpTcpSocket_parseRx( + NyLPC_TcMiMicIpTcpSocket_t* i_inst, + const NyLPC_TcIPv4Payload_t* i_ipp); + +/** + * 定期的に実行する関数。最低でも1s単位で実行してください。 + * uipサービスタスクが実行する関数です。 + */ +void NyLPC_cMiMicIpTcpSocket_periodic( + NyLPC_TcMiMicIpTcpSocket_t* i_inst); + +/** + * CLOSEステータスのソケットを、SYN情報の内容でSYNRECV状態にします。 + * この関数は、NyLPC_TcTcpListenerクラスからコールされます。 + * @return + * 遷移に成功すると、TRUEを返します。 + */ +NyLPC_TBool NyLPC_cMiMicIpTcpSocket_listenSyn(NyLPC_TcMiMicIpTcpSocket_t* i_inst,const struct NyLPC_TTcpSocketSynParam* i_lq,NyLPC_TUInt16 i_lport); + + +/** + * uipサービスタスクが実行する関数です。 + * サービスの開始を通知します。 + * この関数は他のAPIが非同期に実行されないことが保証される状況で使用する必要があります。 + */ +void NyLPC_cMiMicIpTcpSocket_startService(NyLPC_TcMiMicIpTcpSocket_t* i_inst,const NyLPC_TcIPv4Config_t* i_config); + +/** + * uipサービスタスクが実行する関数です。 + * サービスの停止を通知します。 + * この関数は他のAPIが非同期に実行されないことが保証される状況で使用する必要があります。 + */ +void NyLPC_cMiMicIpTcpSocket_stopService(NyLPC_TcMiMicIpTcpSocket_t* i_inst); + + +void* NyLPC_cMiMicIpTcpSocket_allocTcpReverseRstAck( + const NyLPC_TcIPv4Payload_t* i_src); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* NYLPC_CTCPSOCKET_PROTECTED_H_ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cMiMicIpUdpSocket.c Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,435 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For further information please contact. + * http://nyatla.jp/ + * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> + * + * + * Parts of this file were leveraged from uIP: + * + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "NyLPC_cMiMicIpUdpSocket_protected.h" +#include "NyLPC_cIPv4Payload_protected.h" +#include "NyLPC_cMiMicIpNetIf_protected.h" + +/** + * フラグ値 + */ +#define NyLPC_cMiMicIpUdpSocket_FLAG_BROADCAST 0 +/** + * UDP/IPヘッダのサイズ + */ +#define SIZE_OF_IPv4_UDPIP_HEADER 28 + +#define lockResource(i_inst) NyLPC_cMutex_lock(((i_inst)->_smutex)) +#define unlockResource(i_inst) NyLPC_cMutex_unlock(((i_inst)->_smutex)) + +/* + * 関数テーブル + */ +static void joinMulticast(NyLPC_TiUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr); +static void setBroadcast(NyLPC_TiUdpSocket_t* i_inst); +static NyLPC_TInt32 precv(NyLPC_TiUdpSocket_t* i_inst,const void** o_buf_ptr,const struct NyLPC_TIPv4RxInfo** o_info,NyLPC_TUInt32 i_wait_msec); +static void pseek(NyLPC_TiUdpSocket_t* i_inst); +static void* allocSendBuf(NyLPC_TiUdpSocket_t* i_inst,NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_buf_size,NyLPC_TUInt32 i_wait_in_msec); +static void releaseSendBuf(NyLPC_TiUdpSocket_t* i_inst,void* i_buf_ptr); +static NyLPC_TBool psend(NyLPC_TiUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_port,void* i_buf_ptr,int i_len); +static NyLPC_TInt32 send(NyLPC_TiUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_port,const void* i_buf_ptr,NyLPC_TInt32 i_len,NyLPC_TUInt32 i_wait_in_msec); +static void setOnRxHandler(NyLPC_TiUdpSocket_t* i_inst,NyLPC_TiUdpSocket_onRxHandler i_handler); +static void setOnPeriodicHandler(NyLPC_TiUdpSocket_t* i_inst,NyLPC_TiUdpSocket_onPeriodicHandler i_handler); +static struct NyLPC_TIPv4Addr* getSockIP(const NyLPC_TiUdpSocket_t* i_inst); +static void finalize(NyLPC_TiUdpSocket_t* i_inst); + +const struct NyLPC_TiUdpSocket_Interface interface= +{ + joinMulticast, + setBroadcast, + precv, + pseek, + allocSendBuf, + releaseSendBuf, + psend, + send, + setOnRxHandler, + setOnPeriodicHandler, + getSockIP, + finalize +}; + + + + +/* + * Initializer/Finalizer + */ + + +NyLPC_TBool NyLPC_cMiMicIpUdpSocket_initialize(NyLPC_TcMiMicIpUdpSocket_t* i_inst,NyLPC_TUInt16 i_port,void* i_rbuf,NyLPC_TUInt16 i_rbuf_len) +{ + NyLPC_TcMiMicIpNetIf_t* srv=_NyLPC_TcMiMicIpNetIf_inst; + i_inst->_super._super.udp_sock._interface=&interface; + i_inst->_super._super.udp_sock._tag=NULL; + NyLPC_cMiMicIpBaseSocket_initialize(&(i_inst->_super),NyLPC_TcMiMicIpBaseSocket_TYPEID_UDP_SOCK); + //uipサービスは初期化済であること。 + NyLPC_Assert(NyLPC_cMiMicIpNetIf_isInitService()); + i_inst->_smutex=NyLPC_cIPv4_getSockMutex(&(srv->_tcpv4)); + i_inst->uip_udp_conn.lport=NyLPC_htons(i_port); + i_inst->uip_udp_conn.mcastaddr=NyLPC_TIPv4Addr_ZERO; + i_inst->uip_udp_conn.flags=0x00; + i_inst->as_handler.rx=NULL; + i_inst->as_handler.periodic=NULL; + + NyLPC_cFifoBuffer_initialize(&(i_inst->rxbuf),i_rbuf,i_rbuf_len); + //管理リストへ登録。 + return NyLPC_cIPv4_addSocket(&(srv->_tcpv4),&(i_inst->_super)); +} + + + +/** + * IP+UDPヘッダサイズを0x05*4+8バイトとして、UDPの送信バッファをセットします。 + */ +static void setUdpTxBufHeader(const NyLPC_TcMiMicIpUdpSocket_t* i_inst,void*i_buf,const struct NyLPC_TIPv4Addr* i_dest_ip,NyLPC_TUInt16 i_dest_port,NyLPC_TUInt8 i_iph_word,NyLPC_TUInt16 i_payload_size) +{ + struct NyLPC_TIPv4Header* header=(struct NyLPC_TIPv4Header*)i_buf; + struct NyLPC_TUdpHeader* udp =(struct NyLPC_TUdpHeader*)(((NyLPC_TUInt8*)i_buf)+i_iph_word*4); + + header->vhl=0x40|(0x0f&i_iph_word); + header->len16=NyLPC_htons(i_payload_size+(i_iph_word*4+8)); + udp->udplen=NyLPC_htons(i_payload_size+(8)); + //IPv4のTxヘッダを書き込む。 + header->destipaddr=*i_dest_ip; + header->srcipaddr =i_inst->uip_udp_conn.lipaddr; + + NyLPC_TIPv4Header_writeTxIpHeader(header,UIP_PROTO_UDP); + + //UDPのTxヘッダを書き込む + //sorce & destination port + udp->srcport = i_inst->uip_udp_conn.lport; + udp->destport = NyLPC_htons(i_dest_port); + udp->udpchksum= 0; + + udp->udpchksum=~(NyLPC_TIPv4Header_makeTcpChecksum(header)); + header->ipchksum = ~(NyLPC_TIPv4Header_makeIpChecksum(header)); +} + + + + +/** + * この関数は、rxパケットを処理して、ソケットの状態を更新します。 + * uipサービスタスクが実行する関数です。 + * この関数はNyLPC_cTcpSocket_periodicと排他実行すること。 + */ +NyLPC_TBool NyLPC_cMiMicIpUdpSocket_parseRx( + NyLPC_TcMiMicIpUdpSocket_t* i_inst, + const NyLPC_TcIPv4Payload_t* i_ipp) +{ + NyLPC_TUInt16 tmp16; + struct NyLPC_TIPv4RxInfo dheader; + const void* data_offset; + //ブロードキャストの場合、フラグを確認 + if(NyLPC_TIPv4Addr_isEqual(&(i_ipp->header->destipaddr),&NyLPC_TIPv4Addr_BROADCAST)){ + if(!NyLPC_TUInt8_isBitOn(i_inst->uip_udp_conn.flags,NyLPC_cMiMicIpUdpSocket_FLAG_BROADCAST)){ + goto DROP; + } + } + //パラメータの計算 + tmp16=NyLPC_TUdpHeader_getHeaderLength(i_ipp->payload.tcp); + //UDPペイロードの長さは、IPパケットの長さ-(IPヘッダ+UDPヘッダ) + dheader.size=NyLPC_TIPv4Header_getPacketLength(i_ipp->header)-NyLPC_TIPv4Header_getHeaderLength(i_ipp->header)-tmp16; + dheader.peer_ip=i_ipp->header->srcipaddr; + dheader.peer_port=NyLPC_ntohs(i_ipp->payload.udp->srcport); + dheader.ip=i_ipp->header->destipaddr; + dheader.port=NyLPC_ntohs(i_ipp->payload.udp->destport); + if(i_inst->as_handler.rx!=NULL){ + if(!i_inst->as_handler.rx((NyLPC_TiUdpSocket_t*)(i_inst),i_ipp->payload.rawbuf+tmp16,&dheader)){ + return NyLPC_TBool_FALSE;//UDPはReturnパケットなし + } + } + //TCPデータオフセット + data_offset=i_ipp->payload.rawbuf+tmp16; + + //インスタンスをロックする。 + lockResource(i_inst); + //受信キューへ追加(データ構造はsize[2]+data[n]).sizeに16ビットの受信サイズ,後続にデータ + + //受信データサイズを確認 + if(NyLPC_cFifoBuffer_getSpace(&(i_inst->rxbuf))<dheader.size+sizeof(struct NyLPC_TIPv4RxInfo)){ + goto DROP; + } + //バッファに格納可能なら、格納。 + NyLPC_cFifoBuffer_push(&(i_inst->rxbuf),&dheader,sizeof(struct NyLPC_TIPv4RxInfo)); + NyLPC_cFifoBuffer_push(&(i_inst->rxbuf),data_offset,dheader.size); + unlockResource(i_inst); + return NyLPC_TBool_FALSE;//UDPはReturnパケットなし +DROP: + unlockResource(i_inst); + return NyLPC_TBool_FALSE; +} + + + + +static void finalize(NyLPC_TiUdpSocket_t* i_inst) +{ + NyLPC_TcMiMicIpNetIf_t* srv=_NyLPC_TcMiMicIpNetIf_inst; + NyLPC_Assert(NyLPC_cMiMicIpNetIf_isInitService()); + //uipサービスは初期化済であること。 + if(!NyLPC_cIPv4_removeSocket(&(srv->_tcpv4),&(((NyLPC_TcMiMicIpUdpSocket_t*)i_inst)->_super))){ + //削除失敗、それは死を意味する。 + NyLPC_Abort(); + } + NyLPC_cFifoBuffer_finalize(&(i_inst->rxbuf)); + NyLPC_cMiMicIpBaseSocket_finalize(&(((NyLPC_TcMiMicIpUdpSocket_t*)i_inst)->_super)); + NyLPC_cMiMicIpNetIf_releaseUdpSocketMemory((NyLPC_TcMiMicIpUdpSocket_t*)i_inst); + return; +} + + +static void joinMulticast(NyLPC_TiUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr) +{ + NyLPC_TcMiMicIpUdpSocket_t* inst=(NyLPC_TcMiMicIpUdpSocket_t*)i_inst; + inst->uip_udp_conn.mcastaddr=*i_addr; +} +static void setBroadcast(NyLPC_TiUdpSocket_t* i_inst) +{ + NyLPC_TcMiMicIpUdpSocket_t* inst=(NyLPC_TcMiMicIpUdpSocket_t*)i_inst; + NyLPC_TUInt8_setBit(inst->uip_udp_conn.flags,NyLPC_cMiMicIpUdpSocket_FLAG_BROADCAST); +} + + + +/** + * see Header file + */ +static NyLPC_TInt32 precv(NyLPC_TiUdpSocket_t* i_inst,const void** o_buf_ptr,const struct NyLPC_TIPv4RxInfo** o_info,NyLPC_TUInt32 i_wait_msec) +{ + NyLPC_TcMiMicIpUdpSocket_t* inst=(NyLPC_TcMiMicIpUdpSocket_t*)i_inst; + NyLPC_TUInt16 rlen; + //タイマを生成 + NyLPC_TcStopwatch_t sw; + NyLPC_cStopwatch_initialize(&sw); + const char* b; + const struct NyLPC_TIPv4RxInfo* rh; + + //ESTABLISHED以外の場合は、エラー。 + NyLPC_cStopwatch_setNow(&sw); + while(NyLPC_cStopwatch_elapseInMsec(&sw)<i_wait_msec) + { + //MUTEX LOCK + lockResource(inst); + rlen=NyLPC_cFifoBuffer_getLength(&(inst->rxbuf)); + //MUTEX UNLOCK + unlockResource(inst); + if(rlen>0){ + //受信キューにデータがあれば返す。 + b=(char*)NyLPC_cFifoBuffer_getPtr(&(inst->rxbuf)); + rh=(const struct NyLPC_TIPv4RxInfo*)b; + *o_buf_ptr=b+sizeof(struct NyLPC_TIPv4RxInfo); + if(o_info!=NULL){ + *o_info=rh; + } + return rh->size; + } + //タスクスイッチ + NyLPC_cThread_yield(); + }; + NyLPC_cStopwatch_finalize(&sw); + return 0; +} +/** + * See header file + */ +static void pseek(NyLPC_TiUdpSocket_t* i_inst) +{ + NyLPC_TcMiMicIpUdpSocket_t* inst=(NyLPC_TcMiMicIpUdpSocket_t*)i_inst; + NyLPC_TUInt16 s; + const struct NyLPC_TIPv4RxInfo* rh; + //シークサイズを決定 + s=NyLPC_cFifoBuffer_getLength(&(inst->rxbuf)); + if(s==0){ + return; + } + rh=(const struct NyLPC_TIPv4RxInfo*)NyLPC_cFifoBuffer_getPtr(&(inst->rxbuf)); + NyLPC_cFifoBuffer_pop(&(inst->rxbuf),rh->size+sizeof(struct NyLPC_TIPv4RxInfo)); +} + +/** + * See header file. + */ +static void* allocSendBuf(NyLPC_TiUdpSocket_t* i_inst,NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_buf_size,NyLPC_TUInt32 i_wait_in_msec) +{ + NyLPC_TUInt16 s; + void* buf; + NyLPC_TcStopwatch_t sw; + + NyLPC_cStopwatch_initialize(&sw); + NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec); + + //送信バッファを取得 + //@bug バッファが取れるまで通信がブロックするの。ここはなんとかしないと。 + for(;;){ + buf=NyLPC_cMiMicIpNetIf_allocTxBuf(i_hint+(SIZE_OF_IPv4_UDPIP_HEADER),&s); + if(buf!=NULL){ + break; + } + //タイムアウト確認 + if(NyLPC_cStopwatch_isExpired(&sw)){ + return NULL; + } + } + //バッファサイズ確定。 + *o_buf_size=s; + NyLPC_cStopwatch_finalize(&sw); + return (NyLPC_TUInt8*)buf+SIZE_OF_IPv4_UDPIP_HEADER; +} +/** + * See Header file. + */ +static void releaseSendBuf(NyLPC_TiUdpSocket_t* i_inst,void* i_buf_ptr) +{ + NyLPC_cMiMicIpNetIf_releaseTxBuf((NyLPC_TUInt8*)i_buf_ptr-SIZE_OF_IPv4_UDPIP_HEADER); +} + +/** + * See header file + */ +static NyLPC_TBool psend(NyLPC_TiUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_port,void* i_buf_ptr,int i_len) +{ + void* buf; + NyLPC_TcMiMicIpUdpSocket_t* inst=(NyLPC_TcMiMicIpUdpSocket_t*)i_inst; + //ブロードキャストの場合、フラグを確認 + if(NyLPC_TIPv4Addr_isEqual(i_addr,&NyLPC_TIPv4Addr_BROADCAST)){ + if(!NyLPC_TUInt8_isBitOn(inst->uip_udp_conn.flags,NyLPC_cMiMicIpUdpSocket_FLAG_BROADCAST)){ + return NyLPC_TBool_FALSE; + } + } + + //先頭ポインタは、i_buf-sizeof(SIZE_OF_IPv4_TCPIP_HEADER)固定 + buf=(NyLPC_TUInt8*)i_buf_ptr-SIZE_OF_IPv4_UDPIP_HEADER; + + lockResource(inst); + //IPv4ペイロードの書き込み + setUdpTxBufHeader(inst,buf,i_addr,i_port,0x05,i_len); + unlockResource(inst); + // !(BroadCast || Multicast)の場合は送信前にARPテーブルをチェックする。 + if(!(NyLPC_TIPv4Addr_isEqual(i_addr,&NyLPC_TIPv4Addr_BROADCAST) || NyLPC_TIPv4Addr_isEqualWithMask(i_addr,&NyLPC_TIPv4Addr_MULTICAST,&NyLPC_TIPv4Addr_MULTICAST_MASK))){ + if(!NyLPC_cMiMicIpNetIf_hasArpInfo(i_addr)){ + NyLPC_cMiMicIpNetIf_sendArpRequest(i_addr); + NyLPC_cThread_sleep(30); + } + } + NyLPC_cMiMicIpNetIf_sendIPv4Tx(buf); + NyLPC_cMiMicIpNetIf_releaseTxBuf(buf); + return NyLPC_TBool_TRUE; +} + +/** + * See header file. + */ +static NyLPC_TInt32 send(NyLPC_TiUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_port,const void* i_buf_ptr,NyLPC_TInt32 i_len,NyLPC_TUInt32 i_wait_in_msec) +{ + NyLPC_TUInt16 s; + int i; + void* buf; + if(i_len<1 || i_len>1200){ + return 0; + } + //バッファの取得確率を上げるために2倍のサイズを要求 + for(i=0;i<3;i++){ + buf=allocSendBuf(i_inst,i_len*2,&s,i_wait_in_msec); + if(buf==NULL || s<i_len){ + continue; + } + break; + } + if(buf==NULL){ + return -1; + } + //送信サイズの計算 + memcpy(buf,i_buf_ptr,i_len); + if(!psend(i_inst,i_addr,i_port,buf,i_len)){ + releaseSendBuf(i_inst,buf); + return -1; + } + return i_len; +} + +static void setOnRxHandler(NyLPC_TiUdpSocket_t* i_inst,NyLPC_TiUdpSocket_onRxHandler i_handler) +{ + NyLPC_TcMiMicIpUdpSocket_t* inst=(NyLPC_TcMiMicIpUdpSocket_t*)i_inst; + inst->as_handler.rx=i_handler; +} +static void setOnPeriodicHandler(NyLPC_TiUdpSocket_t* i_inst,NyLPC_TiUdpSocket_onPeriodicHandler i_handler) +{ + NyLPC_TcMiMicIpUdpSocket_t* inst=(NyLPC_TcMiMicIpUdpSocket_t*)i_inst; + inst->as_handler.periodic=i_handler; +} +static struct NyLPC_TIPv4Addr* getSockIP(const NyLPC_TiUdpSocket_t* i_inst) +{ + NyLPC_TcMiMicIpUdpSocket_t* inst=(NyLPC_TcMiMicIpUdpSocket_t*)i_inst; + return &inst->uip_udp_conn.lipaddr; +} + + +void NyLPC_cMiMicIpUdpSocket_startService(NyLPC_TcMiMicIpUdpSocket_t* i_inst,const NyLPC_TcIPv4Config_t* i_config) +{ + i_inst->uip_udp_conn.lipaddr=i_config->ip_addr; + //受信バッファのクリア + NyLPC_cFifoBuffer_clear(&(i_inst->rxbuf)); + return; +} + + +void NyLPC_cMiMicIpUdpSocket_stopService(NyLPC_TcMiMicIpUdpSocket_t* i_inst) +{ + //停止処理? +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cMiMicIpUdpSocket.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,93 @@ +/* + * NyLPC_cUdpSocket.h + * + * Created on: 2013/05/20 + * Author: nyatla + */ + +#ifndef NYLPC_CMIMICIPUDPSOCKET_H_ +#define NYLPC_CMIMICIPUDPSOCKET_H_ + +#include "NyLPC_os.h" +#include "NyLPC_cMiMicIpBaseSocket.h" +#include "../NyLPC_iUdpSocket.h" + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define NyLPC_TcMiMicIpUdpSocket_MAX_UDP_SOCKET 1 + +/** + * Class struct + */ +typedef struct NyLPC_TcMiMicIpUdpSocket NyLPC_TcMiMicIpUdpSocket_t; + + +/** + * 受信時に非同期にコールされるハンドラ + * UIPサービスタスクが実行する。 + * @return + * TRUEならパケットを受信キューへ追加する。FALSEならパケットを受信キューへ追加しない。 + */ +typedef NyLPC_TBool (*NyLPC_TcMiMicIpUdpSocket_onRxHandler)(NyLPC_TiUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info); + +/** + * 一定周期で非同期にコールされるハンドラ。 + * UIPサービスタスクが実行する。 + */ +typedef void (*NyLPC_TcMiMicIpUdpSocket_onPeriodicHandler)(NyLPC_TiUdpSocket_t* i_inst); + +/** + * Representation of a uIP UDP connection. + */ +struct uip_udp_conn{ + struct NyLPC_TIPv4Addr lipaddr; /**< The IP address of the remote peer. */ + /** マルチキャスとアドレス(ZEROで無効)*/ + struct NyLPC_TIPv4Addr mcastaddr; + NyLPC_TUInt16 lport; /**< The local port number in network byte order. */ + NyLPC_TUInt8 flags; /**フラグ*/ + NyLPC_TUInt8 padding; /***/ +}; + + + + +struct NyLPC_TcMiMicIpUdpSocket +{ + NyLPC_TcMiMicIpBaseSocket_t _super; + //この変数は、uipタスクの実行する関数のみが変更する。 + struct uip_udp_conn uip_udp_conn; + NyLPC_TcFifoBuffer_t rxbuf; + NyLPC_TcMutex_t* _smutex; + struct{ + /** 受信ハンドラ。サービス実装に使用する。*/ + NyLPC_TcMiMicIpUdpSocket_onRxHandler rx; + /** 定期実行ハンドラ。サービス実装に使用する。最低保障周期は1s*/ + NyLPC_TcMiMicIpUdpSocket_onPeriodicHandler periodic; + }as_handler; +}; + + + + + + +/** + * @param i_rbuf + * 受信バッファアアドレス。サイズは、(最大受信サイズ-4バイト)*キュー数で計算します。 + * @param i_rbuf_len + * 受信バッファのサイズ。 + */ +NyLPC_TBool NyLPC_cMiMicIpUdpSocket_initialize(NyLPC_TcMiMicIpUdpSocket_t* i_inst,NyLPC_TUInt16 i_port,void* i_rbuf,NyLPC_TUInt16 i_rbuf_len); +void NyLPC_cMiMicIpUdpSocket_finalize(NyLPC_TcMiMicIpUdpSocket_t* i_inst); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* NYLPC_CUDPSOCKET_H_ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/netif/mimicip/NyLPC_cMiMicIpUdpSocket_protected.h Wed Nov 19 14:45:17 2014 +0000 @@ -0,0 +1,56 @@ +/* + * NyLPC_cUdpSocket.h + * + * Created on: 2013/05/20 + * Author: nyatla + */ + +#ifndef NYLPC_CUDPSOCKET_PROTECTED_H_ +#define NYLPC_CUDPSOCKET_PROTECTED_H_ +#include "NyLPC_cMiMicIpUdpSocket.h" +#include "NyLPC_cIPv4Payload.h" +#include "../NyLPC_cIPv4Config.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + + + + +/** + * この関数は、rxパケットを処理して、ソケットの状態を更新します。 + * uipサービスタスクが実行する関数です。 + */ +NyLPC_TBool NyLPC_cMiMicIpUdpSocket_parseRx( + NyLPC_TcMiMicIpUdpSocket_t* i_inst, + const NyLPC_TcIPv4Payload_t* i_ipp); + +/** + * uipサービスタスクが実行する関数です。 + * サービスの開始を通知します。 + * この関数は他のAPIが非同期に実行されないことが保証される状況で使用する必要があります。 + */ +void NyLPC_cMiMicIpUdpSocket_startService(NyLPC_TcMiMicIpUdpSocket_t* i_inst,const NyLPC_TcIPv4Config_t* i_config); + +/** + * uipサービスタスクが実行する関数です。 + * サービスの停止を通知します。 + * この関数は他のAPIが非同期に実行されないことが保証される状況で使用する必要があります。 + */ +void NyLPC_cMiMicIpUdpSocket_stopService(NyLPC_TcMiMicIpUdpSocket_t* i_inst); + + +/** + * 定期的に実行する関数。最低でも1s単位で実行してください。 + * uipサービスタスクが実行する関数です。 + */ +#define NyLPC_cMiMicIpUdpSocket_periodic(i_inst) if((i_inst)->as_handler.periodic!=NULL){(i_inst)->as_handler.periodic((NyLPC_TiUdpSocket_t*)(i_inst));} +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* NYLPC_CUDPSOCKET_H_ */ +
--- a/core/uip/NyLPC_cBaseSocket.c Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -#include "NyLPC_cBaseSocket.h" -#include "NyLPC_cUipService_protected.h" - -void NyLPC_cBaseSocket_initialize(NyLPC_TcBaseSocket_t* i_inst,NyLPC_TUInt8 i_typeid) -{ - NyLPC_TcUipService_t* srv=_NyLPC_TcUipService_inst; - i_inst->_typeid=i_typeid; - i_inst->_parent_ipv4=&(srv->_tcpv4); -}
--- a/core/uip/NyLPC_cBaseSocket.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - *********************************************************************************/ -#ifndef NYLPC_CBASESOCKET_H_ -#define NYLPC_CBASESOCKET_H_ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#include "NyLPC_stdlib.h" -#include "NyLPC_cIPv4_typedef.h" - -/** - * Base socket class - * cIPv4 classが管理するソケットオブジェクトのベースクラスです。 - */ -typedef struct NyLPC_TcBaseSocket NyLPC_TcBaseSocket_t; - -#define NyLPC_TcBaseSocket_TYPEID_UDP_SOCK 1 -#define NyLPC_TcBaseSocket_TYPEID_TCP_SOCK 2 -#define NyLPC_TcBaseSocket_TYPEID_TCP_LISTENER 3 - -struct NyLPC_TcBaseSocket -{ - /**タイプID 継承クラスのinitializerで設定。 */ - NyLPC_TUInt8 _typeid; - NyLPC_TUInt8 _padding8; - NyLPC_TUInt16 _padding16; - /** 所属してるIPv4コンローラ*/ - NyLPC_TcIPv4_t* _parent_ipv4; -}; -void NyLPC_cBaseSocket_initialize(NyLPC_TcBaseSocket_t* i_inst,NyLPC_TUInt8 i_typeid); -#define NyLPC_cBaseSocket_finalize(i_inst) - - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* NYLPC_CBASESOCKET_H_ */
--- a/core/uip/NyLPC_cIPv4.c Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,539 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - * - * Parts of this file were leveraged from uIP: - * - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "NyLPC_stdlib.h" -#include "NyLPC_uip.h" -#include "NyLPC_cIPv4.h" -#include "NyLPC_cIPv4Payload_protected.h" -#include "NyLPC_cTcpSocket_protected.h" -#include "NyLPC_cUdpSocket_protected.h" -#include "NyLPC_cTcpListener_protected.h" -#include "NyLPC_cIPv4IComp_protected.h" -#include "NyLPC_cUipService_protected.h" - - - -/**************************************************** - * Socketテーブルに関する宣言 - ***************************************************/ - -#define cSocketTbl_initialize(i_inst,buf) NyLPC_cPtrTbl_initialize(i_inst,buf,NyLPC_cIPv4_MAX_SOCKET) -#define cSocketTbl_finalize(i_inst) - -/** - * 条件に一致する、アクティブなTCPソケットオブジェクトを取得します。 - * この関数は、ローカルIPが一致していると仮定して検索をします。 - * @param i_rip - * リモートIPアドレスを指定します。 - */ -static NyLPC_TcTcpSocket_t* cSocketTbl_getMatchTcpSocket( - NyLPC_TcPtrTbl_t* i_inst, - NyLPC_TUInt16 i_lport, - struct NyLPC_TIPv4Addr i_rip, - NyLPC_TUInt16 i_rport) -{ - NyLPC_TcBaseSocket_t** p=(NyLPC_TcBaseSocket_t**)(i_inst->buf); - NyLPC_TcTcpSocket_t* tp; - int i; - //一致するポートを検索 - for(i=i_inst->size-1;i>=0;i--){ - if(p[i]==NULL || p[i]->_typeid!=NyLPC_TcBaseSocket_TYPEID_TCP_SOCK){ - continue; - } - tp=(NyLPC_TcTcpSocket_t*)p[i]; - if(tp->tcpstateflags==UIP_CLOSED){ - continue; - } - //パラメータの一致チェック - if(i_lport!=tp->uip_connr.lport || i_rport!= tp->uip_connr.rport || i_rip.v!=tp->uip_connr.ripaddr.v) - { - continue; - } - return tp; - } - return NULL; -} -static NyLPC_TcUdpSocket_t* cSocketTbl_getMatchUdpSocket( - NyLPC_TcPtrTbl_t* i_inst, - NyLPC_TUInt16 i_lport) -{ - NyLPC_TcBaseSocket_t** p=(NyLPC_TcBaseSocket_t**)(i_inst->buf); - NyLPC_TcUdpSocket_t* tp; - int i; - //一致するポートを検索 - for(i=i_inst->size-1;i>=0;i--){ - if(p[i]==NULL || p[i]->_typeid!=NyLPC_TcBaseSocket_TYPEID_UDP_SOCK){ - continue; - } - tp=(NyLPC_TcUdpSocket_t*)p[i]; - //パラメータの一致チェック - if(i_lport==tp->uip_udp_conn.lport){ - //unicast - return tp; - } - } - return NULL; -} -static NyLPC_TcUdpSocket_t* cSocketTbl_getMatchMulticastUdpSocket( - NyLPC_TcPtrTbl_t* i_inst, - const struct NyLPC_TIPv4Addr* i_mcast_ip, - NyLPC_TUInt16 i_lport) -{ - NyLPC_TcBaseSocket_t** p=(NyLPC_TcBaseSocket_t**)(i_inst->buf); - NyLPC_TcUdpSocket_t* tp; - int i; - //一致するポートを検索 - for(i=i_inst->size-1;i>=0;i--){ - if(p[i]==NULL || p[i]->_typeid!=NyLPC_TcBaseSocket_TYPEID_UDP_SOCK){ - continue; - } - tp=(NyLPC_TcUdpSocket_t*)p[i]; - //パラメータの一致チェック - if(i_lport!=tp->uip_udp_conn.lport || (!NyLPC_TIPv4Addr_isEqual(i_mcast_ip,&(tp->uip_udp_conn.mcastaddr)))) - { - continue; - } - return tp; - } - return NULL; -} - -/** - * i_port番号に一致するリスナを返します。 - */ -static NyLPC_TcTcpListener_t* cSocketTbl_getListenerByPeerPort(NyLPC_TcPtrTbl_t* i_inst,NyLPC_TUInt16 i_port) -{ - NyLPC_TcBaseSocket_t** p=(NyLPC_TcBaseSocket_t**)(i_inst->buf); - NyLPC_TcTcpListener_t* lp; - int i; - //一致するポートを検索して、acceptをコールする。 - for(i=i_inst->size-1;i>=0;i--){ - if(p[i]==NULL || p[i]->_typeid!=NyLPC_TcBaseSocket_TYPEID_TCP_LISTENER){ - continue; - } - lp=(NyLPC_TcTcpListener_t*)p[i]; - if(lp->_port!=i_port){ - continue; - } - return lp; - } - return NULL; -} -/** - * 指定番号のTCPポートが未使用かを返す。 - * @return - * i_lport番のポートが未使用であればTRUE - */ -static NyLPC_TBool cSocketTbl_isClosedTcpPort( - NyLPC_TcPtrTbl_t* i_inst, - NyLPC_TUInt16 i_lport) -{ - NyLPC_TcBaseSocket_t** p=(NyLPC_TcBaseSocket_t**)(i_inst->buf); - NyLPC_TcTcpSocket_t* tp; - int i; - //一致するポートを検索 - for(i=i_inst->size-1;i>=0;i--){ - if(p[i]==NULL){ - continue; - } - if(p[i]->_typeid!=NyLPC_TcBaseSocket_TYPEID_TCP_SOCK){ - tp=((NyLPC_TcTcpSocket_t*)p[i]); - //TCPソケット && !クローズ && ポート一致なら使用中 - if((tp->tcpstateflags!=UIP_CLOSED) && tp->uip_connr.lport==i_lport){ - return NyLPC_TBool_FALSE; - } - } - if(p[i]->_typeid!=NyLPC_TcBaseSocket_TYPEID_TCP_LISTENER){ - //Listenerソケット && ポート一致なら使用中 - if(((NyLPC_TcTcpListener_t*)p[i])->_port==i_lport){ - return NyLPC_TBool_FALSE; - } - } - } - //未使用 - return NyLPC_TBool_TRUE; -} -/** - * テーブルにある有効なソケットのperiodicをすべて呼び出します。 - */ -static void cSocketTbl_callPeriodic( - NyLPC_TcPtrTbl_t* i_inst) -{ - NyLPC_TcBaseSocket_t** p=(NyLPC_TcBaseSocket_t**)(i_inst->buf); - int i; - for(i=i_inst->size-1;i>=0;i--){ - if(p[i]==NULL){ - continue; - } - switch(p[i]->_typeid){ - case NyLPC_TcBaseSocket_TYPEID_TCP_SOCK: - //downcast! - NyLPC_cTcpSocket_periodic((NyLPC_TcTcpSocket_t*)(p[i])); - break; - case NyLPC_TcBaseSocket_TYPEID_UDP_SOCK: - NyLPC_cUdpSocket_periodic((NyLPC_TcUdpSocket_t*)(p[i])); - break; - default: - continue; - } - } -} - -/** - * テーブルにある有効なソケットのstartを全て呼び出します。 - */ -static void cSocketTbl_callSocketStart( - NyLPC_TcPtrTbl_t* i_inst, - const NyLPC_TcIPv4Config_t* i_cfg) -{ - NyLPC_TcBaseSocket_t** p=(NyLPC_TcBaseSocket_t**)(i_inst->buf); - int i; - for(i=i_inst->size-1;i>=0;i--){ - if(p[i]==NULL){ - continue; - } - switch(p[i]->_typeid){ - case NyLPC_TcBaseSocket_TYPEID_UDP_SOCK: - NyLPC_cUdpSocket_startService((NyLPC_TcUdpSocket_t*)(p[i]),i_cfg); - break; - case NyLPC_TcBaseSocket_TYPEID_TCP_SOCK: - NyLPC_cTcpSocket_startService((NyLPC_TcTcpSocket_t*)(p[i]),i_cfg); - break; - default: - continue; - } - } -} -/** - * テーブルにある有効なソケットのstartを全て呼び出します。 - */ -static void cSocketTbl_callSocketStop( - NyLPC_TcPtrTbl_t* i_inst) -{ - NyLPC_TcBaseSocket_t** p=(NyLPC_TcBaseSocket_t**)(i_inst->buf); - int i; - for(i=i_inst->size-1;i>=0;i--){ - if(p[i]==NULL){ - continue; - } - switch(p[i]->_typeid){ - case NyLPC_TcBaseSocket_TYPEID_UDP_SOCK: - NyLPC_cUdpSocket_stopService((NyLPC_TcUdpSocket_t*)(p[i])); - break; - case NyLPC_TcBaseSocket_TYPEID_TCP_SOCK: - NyLPC_cTcpSocket_stopService((NyLPC_TcTcpSocket_t*)(p[i])); - break; - default: - continue; - } - } -} - -/**************************************************** - * NyLPC_cIPv4 - ***************************************************/ - -/** - * Static関数 - */ - -static void* tcp_rx( - NyLPC_TcIPv4_t* i_inst, - const NyLPC_TcIPv4Payload_t* i_ipp); - -static NyLPC_TBool udp_rx( - NyLPC_TcIPv4_t* i_inst, - NyLPC_TcIPv4Payload_t* i_ipp); - -/** - * See Header file. - */ -void NyLPC_cIPv4_initialize( - NyLPC_TcIPv4_t* i_inst) -{ - //IP制御パケットの為に40バイト以上のシステムTXメモリが必要。 - NyLPC_ArgAssert(NyLPC_cUipService_SYS_TX_BUF_SIZE>40); - //内部テーブルの初期化 - cSocketTbl_initialize(&(i_inst->_socket_tbl),(void**)(i_inst->_socket_array_buf)); - //instanceの初期化 - NyLPC_cMutex_initialize(&(i_inst->_sock_mutex)); - NyLPC_cMutex_initialize(&(i_inst->_listener_mutex)); - i_inst->tcp_port_counter=0; - i_inst->_ref_config=NULL; - return; -} - -/** - * See header file. - */ -void NyLPC_cIPv4_finalize( - NyLPC_TcIPv4_t* i_inst) -{ - cSocketTbl_finalize(&(i_inst->_socket_tbl)); - NyLPC_cMutex_finalize(&(i_inst->_sock_mutex)); - NyLPC_cMutex_finalize(&(i_inst->_listener_mutex)); - return; -} - -/** - * See header file. - */ -void NyLPC_cIPv4_start( - NyLPC_TcIPv4_t* i_inst, - const NyLPC_TcIPv4Config_t* i_ref_configlation) -{ - NyLPC_ArgAssert(i_ref_configlation!=NULL); - //リストの初期化、ここでするべき?しないべき? - i_inst->_ref_config=i_ref_configlation; - //configulationのアップデートを登録されてるソケットに通知 - cSocketTbl_callSocketStart(&(i_inst->_socket_tbl),i_ref_configlation); - return; -} - -/** - * See header file. - */ -void NyLPC_cIPv4_stop( - NyLPC_TcIPv4_t* i_inst) -{ - cSocketTbl_callSocketStop(&(i_inst->_socket_tbl)); - i_inst->_ref_config=NULL; - return; -} - -/** - * See header file. - */ -NyLPC_TBool NyLPC_cIPv4_addSocket( - NyLPC_TcIPv4_t* i_inst, - NyLPC_TcBaseSocket_t* i_sock) -{ - //当面、stop中しか成功しない。 - NyLPC_Assert(!NyLPC_cUipService_isRun()); - return NyLPC_cPtrTbl_add(&(i_inst->_socket_tbl),i_sock)>=0; -} - -/** - * See header file. - */ -NyLPC_TBool NyLPC_cIPv4_removeSocket( - NyLPC_TcIPv4_t* i_inst, - NyLPC_TcBaseSocket_t* i_sock) -{ - NyLPC_TInt16 i; - NyLPC_Assert(!NyLPC_cUipService_isRun()); - i=NyLPC_cPtrTbl_getIndex(&(i_inst->_socket_tbl),i_sock); - if(i>=0){ - NyLPC_cPtrTbl_remove(&(i_inst->_socket_tbl),i); - return NyLPC_TBool_TRUE; - } - return NyLPC_TBool_FALSE; -} - - -#define IS_START(i_inst) ((i_inst)->_ref_config!=NULL) - -/** - * 稼動時に、1s置きに呼び出す関数です。 - */ -void NyLPC_cIPv4_periodec(NyLPC_TcIPv4_t* i_inst) -{ - cSocketTbl_callPeriodic(&(i_inst->_socket_tbl)); -} - - -/** - * IPv4ペイロードを処理する関数。 - * この関数は、パケット受信タスクから実行します。 - * @param i_rx - * 先頭ポインタ。 - * @return - * TRUEなら、i_rxに応答パケットをセットして返します。 - */ -void* NyLPC_cIPv4_rx(NyLPC_TcIPv4_t* i_inst,const void* i_rx,NyLPC_TUInt16 i_rx_size) -{ - NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst; - NyLPC_TcIPv4Payload_t ipv4; - //NOT開始状態なら受け付けないよ。 - if(!IS_START(i_inst)){ - NyLPC_OnErrorGoto(ERROR_DROP); - } - - NyLPC_cIPv4Payload_initialize(&ipv4); - //IPフラグメントを読出し用にセットする。 - if(!NyLPC_cIPv4Payload_attachRxBuf(&ipv4,i_rx,i_rx_size)) - { - NyLPC_OnErrorGoto(ERROR_DROP); - } - switch(ipv4.header->proto) - { - case UIP_PROTO_TCP: - //TCP受信処理 - return tcp_rx(i_inst,&ipv4); - case UIP_PROTO_UDP: - //UDP処理 - udp_rx(i_inst,&ipv4);//r - return NyLPC_TBool_FALSE; - case UIP_PROTO_ICMP: - return NyLPC_cIPv4IComp_rx(&(inst->_icomp),&ipv4); - } - return NULL; -ERROR_DROP: - return NULL; -} - -NyLPC_TUInt16 NyLPC_cIPv4_getNewPortNumber(NyLPC_TcIPv4_t* i_inst) -{ - NyLPC_TUInt16 i,n; - for(i=0;i<0x0fff;i--){ - i_inst->tcp_port_counter=(i_inst->tcp_port_counter+1)%0x0fff; - n=i_inst->tcp_port_counter+49152; - if(cSocketTbl_isClosedTcpPort(&i_inst->_socket_tbl,n)) - { - return n; - } - } - return 0; -} - - -/********************************************************************** - * - * packet handler - * - **********************************************************************/ - - -static void* tcp_rx( - NyLPC_TcIPv4_t* i_inst, - const NyLPC_TcIPv4Payload_t* i_ipp) -{ - NyLPC_TcTcpSocket_t* sock; - NyLPC_TcTcpListener_t* listener; - - //自分自身のIPに対する呼び出し? - if(!NyLPC_TIPv4Addr_isEqual(&(i_ipp->header->destipaddr),&(i_inst->_ref_config->ip_addr))) - { - //自分以外のパケットはドロップ - goto DROP; - } - //チェックサムの計算 - if((NyLPC_TIPv4Header_makeTcpChecksum(i_ipp->header) != 0xffff)) - { - //受信エラーのあるパケットはドロップ - goto DROP; - } - //アクティブなTCPソケットを探す。 - sock=cSocketTbl_getMatchTcpSocket(&(i_inst->_socket_tbl),i_ipp->payload.tcp->destport,i_ipp->header->srcipaddr,i_ipp->payload.tcp->srcport); - if(sock!=NULL) - { - //既存の接続を処理 - return NyLPC_cTcpSocket_parseRx(sock,i_ipp); - } - - //未知の接続 - if(!NyLPC_cPtrTbl_hasEmpty(&(i_inst->_socket_tbl))){ - //ソケットテーブルが不十分。RST送信 - return NyLPC_cTcpSocket_allocTcpReverseRstAck(i_ipp); - } - //このポートに対応したListenerを得る。 - listener=cSocketTbl_getListenerByPeerPort(&(i_inst->_socket_tbl),i_ipp->payload.tcp->destport); - if(listener==NULL){ - //Listen対象ではない。RST送信 - return NyLPC_cTcpSocket_allocTcpReverseRstAck(i_ipp); - } - //リスナにソケットのバインドを依頼する。 - NyLPC_cTcpListener_synPacket(listener,i_ipp); - return NULL;//LISTEN成功。送信データなし -DROP: - return NULL; -} - - - -static NyLPC_TBool udp_rx( - NyLPC_TcIPv4_t* i_inst, - NyLPC_TcIPv4Payload_t* i_ipp) -{ - NyLPC_TcUdpSocket_t* sock=NULL; - if(!NyLPC_TIPv4Addr_isEqual(&(i_ipp->header->destipaddr),&(i_inst->_ref_config->ip_addr))) - { - sock=cSocketTbl_getMatchUdpSocket(&(i_inst->_socket_tbl),i_ipp->payload.udp->destport); - }else{ - if(NyLPC_TIPv4Addr_isEqualWithMask(&(i_ipp->header->destipaddr),&NyLPC_TIPv4Addr_MULTICAST,&NyLPC_TIPv4Addr_MULTICAST_MASK)){ - //MultiCast? - //マルチキャストに参加している&&portの一致するソケットを検索 - sock=cSocketTbl_getMatchMulticastUdpSocket(&(i_inst->_socket_tbl),&(i_ipp->header->destipaddr),i_ipp->payload.udp->destport); - }else if(!NyLPC_TIPv4Addr_isEqual(&(i_ipp->header->destipaddr),&NyLPC_TIPv4Addr_BROADCAST)){ - //Broadcast? - sock=cSocketTbl_getMatchUdpSocket(&(i_inst->_socket_tbl),i_ipp->payload.udp->destport); - } - } - if(sock==NULL) - { - goto DROP; - } - //パケットのエラーチェック - if((NyLPC_TIPv4Header_makeTcpChecksum(i_ipp->header) != 0xffff)) - { - //受信エラーのあるパケットはドロップ - goto DROP; - } - //既存の接続を処理 - return NyLPC_cUdpSocket_parseRx(sock,i_ipp); -DROP: - return NyLPC_TBool_FALSE; -} - -
--- a/core/uip/NyLPC_cIPv4.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,233 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - * - * Parts of this file were leveraged from uIP: - * - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/** - * @file - * このファイルは、NyLPC_cIPv4IPv4クラスを定義します。 - */ -#ifndef NYLPC_CIPV4TCP_H_ -#define NYLPC_CIPV4TCP_H_ - - - -#include "NyLPC_uip.h" -#include "NyLPC_cTcpListener.h" -#include "NyLPC_cTcpSocket.h" -#include "NyLPC_cIPv4Config.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - - - -/********************************************************************** - * - * class NyLPC_TcIPv4 - * - **********************************************************************/ -#include "NyLPC_cIPv4_typedef.h" - -///** -// * 環境定数です。NyLPC_TcTcpListenerインスタンスリストの数を設定します。 -// * この値は、NyLPC_cTcpListenerクラスの最大生成数になります。 -// */ -//#define NyLPC_cIPv4_MAX_TCP_LISTENER 10 - -/** - * Socketの最大生成数 - * この値は、NyLPC_cTcpSocketクラス,NyLPC_cTcpListener,NyLPC_cUdpの最大生成数になります。 - */ -#define NyLPC_cIPv4_MAX_SOCKET 10 - - - -/** - * NyLPC_TcIPv4クラスの構造体です。 - */ -struct NyLPC_TcIPv4 -{ - /** 参照しているIPスタックの環境値です。この値は、start関数が設定します。*/ - const NyLPC_TcIPv4Config_t* _ref_config; - /** ソケットリソースの保護用。コールバック関数から呼び出されるソケット内部のリソース保護に使用する共通MUTEX*/ - NyLPC_TcMutex_t _sock_mutex; - /** リスナリソースの保護用。コールバック関数から呼び出されるソケット内部のリソース保護に使用する共通MUTEX*/ - NyLPC_TcMutex_t _listener_mutex; - /** NyLPC_cTcpSocketを管理するポインタリストです。*/ - NyLPC_TcPtrTbl_t _socket_tbl; - /** _socket_tblが使用するメモリ領域です。*/ - NyLPC_TcBaseSocket_t* _socket_array_buf[NyLPC_cIPv4_MAX_SOCKET]; - /** 0-0xfffまでを巡回するカウンタ*/ - NyLPC_TUInt16 tcp_port_counter; -}; - -/** - * コンストラクタです。インスタンスを初期化します。 - * @param i_inst - * 初期化するインスタンス - */ -void NyLPC_cIPv4_initialize( - NyLPC_TcIPv4_t* i_inst); - -/** - * デストラクタです。インスタンスを破棄して、確保している動的リソースを元に戻します。 - * @param i_inst - * 破棄するインスタンス - * initializeが成功したインスタンスだけが指定できます。 - */ -void NyLPC_cIPv4_finalize( - NyLPC_TcIPv4_t* i_inst); - -/** - * この関数は、インスタンスにTCP/IP処理の準備をするように伝えます。 - * @param i_inst - * 操作するインスタンス - * @param i_ref_configlation - * IPの環境値をセットしたオブジェクトを指定します。 - * この値は、stop関数を実行するまでの間、維持してください。 - */ -void NyLPC_cIPv4_start( - NyLPC_TcIPv4_t* i_inst, - const NyLPC_TcIPv4Config_t* i_ref_configlation); - -/** - * この関数はTCP/IP処理を停止することを伝えます。 - * @param i_inst - * 操作するインスタンス。 - * startで開始済みで無ければなりません。 - * @note - * 現在、接続中の接続に対する保障は未実装です。安全に使用することが出来ません。 - */ -void NyLPC_cIPv4_stop( - NyLPC_TcIPv4_t* i_inst); - -/** - * この関数は、NyLPC_TcBaseSocketオブジェクトを管理リストへ追加します。 - * @param i_inst - * 操作するインスタンス。 - * @param i_sock - * 追加するインスタンスのポインタ - * @return - * 追加が成功するとTRUEを返します。 - */ -NyLPC_TBool NyLPC_cIPv4_addSocket( - NyLPC_TcIPv4_t* i_inst, - NyLPC_TcBaseSocket_t* i_sock); - -/** - * この関数は、NyLPC_cTcpSocketオブジェクトを管理リストから除外します。 - * NyLPC_TcBaseSocketが使います。 - * @param i_inst - * 操作するインスタンス。 - * @param i_sock - * 削除するインスタンスのポインタ - * @return - * 削除が成功するとTRUEを返します。 - */ -NyLPC_TBool NyLPC_cIPv4_removeSocket( - NyLPC_TcIPv4_t* i_inst, - NyLPC_TcBaseSocket_t* i_sock); - - -/** - * この関数は、RxIPパケットを処理して、管理下のインスタンスに処理を依頼します。 - * 現在の関数は、i_rxに最大64バイトの応答パケットのイメージを格納することがあります。 - * 応答パケットは、RXに対するACKパケットです。 - * 格納の有無は戻り値を確認することで判ります。 - * この関数はstart-stopの間だけコールすることが出来ます。start,stopと非同期に実行しないでください。 - * @param i_inst - * 操作するインスタンスです。 - * @param i_rx - * RXパケットを格納したメモリアドレスです。 - * 最低でも、64バイト以上のサイズが必要です。 - * @param i_rx_size - * i_rxに格納したデータのサイズです。 - * @return - * 応答パケットを格納したメモリです。 - */ -void* NyLPC_cIPv4_rx(NyLPC_TcIPv4_t* i_inst,const void* i_rx,NyLPC_TUInt16 i_rx_size); -/** - * この関数は、定期的にインスタンスへ実行機会を与える関数です。 - * TCPの再送、無通信タイムアウトなどを処理します。 - * 約1秒おきに呼び出してください。 - * @param i_inst - * 操作するインスタンスです。 - */ -void NyLPC_cIPv4_periodec(NyLPC_TcIPv4_t* i_inst); - -/** - * ソケットリソースとコールバックの排他処理に使う共通MUTEXを返します。 - * このMutexはソケット同士の干渉が起こらない処理にだけ使ってください。 - */ -#define NyLPC_cIPv4_getSockMutex(i_inst) (&((i_inst)->_sock_mutex)) -/** - * リスナーリソースとコールバックの排他処理に使う共通MUTEXを返します。 - */ -#define NyLPC_cIPv4_getListenerMutex(i_inst) (&((i_inst)->_listener_mutex)) - -/** - * ポート0で使用するポート番号を返します。 - * @return - * 49152 - (49152+0x0ffff)番までのポートのうち、使用中でないポート番号を返します。 - * エラー時は0です。 - */ -NyLPC_TUInt16 NyLPC_cIPv4_getNewPortNumber(NyLPC_TcIPv4_t* i_inst); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif
--- a/core/uip/NyLPC_cIPv4Arp.c Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,334 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - * - * Parts of this file were leveraged from uIP: - * - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "NyLPC_cIPv4Arp.h" -#include "NyLPC_uip.h" -#include "NyLPC_cUipService_protected.h" -#include <string.h> - - -/** - * The maxium age of ARP table entries measured in 10ths of seconds. - * - * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD - * default). - */ -#define UIP_ARP_MAXAGE 120 - - -//static const struct NyLPC_TEthAddr broadcast_ethaddr = { { 0xff, 0xff, 0xff,0xff, 0xff, 0xff } }; -//static const struct NyLPC_TIPv4Addr broadcast_ipaddr = { 0xfffffff }; - - - - -static void uip_arp_update(NyLPC_TcIPv4Arp_t* i_inst,const struct NyLPC_TIPv4Addr* ipaddr,const struct NyLPC_TEthAddr *ethaddr); -/*-----------------------------------------------------------------------------------*/ -/** - * Initialize the ARP module. - * - */ -/*-----------------------------------------------------------------------------------*/ -void NyLPC_cIPv4Arp_initialize(NyLPC_TcIPv4Arp_t* i_inst,const NyLPC_TcIPv4Config_t* i_ref_config) -{ - int i; - struct NyLPC_TArpTableItem* tbl=i_inst->arp_table; - i_inst->_cfg = i_ref_config; - i_inst->arptime = 0; - i_inst->tmpage = 0; - for (i = 0; i < NyLPC_TcIPv4Arp_ARPTAB_SIZE; ++i) { - memset(&(tbl[i].ipaddr), 0, sizeof(struct NyLPC_TIPv4Addr)); - } -} -/*-----------------------------------------------------------------------------------*/ -/** - * Periodic ARP processing function. - * - * This function performs periodic timer processing in the ARP module - * and should be called at regular intervals. The recommended interval - * is 10 seconds between the calls. - * - */ -/*-----------------------------------------------------------------------------------*/ -void NyLPC_cIPv4Arp_periodic(NyLPC_TcIPv4Arp_t* i_inst) -{ - struct NyLPC_TArpTableItem* tbl=i_inst->arp_table; - struct NyLPC_TArpTableItem* tabptr; - int i; - i_inst->arptime++; - for (i = 0; i < NyLPC_TcIPv4Arp_ARPTAB_SIZE; ++i) { - tabptr = &tbl[i]; - if (tabptr->ipaddr.v != 0 && i_inst->arptime - tabptr->time >= UIP_ARP_MAXAGE) - { - tabptr->ipaddr.v = 0; - } - } - -} -/*-----------------------------------------------------------------------------------*/ -/** - * ARP processing for incoming IP packets - * - * This function should be called by the device driver when an IP - * packet has been received. The function will check if the address is - * in the ARP cache, and if so the ARP cache entry will be - * refreshed. If no ARP cache entry was found, a new one is created. - * - * This function expects an IP packet with a prepended Ethernet header - * in the uip_buf[] buffer, and the length of the packet in the global - * variable uip_len. - */ -/*-----------------------------------------------------------------------------------*/ -void NyLPC_cIPv4Arp_incomingIp(NyLPC_TcIPv4Arp_t* i_inst,const struct NyLPC_TEthernetIIHeader* i_eth,struct NyLPC_TIPv4Addr i_ip_src) -{ - //EtherとIPv4の値を読みだす。 - /* Only insert/update an entry if the source IP address of the - incoming IP packet comes from a host on the local network. */ - if ((i_ip_src.v & i_inst->_cfg->netmask.v) != (i_inst->_cfg->ip_addr.v & i_inst->_cfg->netmask.v)) { - return; - } - uip_arp_update(i_inst,&(i_ip_src), &(i_eth->src)); - return; -} -/** - * ARP processing for incoming ARP packets. - * - * This function should be called by the device driver when an ARP - * packet has been received. The function will act differently - * depending on the ARP packet type: if it is a reply for a request - * that we previously sent out, the ARP cache will be filled in with - * the values from the ARP reply. If the incoming ARP packet is an ARP - * request for our IP address, an ARP reply packet is created and put - * into the uip_buf[] buffer. - * - * When the function returns, the value of the global variable uip_len - * indicates whether the device driver should send out a packet or - * not. If uip_len is zero, no packet should be sent. If uip_len is - * non-zero, it contains the length of the outbound packet that is - * present in the uip_buf[] buffer. - * - * This function expects an ARP packet with a prepended Ethernet - * header in the uip_buf[] buffer, and the length of the packet in the - * global variable uip_len. - */ - - -/** - * ARPパケットの読出し用構造体 - */ -struct TArpPacketPtr -{ - struct NyLPC_TEthernetIIHeader header; - struct NyLPC_TArpHeader arp; -}PACK_STRUCT_END; - -/** - * arpパケットを処理します。 - */ -void* NyLPC_cIPv4Arp_rx(NyLPC_TcIPv4Arp_t* i_inst,const struct NyLPC_TArpHeader* i_arp, NyLPC_TUInt16 i_len, NyLPC_TUInt16* o_tx_len) -{ - struct NyLPC_TArpHeader* arp_tx; - if (i_len < sizeof(struct NyLPC_TArpHeader)) { - return NULL; - } - const NyLPC_TcIPv4Config_t* cfg=i_inst->_cfg; - switch (i_arp->opcode) { - case NyLPC_HTONS(ARP_REQUEST): - /* ARP request. If it asked for our address, we send out a reply. */ - if (NyLPC_TIPv4Addr_isEqual(&(i_arp->dipaddr), &(cfg->ip_addr))) { - /* First, we register the one who made the request in our ARP - table, since it is likely that we will do more communication - with this host in the future. */ - uip_arp_update(i_inst,&(i_arp->sipaddr), &i_arp->shwaddr); - //イーサネットヘッダもいじくるから - arp_tx=(struct NyLPC_TArpHeader*)NyLPC_cUipService_allocSysTxBuf(); - - /* The reply opcode is 2. */ - arp_tx->hwtype =i_arp->hwtype; - arp_tx->protocol =i_arp->protocol; - arp_tx->hwlen =i_arp->hwlen; - arp_tx->protolen =i_arp->protolen; - arp_tx->opcode = NyLPC_HTONS(2); - memcpy(arp_tx->dhwaddr.addr, i_arp->shwaddr.addr, 6); - memcpy(arp_tx->shwaddr.addr, cfg->eth_mac.addr, 6); - arp_tx->dipaddr = i_arp->sipaddr; - arp_tx->sipaddr = cfg->ip_addr; - *o_tx_len=NyLPC_TEthernetIIHeader_setArpTx((((struct NyLPC_TEthernetIIHeader*)arp_tx)-1),&(i_inst->_cfg->eth_mac)); - -// /* The reply opcode is 2. */ -// i_arp->opcode = NyLPC_HTONS(2); -// -// memcpy(i_arp->dhwaddr.addr, i_arp->shwaddr.addr, 6); -// memcpy(i_arp->shwaddr.addr, cfg->eth_mac.addr, 6); -// -// i_arp->dipaddr = i_arp->sipaddr; -// i_arp->sipaddr = cfg->ip_addr; - return arp_tx; - } - break; - case NyLPC_HTONS(ARP_REPLY): - // ARP reply. We insert or update the ARP table if it was meant for us. - if (NyLPC_TIPv4Addr_isEqual(&(i_arp->dipaddr),&(cfg->ip_addr))) { - uip_arp_update(i_inst,&(i_arp->sipaddr), &i_arp->shwaddr); - } - break; - } - return NULL; -} -/** - * Prepend Ethernet header to an outbound IP packet and see if we need - * to send out an ARP request. - * - * This function should be called before sending out an IP packet. The - * function checks the destination IP address of the IP packet to see - * what Ethernet MAC address that should be used as a destination MAC - * address on the Ethernet. - * - * If the destination IP address is in the local network (determined - * by logical ANDing of netmask and our IP address), the function - * checks the ARP cache to see if an entry for the destination IP - * address is found. If so, an Ethernet header is prepended and the - * function returns. If no ARP cache entry is found for the - * destination IP address, the packet in the uip_buf[] is replaced by - * an ARP request packet for the IP address. The IP packet is dropped - * and it is assumed that they higher level protocols (e.g., TCP) - * eventually will retransmit the dropped packet. - * - * If the destination IP address is not on the local network, the IP - * address of the default router is used instead. - * - * When the function returns, a packet is present in the uip_buf[] - * buffer, and the length of the packet is in the global variable - * uip_len. - */ - -/** - * IPアドレス-MACアドレス交換 - */ -const struct NyLPC_TEthAddr* NyLPC_cIPv4Arp_IPv4toEthAddr(NyLPC_TcIPv4Arp_t* i_inst,const struct NyLPC_TIPv4Addr i_ip_addr) -{ - int i; - struct NyLPC_TArpTableItem *tabptr; - //ARPテーブルから検索 - for (i = NyLPC_TcIPv4Arp_ARPTAB_SIZE - 1; i >= 0; i--) { - tabptr = &i_inst->arp_table[i]; - if (NyLPC_TIPv4Addr_isEqual(&i_ip_addr,&(tabptr->ipaddr))) { - return &tabptr->ethaddr; - } - } - return NULL; -} - - - - - - - -static void uip_arp_update(NyLPC_TcIPv4Arp_t* i_inst,const struct NyLPC_TIPv4Addr* ipaddr,const struct NyLPC_TEthAddr *ethaddr) -{ - register struct NyLPC_TArpTableItem *tabptr; - int i,c; - /* Walk through the ARP mapping table and try to find an entry to - update. If none is found, the IP -> MAC address mapping is - inserted in the ARP table. */ - for (i = 0; i < NyLPC_TcIPv4Arp_ARPTAB_SIZE; ++i) { - tabptr = &i_inst->arp_table[i]; - /* Only check those entries that are actually in use. */ - if (tabptr->ipaddr.v != 0) { - /* Check if the source IP address of the incoming packet matches - the IP address in this ARP table entry. */ - if (ipaddr->v == tabptr->ipaddr.v) { - /* An old entry found, update this and return. */ - memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); - tabptr->time = i_inst->arptime; - - return; - } - } - } - - /* If we get here, no existing ARP table entry was found, so we - create one. */ - /* First, we try to find an unused entry in the ARP table. */ - for (i = 0; i < NyLPC_TcIPv4Arp_ARPTAB_SIZE; ++i) { - tabptr = &i_inst->arp_table[i]; - if (tabptr->ipaddr.v == 0) { - break; - } - } - - /* If no unused entry is found, we try to find the oldest entry and - throw it away. */ - if (i == NyLPC_TcIPv4Arp_ARPTAB_SIZE) { - i_inst->tmpage = 0; - c = 0; - for (i = 0; i < NyLPC_TcIPv4Arp_ARPTAB_SIZE; ++i) { - tabptr = &i_inst->arp_table[i]; - if (i_inst->arptime - tabptr->time > i_inst->tmpage) { - i_inst->tmpage = i_inst->arptime - tabptr->time; - c = i; - } - } - i = c; - tabptr = &i_inst->arp_table[i]; - } - - /* Now, i is the ARP table entry which we will fill with the new information. */ - tabptr->ipaddr = *ipaddr; - memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); - tabptr->time = i_inst->arptime; -} - -
--- a/core/uip/NyLPC_cIPv4Arp.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,115 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - * - * Parts of this file were leveraged from uIP: - * - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef NYLPC_CIPV4ARP_H_ -#define NYLPC_CIPV4ARP_H_ -#include "NyLPC_cIPv4Config.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -struct NyLPC_TArpTableItem -{ - struct NyLPC_TIPv4Addr ipaddr; - struct NyLPC_TEthAddr ethaddr; - NyLPC_TUInt8 time; -}; - -/********************************************************************** - * - * class NyLPC_TcIPv4Config - * - **********************************************************************/ - - -#define NyLPC_TcIPv4Arp_ARPTAB_SIZE 8 - - -typedef struct NyLPC_TcIPv4Arp NyLPC_TcIPv4Arp_t; - -/** - * NyLPC_TcIPv4クラスの構造体です。 - */ -struct NyLPC_TcIPv4Arp -{ - const NyLPC_TcIPv4Config_t* _cfg; - NyLPC_TUInt8 arptime; - NyLPC_TUInt8 tmpage; - struct NyLPC_TArpTableItem arp_table[NyLPC_TcIPv4Arp_ARPTAB_SIZE]; -}; - -void NyLPC_cIPv4Arp_initialize(NyLPC_TcIPv4Arp_t* i_inst,const NyLPC_TcIPv4Config_t* i_ref_config); -#define NyLPC_cIPv4Arp_finalize(i_inst) -void NyLPC_cIPv4Arp_periodic(NyLPC_TcIPv4Arp_t* i_inst); -void NyLPC_cIPv4Arp_incomingIp(NyLPC_TcIPv4Arp_t* i_inst,const struct NyLPC_TEthernetIIHeader* i_eth,struct NyLPC_TIPv4Addr i_ip_src); -/** - * ARPメッセージを処理します。 - * @param o_tx_len - * 戻り値がある場合そのサイズ - * @return - * 応答パケットを格納したcUipService_allocBufで確保したメモリ - */ -void* NyLPC_cIPv4Arp_rx(NyLPC_TcIPv4Arp_t* i_inst,const struct NyLPC_TArpHeader* i_arp, NyLPC_TUInt16 i_len, NyLPC_TUInt16* o_tx_len); -const struct NyLPC_TEthAddr* NyLPC_cIPv4Arp_IPv4toEthAddr(NyLPC_TcIPv4Arp_t* i_inst,const struct NyLPC_TIPv4Addr i_ip_addr); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - - -#endif /* NYLPC_CIPV4ARP_H_ */
--- a/core/uip/NyLPC_cIPv4Config.c Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - *********************************************************************************/ -#include "NyLPC_uip.h" -#include "NyLPC_cIPv4Payload_protected.h" -#include "NyLPC_cIPv4Config.h" - -/** イーサネットヘッダのサイズ値*/ -#define UIP_ETHERHEADER_LEN 14 - -/** - * See header file. - */ -void NyLPC_cIPv4Config_initialzeForEthernet(NyLPC_TcIPv4Config_t* i_inst,const struct NyLPC_TEthAddr* i_ether_addr,NyLPC_TUInt16 i_ether_frame_len) -{ - i_inst->ip_addr=i_inst->netmask=i_inst->dr_addr=NyLPC_TIPv4Addr_ZERO; - i_inst->eth_mac=*i_ether_addr; - //mssの計算 - i_inst->default_mss=i_ether_frame_len-(UIP_ETHERHEADER_LEN+UIP_TCPH_LEN + UIP_IPH_LEN); - return; -} -void NyLPC_cIPv4Config_initialzeCopy(NyLPC_TcIPv4Config_t* i_inst,const NyLPC_TcIPv4Config_t* i_src) -{ - memcpy(i_inst,i_src,sizeof(NyLPC_TcIPv4Config_t)); -} -/** - * See header file. - */ -void NyLPC_cIPv4Config_setDefaultRoute(NyLPC_TcIPv4Config_t* i_inst,const struct NyLPC_TIPv4Addr* i_dr_addr) -{ - i_inst->dr_addr=*i_dr_addr; - return; -} - -/** - * See header file. - */ -void NyLPC_cIPv4Config_setIp(NyLPC_TcIPv4Config_t* i_inst,const struct NyLPC_TIPv4Addr* i_ipaddr,const struct NyLPC_TIPv4Addr* i_netmask) -{ - i_inst->ip_addr=*i_ipaddr; - i_inst->netmask=*i_netmask; - return; -} - -/** - * See header file. - */ -NyLPC_TBool NyLPC_cIPv4Config_isLocalIP(const NyLPC_TcIPv4Config_t* i_inst,const struct NyLPC_TIPv4Addr* i_target_ip) -{ - return NyLPC_TIPv4Addr_isEqualWithMask(&(i_inst->ip_addr),i_target_ip,&(i_inst->netmask)); -}
--- a/core/uip/NyLPC_cIPv4Config.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,134 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - *********************************************************************************/ -/** - * @file - * このファイルは、NyLPC_cIPv4Configクラスを定義します。 - */ -#ifndef NYLPC_CIPV4CONFIG_H_ -#define NYLPC_CIPV4CONFIG_H_ - - -#include "NyLPC_uip.h" - -/** - * クラス型を定義します。 - * NyLPC_cIPv4Configクラスは、IPと、下位のネットワーク層の設定を保持します。 - * 関連するオブジェクトが、ネットワーク設定を問い合わせる為に使います。 - */ -typedef struct NyLPC_TcIPv4Config NyLPC_TcIPv4Config_t; - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ -/********************************************************************** - * - * class NyLPC_TcIPv4Config - * - **********************************************************************/ - - - - -/** - * NyLPC_TcIPv4Configクラスの構造体です。 - */ -struct NyLPC_TcIPv4Config -{ - /** イーサネットアドレスを格納します。 */ - struct NyLPC_TEthAddr eth_mac; - /** IPアドレスを格納します。Network orderです。 */ - struct NyLPC_TIPv4Addr ip_addr; - /** ネットマスクを格納します。Network orderです。 */ - struct NyLPC_TIPv4Addr netmask; - /** デフォルトゲートウェイアドレスを格納します。Network orderです。 */ - struct NyLPC_TIPv4Addr dr_addr; - /** デフォルトMMSサイズです。送信パケットのMSS値、受信パケットのデフォルトMSS値として使います。 */ - NyLPC_TUInt16 default_mss; -}; - -#define NyLPC_TcIPv4Config_getEtherMac000120203(v)(((v)->eth_mac.addr[0]<<24)|((v)->eth_mac.addr[1]<<16)|((v)->eth_mac.addr[2]<<8)|((v)->eth_mac.addr[3]<<0)) -#define NyLPC_TcIPv4Config_getEtherMac0405xxxx(v) (((v)->eth_mac.addr[4]<<24)|((v)->eth_mac.addr[5]<<16)) - -/** - * コンストラクタです。 - * イーサネット用にコンフィギュレーションを初期化します。 - * @param i_inst - * 初期化するインスタンスです。 - * @param i_ether_frame_len - * イーサネットフレームのサイズ。この数値から、MSSのデフォルト値を計算します。 - */ -void NyLPC_cIPv4Config_initialzeForEthernet(NyLPC_TcIPv4Config_t* i_inst,const struct NyLPC_TEthAddr* i_ether_addr,NyLPC_TUInt16 i_ether_frame_len); - -/** - * コピーコンストラクタ - */ -void NyLPC_cIPv4Config_initialzeCopy(NyLPC_TcIPv4Config_t* i_inst,const NyLPC_TcIPv4Config_t* i_src); - - -/** - * デストラクタです。インスタンスを破棄して、確保している動的リソースを元に戻します。 - * @param i_inst - * 破棄するインスタンスです。 - * initializeに成功したインスタンスだけが指定できます。 - */ -#define NyLPC_cIPv4Config_finalize(i_inst) - -/** - * この関数は、IPのデフォルトゲートウェイを設定します。dr_addrの値を更新します。 - * @param i_inst - * 操作するインスタンスです。 - * @param i_dr_addr - * 設定するIPアドレスを格納したアドレスです。 - */ -void NyLPC_cIPv4Config_setDefaultRoute(NyLPC_TcIPv4Config_t* i_inst,const struct NyLPC_TIPv4Addr* i_dr_addr); - -/** - * この関数は、ローカルIPアドレスとネットマスクを設定します。 - * @param i_inst - * 操作するインスタンスです。 - * @param i_ipaddr - * 設定するIPアドレスを格納したアドレスです。 - * @param i_netmask - * 設定するネットマスクを格納したアドレスです。 - */ -void NyLPC_cIPv4Config_setIp(NyLPC_TcIPv4Config_t* i_inst,const struct NyLPC_TIPv4Addr* i_ipaddr,const struct NyLPC_TIPv4Addr* i_netmask); - -/** - * この関数は、i_target_ipが、現在のIPアドレスに対するローカルアドレスであるかを返します。 - * @param i_inst - * 操作するインスタンスです。 - * @param i_target_ip - * 確認するIPアドレスです。 - * @return - * i_target_ipがローカルIPアドレスなら、TRUEを返します。 - */ -NyLPC_TBool NyLPC_cIPv4Config_isLocalIP(const NyLPC_TcIPv4Config_t* i_inst,const struct NyLPC_TIPv4Addr* i_target_ip); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif
--- a/core/uip/NyLPC_cIPv4IComp.c Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - * - * Parts of this file were leveraged from uIP: - * - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "NyLPC_cIPv4IComp_protected.h" -#include "NyLPC_cUipService_protected.h" -#define ICMP_ECHO_REPLY 0 -#define ICMP_ECHO 8 - - - -NyLPC_TBool NyLPC_cIPv4IComp_initialize( - NyLPC_TcIPv4IComp_t* i_inst, - const NyLPC_TcIPv4Config_t* i_ref_config) -{ - i_inst->_ref_config=i_ref_config; - return NyLPC_TBool_TRUE; -} -void NyLPC_cIPv4IComp_finalize( - NyLPC_TcIPv4IComp_t* i_inst) -{ - return; -} -/** - * ヘッダブロックの後ろにあるIPペイロードのアドレスを返します。 - */ -#define NyLPC_TIPv4Header_getHeaderSize(i) (((i)->vhl & 0x0f)*4) - -void* NyLPC_cIPv4IComp_rx( - const NyLPC_TcIPv4IComp_t* i_inst, - const NyLPC_TcIPv4Payload_t* i_ipp) -{ - NyLPC_TUInt16 tx_size; - struct NyLPC_TIPv4Header* tx; - struct NyLPC_TIcmpHeader* payload; - const struct NyLPC_TIPv4Addr* my_ip=&(i_inst->_ref_config->ip_addr); - - if (NyLPC_TIPv4Addr_isEqual(&(i_inst->_ref_config->ip_addr),&NyLPC_TIPv4Addr_ZERO)) - { - /* If we are configured to use ping IP address configuration and - hasn't been assigned an IP address yet, we accept all ICMP - packets. */ - } else { - /* Check if the packet is destined for our IP address. */ - if (!NyLPC_TIPv4Addr_isEqual(&(i_ipp->header->destipaddr),my_ip)) - { - return NyLPC_TBool_FALSE; - } - } - // ICMP echo (i.e., ping) processing. This is simple, we only change the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP checksum before we return the packet. - if (i_ipp->payload.icmp->type != ICMP_ECHO) - { - return NyLPC_TBool_FALSE; - } - //返送パケットの取得 - tx=(struct NyLPC_TIPv4Header*)NyLPC_cUipService_allocTxBuf(NyLPC_NTOHS(i_ipp->header->len16),&tx_size); - if(tx==NULL){ - return NyLPC_TBool_FALSE; - } - //パケットサイズのチェック - if(tx_size<NyLPC_NTOHS(i_ipp->header->len16)){ - NyLPC_cUipService_releaseTxBuf(tx); - return NyLPC_TBool_FALSE; - } - //返送パケットの構築 - ; - - //複製 - memcpy(tx,i_ipp->header,NyLPC_NTOHS(i_ipp->header->len16)); - - //ペイロードの編集 - payload=(struct NyLPC_TIcmpHeader*)(((NyLPC_TUInt8*)tx)+NyLPC_TIPv4Header_getHeaderSize(tx)); - payload->type = ICMP_ECHO_REPLY; - //update checksum - if (payload->icmpchksum >= NyLPC_HTONS(0xffff - (ICMP_ECHO << 8))) { - payload->icmpchksum += NyLPC_HTONS(ICMP_ECHO << 8) + 1; - } else { - payload->icmpchksum += NyLPC_HTONS(ICMP_ECHO << 8); - } - //IPヘッダの編集 - tx->destipaddr=tx->srcipaddr; - tx->srcipaddr=*my_ip; -/* - - //チェックサムの再計算 - i_ipp->payload.icmp->type = ICMP_ECHO_REPLY; - if (i_ipp->payload.icmp->icmpchksum >= NyLPC_HTONS(0xffff - (ICMP_ECHO << 8))) { - i_ipp->payload.icmp->icmpchksum += NyLPC_HTONS(ICMP_ECHO << 8) + 1; - } else { - i_ipp->payload.icmp->icmpchksum += NyLPC_HTONS(ICMP_ECHO << 8); - } - //OUT/INアドレスの反転 - i_ipp->header->destipaddr=i_ipp->header->srcipaddr; - i_ipp->header->srcipaddr=*my_ip; -*/ - return tx; - -}
--- a/core/uip/NyLPC_cIPv4IComp.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - * - * Parts of this file were leveraged from uIP: - * - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef NYLPC_CIPV4ICOMP_H_ -#define NYLPC_CIPV4ICOMP_H_ -#include "NyLPC_cIPv4Config.h" -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -typedef struct NyLPC_TcIPv4IComp NyLPC_TcIPv4IComp_t; -struct NyLPC_TcIPv4IComp -{ - const NyLPC_TcIPv4Config_t* _ref_config; -}; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* NYLPC_CIPV4ICOMP_H_ */ \ No newline at end of file
--- a/core/uip/NyLPC_cIPv4IComp_protected.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - * - * Parts of this file were leveraged from uIP: - * - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef NYLPC_NyLPC_cIPv4IComp_protected_H_ -#define NYLPC_NyLPC_cIPv4IComp_protected_H_ - -#include "NyLPC_uip.h" -#include "NyLPC_cIPv4Payload_protected.h" -#include "NyLPC_cIPv4IComp.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -NyLPC_TBool NyLPC_cIPv4IComp_initialize( - NyLPC_TcIPv4IComp_t* i_inst, - const NyLPC_TcIPv4Config_t* i_ref_config); - -void NyLPC_cIPv4IComp_finalize( - NyLPC_TcIPv4IComp_t* i_inst); - -/** - * この関数は、ICOMP IPv4パケットを処理します。 - * @return - * イーサネットパケットを格納したメモリを返します。 - * このメモリはNyLPC_cUipService_allocTxBufで取得されたメモリです。 - */ -void* NyLPC_cIPv4IComp_rx( - const NyLPC_TcIPv4IComp_t* i_inst, - const NyLPC_TcIPv4Payload_t* i_ipp); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif
--- a/core/uip/NyLPC_cIPv4Payload.c Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,144 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - * - * Parts of this file were leveraged from uIP: - * - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "NyLPC_uip.h" -#include "NyLPC_cIPv4Payload_protected.h" - - - - - -/********************************************************************************* - * public 関数 - *********************************************************************************/ - - - - -void NyLPC_cIPv4Payload_initialize(NyLPC_TcIPv4Payload_t* i_inst) -{ - return; -} - -/** - * IPパケットを格納したバッファをセットして、ペイロードのポインタを返します。 - * 失敗時はFALSE - */ -NyLPC_TBool NyLPC_cIPv4Payload_attachRxBuf(NyLPC_TcIPv4Payload_t* i_inst,const void* i_buf,NyLPC_TUInt16 i_flagment_size) -{ - i_inst->header=(const struct NyLPC_TIPv4Header*)i_buf; - i_inst->payload.rawbuf=(const NyLPC_TUInt8*)i_buf+(i_inst->header->vhl & 0x0f)*4; - //IPパケットのバージョンチェック - if((i_inst->header->vhl & 0xf0)!=0x40){ - NyLPC_OnErrorGoto(Error); - } - //IPフレームサイズの調整 - if(NyLPC_ntohs(i_inst->header->len16)>i_flagment_size){ - NyLPC_OnErrorGoto(Error); - } - //フラグメントは許可しない。 - if ((NyLPC_ntohs(i_inst->header->ipoffset) & 0x3fff) != 0){ - NyLPC_OnErrorGoto(Error); - } - //IPv4ヘッダのチェックサムを確認 - if(!NyLPC_TIPv4Header_isCorrectIpCheckSum(i_inst->header)) - { - NyLPC_OnErrorGoto(Error); - } - return NyLPC_TBool_TRUE; -Error: - return NyLPC_TBool_FALSE; -} - -/* - * TcpIpのRxバッファをセットします。 - * @todo いらない? - */ -/* -void* NyLPC_cIPv4Payload_setTcpRxBuf(NyLPC_TcIPv4Payload_t* i_inst,void* i_buf,NyLPC_TUInt16 i_flagment_size) -{ - if(!NyLPC_cIPv4Payload_setRxBuf(i_inst,i_buf,i_flagment_size)){ - return NULL; - } - i_inst->header=(struct NyLPC_TIPv4Header*)i_buf; - return i_inst->payload.rawbuf+(i_inst->payload.tcp->tcpoffset>>4)*4; -} -*/ - - -const void* NyLPC_cIPv4Payload_detachBuf(NyLPC_TcIPv4Payload_t* i_inst) -{ - const void* r=i_inst->header; - NyLPC_ArgAssert(r!=NULL); - i_inst->header=NULL; - return r; -} -/* なんだっけっこれ? -//1の補数v1にv2を加算する。 -static NyLPC_TUInt16 add16c(NyLPC_TUInt16 i_v1,NyLPC_TUInt16 i_v2) -{ - NyLPC_TUInt16 t; - t=i_v1+i_v2; - return (t>i_v1)?t:t+1; -} -//1の補数v1から、v2を減算する。 -static NyLPC_TUInt16 sub16c(NyLPC_TUInt16 i_v1,NyLPC_TUInt16 i_v2) -{ - NyLPC_TUInt16 t; - t=i_v1-i_v2; - return (t<i_v1)?t:t-1; -} -*/ - -
--- a/core/uip/NyLPC_cIPv4Payload.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - * - * Parts of this file were leveraged from uIP: - * - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef NyLPC_cIPv4Payload_h -#define NyLPC_cIPv4Payload_h -typedef struct NyLPC_TcIPv4Payload NyLPC_TcIPv4Payload_t; - -#include "NyLPC_uip.h" - - -/********************************************************************** - * - * NyLPC_TcIPv4Payload - * - **********************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -struct NyLPC_TcIPv4Payload -{ - //IPヘッダへのポインタです。バッファの先頭アドレスと同一です。 - const struct NyLPC_TIPv4Header* header; - union{ - //IPヘッダ終了位置のポインタです。 - const NyLPC_TUInt8* rawbuf; - const struct NyLPC_TIcmpHeader* icmp; - const struct NyLPC_TTcpHeader* tcp; - const struct NyLPC_TUdpHeader* udp; - }payload; -// NyLPC_TUInt16 buf_len; -}; - - - - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif
--- a/core/uip/NyLPC_cIPv4Payload_protected.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,123 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - * - * Parts of this file were leveraged from uIP: - * - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef NYLPC_CIPV4PAYLOAD_PROTECTED_H_ -#define NYLPC_CIPV4PAYLOAD_PROTECTED_H_ - -#include "NyLPC_cIPv4Payload.h" -#include "NyLPC_cIPv4.h" -#include "NyLPC_cTcpSocket.h" -#include "NyLPC_cUdpSocket.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#define TCP_FIN 0x01 -#define TCP_SYN 0x02 -#define TCP_RST 0x04 -#define TCP_PSH 0x08 -#define TCP_ACK 0x10 -#define TCP_URG 0x20 -#define TCP_CTL 0x3f -#define UIP_TCPH_LEN 20 /* Size of TCP header */ -#define UIP_IPH_LEN 20 /* Size of IP header */ - - - -void NyLPC_cIPv4Payload_initialize(NyLPC_TcIPv4Payload_t* i_inst); -#define NyLPC_cIPv4Payload_finalize(i) - -/** - * アタッチされているバッファを返します。 - */ -#define NyLPC_cIPv4Payload_getBuf(i) ((i)->header) - - - -void NyLPC_cIPv4Payload_attachTxBuf(NyLPC_TcIPv4Payload_t* i_inst,void* i_buf); -const void* NyLPC_cIPv4Payload_detachBuf(NyLPC_TcIPv4Payload_t* i_inst); - -NyLPC_TBool NyLPC_cIPv4Payload_attachRxBuf(NyLPC_TcIPv4Payload_t* i_inst,const void* i_buf,NyLPC_TUInt16 i_flagment_size); -void NyLPC_cIPv4Payload_setTcpReverseRstAck( - NyLPC_TcIPv4Payload_t* i_inst); -void NyLPC_cIPv4Payload_setTcpReverseRstAck2( - NyLPC_TcIPv4Payload_t* i_inst, - const NyLPC_TcIPv4Payload_t* i_src); - - - - -/** - * UDPの送信バッファを初期化します。 - */ -void* NyLPC_cIPv4Payload_initUdpTx(NyLPC_TcIPv4Payload_t* i_inst,NyLPC_TUInt8 i_iph_word,NyLPC_TUInt16 i_tcp_payload_size); -/** - * UDPの送信情報を設定します。 - */ -void NyLPC_cIPv4Payload_setUdpTxHeaderByConnection(NyLPC_TcIPv4Payload_t* i_inst,const struct uip_udp_conn* i_conn,const struct NyLPC_TIPv4Addr* i_dest_ip,NyLPC_TUInt16 i_dest_port); - -void NyLPC_cIPv4Payload_closeUdpTxPacket( - NyLPC_TcIPv4Payload_t* i_inst); - - -void NyLPC_TcIPv4TxPacket_initialize_icomp(NyLPC_TcIPv4Payload_t* i_inst,void* i_buf,NyLPC_TUInt8 i_iph_word,NyLPC_TUInt16 i_tcp_payload_size); - - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* NYLPC_CIPV4PAYLOAD_PROTECTED_H_ */
--- a/core/uip/NyLPC_cIPv4_typedef.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,17 +0,0 @@ -#ifndef NYLPC_CIPV4_TYPEDEF_H_ -#define NYLPC_CIPV4_TYPEDEF_H_ - -/** - * クラス型を定義します。 - * NyLPC_cIPv4クラスは、NyLPC_cUipServiceクラスの一部として働きます。 - * 通常ユーザが操作することはありません。 - * IPv4における、ソケットクラス(NyLPC_cTcpSocketとNyLPC_cTcpListener)の管理を担当します。 - * クラスのインスタンスは、NyLPC_cUipServiceのインスタンスにより生成されます。 - * インスタンスは2つのポインタリストをもち、ここにこれらのインスタンスを登録します。 - * インスタンスは、NyLPC_cUipServiceから送られてきた受信パケットを、登録されているソケットクラスに - * ディスパッチする機能を持ちます。 - */ -typedef struct NyLPC_TcIPv4 NyLPC_TcIPv4_t; - -#endif /* NYLPC_CIPV4_PUBLIC_H_ */ -
--- a/core/uip/NyLPC_cTcpListener.c Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,213 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - *********************************************************************************/ -#include "NyLPC_cTcpListener_protected.h" -#include "NyLPC_cTcpSocket_protected.h" -#include "NyLPC_cUipService_protected.h" -#include "NyLPC_cIPv4.h" -#include "NyLPC_stdlib.h" -#include <stdio.h> -/** - * NyLPC_TTcpListenerListenQ - */ - -void NyLPC_TTcpListenerListenQ_init(struct NyLPC_TTcpListenerListenQ* i_struct) -{ - i_struct->wp=0; - int i; - for(i=NyLPC_TcTcpListener_NUMBER_OF_Q-1;i>=0;i--){ - i_struct->item[i].rport=0; - } -} - -/** - * ListenQへSYNパケットの情報を追加する。 - */ -void NyLPC_TTcpListenerListenQ_add(struct NyLPC_TTcpListenerListenQ* i_struct,const NyLPC_TcIPv4Payload_t* i_payload) -{ - struct NyLPC_TTcpSocketSynParam* item=&i_struct->item[i_struct->wp]; - //未処理のものがあれば登録しない。 - if(item->rport!=0){ - return; - } - - //SYNリングバッファにセット - item->rport = i_payload->payload.tcp->srcport; - item->srcaddr=i_payload->header->srcipaddr; - item->rcv_nxt32=NyLPC_ntohl(i_payload->payload.tcp->seqno32)+1; - //MSSの設定 - if(!NyLPC_TTcpHeader_getTcpMmsOpt(i_payload->payload.tcp,&item->mss)){ - item->mss=0; - } - //書込み位置の進行 - i_struct->wp=(i_struct->wp+1)%NyLPC_TcTcpListener_NUMBER_OF_Q; -} - -/** - * 最も古いSYNパケット情報のインデクスをキューから返す。 - * @return - * 見つからない場合-1である。 - */ -int NyLPC_TTcpListenerListenQ_getLastIndex(struct NyLPC_TTcpListenerListenQ* i_struct) -{ - int i,t; - //古いものから順に返す - for(i=1;i<=NyLPC_TcTcpListener_NUMBER_OF_Q;i++){ - t=(i_struct->wp+i)%NyLPC_TcTcpListener_NUMBER_OF_Q; - //有効なデータ? - if(i_struct->item[t].rport!=0){ - return t; - } - } - return -1; -} - -/** - * ListenQのN番目を削除する。 - */ -void NyLPC_TTcpListenerListenQ_remove(struct NyLPC_TTcpListenerListenQ* i_struct,int i_idx) -{ - i_struct->item[i_idx].rport=0; - return; -} - - - - - - -//#define lockResource(i_inst) NyLPC_cMutex_lock(((i_inst)->_mutex)) -//#define unlockResource(i_inst) NyLPC_cMutex_unlock(((i_inst)->_mutex)) -#define lockResource(i_inst) NyLPC_cMutex_lock(NyLPC_cIPv4_getListenerMutex(((i_inst)->_super._parent_ipv4))) -#define unlockResource(i_inst) NyLPC_cMutex_unlock(NyLPC_cIPv4_getListenerMutex(((i_inst)->_super._parent_ipv4))) - - -/** - * uipサービスが稼働中にのみ機能します。 - */ -NyLPC_TBool NyLPC_cTcpListener_initialize(NyLPC_TcTcpListener_t* i_inst,NyLPC_TUInt16 i_port) -{ - NyLPC_TcUipService_t* srv=_NyLPC_TcUipService_inst; - NyLPC_cBaseSocket_initialize(&(i_inst->_super),NyLPC_TcBaseSocket_TYPEID_TCP_LISTENER); - NyLPC_TTcpListenerListenQ_init(&i_inst->_listen_q); - //uipサービスは初期化済であること。 - NyLPC_Assert(NyLPC_TcUipService_isInitService()); - //初期化 -// // NyLPC_cMutex_initialize(&(i_inst->_mutex)); -// i_inst->_mutex=NyLPC_cIPv4_getListenerMutex(&srv->_tcpv4);// NyLPC_cMutex_initialize(&(i_inst->_mutex)); - i_inst->_port=NyLPC_htons(i_port); - //管理リストへ登録。 - return NyLPC_cIPv4_addSocket(&(srv->_tcpv4),&(i_inst->_super)); -} - -void NyLPC_cTcpListener_finaize(NyLPC_TcTcpListener_t* i_inst) -{ - NyLPC_TcUipService_t* srv=_NyLPC_TcUipService_inst; - NyLPC_Assert(NyLPC_TcUipService_isInitService()); - //uipサービスは初期化済であること。 - if(!NyLPC_cIPv4_removeSocket(&(srv->_tcpv4),&(i_inst->_super))){ - //削除失敗、それは死を意味する。 - NyLPC_Abort(); - } - NyLPC_cBaseSocket_finalize(&(i_inst->_super)); - return; -} - - - - -NyLPC_TBool NyLPC_cTcpListener_listen(NyLPC_TcTcpListener_t* i_inst,NyLPC_TcTcpSocket_t* i_sock,NyLPC_TUInt32 i_wait_msec) -{ - int qi; - NyLPC_TcStopwatch_t sw; - NyLPC_TBool ret=NyLPC_TBool_FALSE; - //サービスは稼働中であること。 - NyLPC_Assert(NyLPC_cUipService_isRun()); - - //入力ソケットはCLOSEDであること。 - if(i_sock->tcpstateflags!=UIP_CLOSED){ - return NyLPC_TBool_FALSE; - } - - //ストップウォッチを起動 - NyLPC_cStopwatch_initialize(&sw); - NyLPC_cStopwatch_setNow(&sw); - - - //Listenerのリソースロック - lockResource(i_inst); - - while(NyLPC_cStopwatch_elapseInMsec(&sw)<i_wait_msec){ - qi=NyLPC_TTcpListenerListenQ_getLastIndex(&i_inst->_listen_q); - if(qi>=0){ - //SYN処理要求がある - if(!NyLPC_cTcpSocket_listenSyn(i_sock,&i_inst->_listen_q.item[qi],i_inst->_port)){ - ret=NyLPC_TBool_FALSE; - }else{ - //成功 - ret=NyLPC_TBool_TRUE; - } - //処理したSYNの削除 - NyLPC_TTcpListenerListenQ_remove(&i_inst->_listen_q,qi); - break; - }else{ - //SYN処理要求は無い(しばらくまつ) - unlockResource(i_inst); - NyLPC_cThread_yield(); - lockResource(i_inst); - } - } - //タイムアウト - unlockResource(i_inst); - NyLPC_cStopwatch_finalize(&sw); - return ret; -} - -/** - * この関数は、Uip受信タスクから実行します。 - */ -NyLPC_TBool NyLPC_cTcpListener_synPacket(NyLPC_TcTcpListener_t* i_inst,const NyLPC_TcIPv4Payload_t* i_payload) -{ - //パケットチェック。SYN設定されてる? - if(!(i_payload->payload.tcp->flags & TCP_SYN)){ - //SYNない - return NyLPC_TBool_FALSE; - } - //peer port==0は受け取らない。 - if(i_payload->payload.tcp->srcport==0){ - return NyLPC_TBool_FALSE; - } - //Listenerのリソースロック - lockResource(i_inst); - //ListenQへ追加 - NyLPC_TTcpListenerListenQ_add(&(i_inst->_listen_q),i_payload); - //Listenerのリソースアンロック - unlockResource(i_inst); - return NyLPC_TBool_TRUE; -} - - - -
--- a/core/uip/NyLPC_cTcpListener.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - *********************************************************************************/ -#ifndef NYLPC_CTCPLISTENER_H_ -#define NYLPC_CTCPLISTENER_H_ - - -#include "NyLPC_stdlib.h" -#include "NyLPC_os.h" -#include "NyLPC_cBaseSocket.h" -#include "NyLPC_cTcpSocket.h" -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -typedef struct NyLPC_TcTcpListener NyLPC_TcTcpListener_t; - -/********************************************************************** - * - * NyLPC_TTcpListenerListenQ struct - * - **********************************************************************/ - -#define NyLPC_TcTcpListener_NUMBER_OF_Q 10 - -struct NyLPC_TTcpListenerListenQ -{ - struct NyLPC_TTcpSocketSynParam item[NyLPC_TcTcpListener_NUMBER_OF_Q]; - NyLPC_TUInt16 wp; -}; - - -/********************************************************************** - * - * NyLPC_TcTcpListener class - * - **********************************************************************/ - -/** - * TCP listenerクラス型です。 - */ -struct NyLPC_TcTcpListener -{ - NyLPC_TcBaseSocket_t _super; - NyLPC_TUInt16 _port; /**<ネットワークオーダーのポート番号*/ -// /** -// * タスク間の調停用Mutex -// * Listener用の共通Mutexポインタ -// */ -// NyLPC_TcMutex_t* _mutex; - /** - * SYNパケットのキュー - */ - struct NyLPC_TTcpListenerListenQ _listen_q; -}; -/** - * この関数は、TCPのリスナーを初期化します。 - * 初期化したリスナーをサービスに登録することにより、listen関数を使用できるようになります。 - * サービスへの登録は、NyLPC_cUipService_addListenerを使います。 - * @param i_port - * ポート番号。host orderです。 - */ -NyLPC_TBool NyLPC_cTcpListener_initialize(NyLPC_TcTcpListener_t* i_inst,NyLPC_TUInt16 i_port); - -/** - * この関数は、一定時間i_sockに接続を受け付けます。 - */ -NyLPC_TBool NyLPC_cTcpListener_listen(NyLPC_TcTcpListener_t* i_inst,NyLPC_TcTcpSocket_t* i_sock,NyLPC_TUInt32 i_wait_msec); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* NYLPC_CTCPLISTENER_H_ */
--- a/core/uip/NyLPC_cTcpListener_protected.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - *********************************************************************************/ -#ifndef NYLPC_CTCPLISTENER_PROTECTED_H_ -#define NYLPC_CTCPLISTENER_PROTECTED_H_ -#include "NyLPC_cTcpListener.h" -#include "NyLPC_cUipService_protected.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - - -/** - * ListenerへSYNパケットを通知します。 - * @return - * 常にTRUE - */ -NyLPC_TBool NyLPC_cTcpListener_synPacket(NyLPC_TcTcpListener_t* i_inst,const NyLPC_TcIPv4Payload_t* i_payload); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* NYLPC_CTCPLISTENER_PROTECTED_H_ */
--- a/core/uip/NyLPC_cTcpSocket.c Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1492 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - *********************************************************************************/ -#include "NyLPC_cTcpSocket_protected.h" -#include "NyLPC_stdlib.h" -#include "NyLPC_cUipService_protected.h" - - -static NyLPC_TUInt32 iss32=3939; -#define SIZE_OF_IPv4_TCPIP_HEADER 40 - -/** - * TCPのRTOの最大値。 - * ms単位である。 - * defaultは64SEC - */ -#define UIP_IP_RTO_MAX_RTO 64000 -/** - * TCPのRTOの初期値。 - * ms単位である。 - * 伝送路の特性に合わせて調整すること。 - */ -#define UIP_TCP_RTO_INITIAL 3000 - -/** - * CONNECTION時のRTO - */ -#define UIP_TCP_RTO_CONNECTION_INITIAL 200 - -/** - * 下限値 - */ -#define UIP_TCP_RTO_MINIMUM 100 - - -/** - * for Debug - * RTOの情報をログ領域に取る。 - */ -#ifdef RTO_LOG - NyLPC_TUInt32 rto_log[256]; - int rto_log_st=0; - #define DEBUG_RTO_LOG(i_inst) if(rto_log_st<256){rto_log[rto_log_st++]=i_inst->uip_connr.current_rto32;}; -#else - #define DEBUG_RTO_LOG(i_inst) -#endif - -//#define lockResource(i_inst) NyLPC_cMutex_lock(&((i_inst)->_smutex)) -//#define unlockResource(i_inst) NyLPC_cMutex_unlock(&((i_inst)->_smutex)) -#define lockResource(i_inst) NyLPC_cMutex_lock(NyLPC_cIPv4_getSockMutex(((i_inst)->_super._parent_ipv4))) -#define unlockResource(i_inst) NyLPC_cMutex_unlock(NyLPC_cIPv4_getSockMutex(((i_inst)->_super._parent_ipv4))) - -static void sendRst(NyLPC_TcTcpSocket_t* i_inst); - - - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Packet writer -// -//////////////////////////////////////////////////////////////////////////////////////////////////// - - -/** - * TCPヘッダに値をセットする。checksum,wndは0初期化する。 - */ -static void setTcpTxHeader(struct NyLPC_TTcpHeader* i_struct,NyLPC_TUInt8 i_flag,const struct uip_conn* i_conn) -{ - i_struct->flags = i_flag; - //sorce & destination port - i_struct->srcport = i_conn->lport; - i_struct->destport = i_conn->rport; - //ACK number - i_struct->ackno32 = NyLPC_htonl(i_conn->rcv_nxt32); - //Seq Number - i_struct->seqno32 = NyLPC_htonl(i_conn->snd_nxt32); - //uip_func_tcp_send_noconn(BUF); - i_struct->urgp[0] = i_struct->urgp[1] = 0; - i_struct->tcpchksum= 0; -} - -static void setTxPacket(const NyLPC_TcTcpSocket_t* i_inst,void* i_tx_buf,NyLPC_TUInt8 i_tcpf,const void* i_buf,NyLPC_TUInt16 i_len) -{ - struct NyLPC_TIPv4Header* iph; - struct NyLPC_TTcpHeader* tcph; - NyLPC_TUInt8 iph_word=0x05; - NyLPC_TUInt8 tcph_word=(UIP_TCPH_LEN) / 4; - //IPヘッダの更新 - iph=(struct NyLPC_TIPv4Header*)i_tx_buf; - iph->vhl=0x40|(0x0f&iph_word); - iph->destipaddr=i_inst->uip_connr.ripaddr; - iph->srcipaddr =*(i_inst->uip_connr.lipaddr); - NyLPC_TIPv4Header_writeTxIpHeader(iph,UIP_PROTO_TCP); - //TCPヘッダの更新 - tcph=(struct NyLPC_TTcpHeader*)(((NyLPC_TUInt8*)i_tx_buf)+NyLPC_TIPv4Header_getHeaderLength(iph)); - - - //SYNが有るならMSSの書き込み - if((TCP_SYN & i_tcpf)){ - tcph_word+=((TCP_OPT_MSS_LEN) / 4); - NyLPC_TTcpHeader_setMmsOpt(((NyLPC_TUInt8*)(tcph+1)),i_inst->uip_connr.default_mss); - } - tcph->tcpoffset=(tcph_word<<4); - setTcpTxHeader(tcph,i_tcpf,&(i_inst->uip_connr)); - - //最終的なパケットサイズと必要ならペイロードを書き込み - if(i_buf!=NULL){ - iph->len16=NyLPC_htons(i_len+(iph_word+tcph_word)*4); - memcpy(((NyLPC_TUInt8*)i_tx_buf)+((iph_word+tcph_word)*4),i_buf,i_len); - }else{ - iph->len16=NyLPC_htons((iph_word+tcph_word)*4); - } - //WND設定 - tcph->wnd16=NyLPC_htons(NyLPC_cFifoBuffer_getSpace(&(i_inst->rxbuf))); - //Checksumの生成 - tcph->tcpchksum=~(NyLPC_TIPv4Header_makeTcpChecksum(iph)); - iph->ipchksum = ~(NyLPC_TIPv4Header_makeIpChecksum(iph)); - return; -} - -/** - * IP/TCPヘッダが40バイト固定として、i_tx_buf+40の位置にあるペイロードに対するIP/TCPヘッダを書き込みます。 - */ -static void setTxPacketHeader(const NyLPC_TcTcpSocket_t* i_inst,void* i_tx_buf,NyLPC_TUInt8 i_tcpf,NyLPC_TUInt16 i_len) -{ - struct NyLPC_TIPv4Header* iph; - struct NyLPC_TTcpHeader* tcph; - NyLPC_TUInt8 iph_word=0x05; - NyLPC_TUInt8 tcph_word=(UIP_TCPH_LEN) / 4; - //IPヘッダの更新 - iph=(struct NyLPC_TIPv4Header*)i_tx_buf; - iph->vhl=0x40|(0x0f&iph_word); - iph->destipaddr=i_inst->uip_connr.ripaddr; - iph->srcipaddr =*(i_inst->uip_connr.lipaddr); - NyLPC_TIPv4Header_writeTxIpHeader(iph,UIP_PROTO_TCP); - - //TCPヘッダの更新 - tcph=(struct NyLPC_TTcpHeader*)(((NyLPC_TUInt8*)i_tx_buf)+NyLPC_TIPv4Header_getHeaderLength(iph)); - tcph->tcpoffset=(tcph_word<<4); - setTcpTxHeader(tcph,i_tcpf,&(i_inst->uip_connr)); - - //最終的なパケットサイズと必要ならペイロードを書き込み - iph->len16=NyLPC_htons(i_len+(iph_word+tcph_word)*4); - //WND設定 - tcph->wnd16=NyLPC_htons(NyLPC_cFifoBuffer_getSpace(&(i_inst->rxbuf))); - //Checksumの生成 - tcph->tcpchksum=~(NyLPC_TIPv4Header_makeTcpChecksum(iph)); - iph->ipchksum = ~(NyLPC_TIPv4Header_makeIpChecksum(iph)); - return; -} - - - - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Mainclass::private -// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/** - * ACK番号を更新する。 - * @param i_ackno - * ネットワークオーダーのACK番号 - */ -static void updateAckNo(void* i_tx_buf,NyLPC_TUInt32 i_ackno) -{ - struct NyLPC_TIPv4Header* iph=(struct NyLPC_TIPv4Header*)i_tx_buf; - struct NyLPC_TTcpHeader* tcph=(struct NyLPC_TTcpHeader*)(((NyLPC_TUInt8*)i_tx_buf)+NyLPC_TIPv4Header_getHeaderLength(iph)); - -/* union{ - NyLPC_TUInt32 l; - NyLPC_TUInt8 b[4]; - }old_ack,new_ack; - NyLPC_TUInt16 v1; - //checksumの計算 - old_ack.l=i_inst->payload.tcp->ackno32;//古いACK番号 - new_ack.l=i_ackno;//新しいACK番号 - v1=NyLPC_ntohs(~(i_inst->payload.tcp->tcpchksum));//1の補数を取って、ホストオーダーに戻す。 - //減算 - v1=sub16c(v1,(old_ack.b[0]<<8)+old_ack.b[1]); - v1=sub16c(v1,(old_ack.b[2]<<8)+old_ack.b[3]); - //加算 - v1=add16c(v1,(new_ack.b[0]<<8)+new_ack.b[1]); - v1=add16c(v1,(new_ack.b[2]<<8)+new_ack.b[3]); - v1=~NyLPC_htons(v1);*/ -NyLPC_Trace(); - tcph->ackno32=i_ackno; -NyLPC_Trace(); - tcph->tcpchksum = 0; -NyLPC_Trace(); - tcph->tcpchksum = ~(NyLPC_TIPv4Header_makeTcpChecksum(iph)); -NyLPC_Trace(); - -/* - if((i_inst->payload.tcp->tcpchksum!=v1)){ - NyLPC_Warning(); - }*/ -} - - - -/** - * 指定した送信パケットがACK済であるか調べる。 - */ -static NyLPC_TBool isPacketAcked(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_sq) -{ - int rp; - struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; - rp=i_inst->txbuf.rp; - while(rp!=i_inst->txbuf.wp){ - if(q[rp].ackno==i_sq){ - return NyLPC_TBool_FALSE; - } - rp=(rp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; - } - return NyLPC_TBool_TRUE; -} -/** - * 送信キューからi_sq以前に送信したパケットを除外して、残り個数を返却する。 - */ -static int getNumOfSending(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_sq) -{ - int rp,n; - struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; - rp=i_inst->txbuf.rp; - n=0; - while(rp!=i_inst->txbuf.wp){ - if(q[rp].ackno==i_sq){ - return n; - } - n++; - rp=(rp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; - } - return n; -} -/** - * この関数は、コネクションをリセットします。 - * ロック状態でコールしてください。 - * 関数は、現在バッファにある再送信待ちデータを開放します。 - */ -static void resetTxQWithUnlock(NyLPC_TcTcpSocket_t* i_inst) -{ - int i,l; - struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; - void* dlist[NyLPC_TcTcpSocket_NUMBER_OF_TXQ]; - - l=0; - while(i_inst->txbuf.rp!=i_inst->txbuf.wp){ - dlist[l]=q[i_inst->txbuf.rp].packet; - l++; - i_inst->txbuf.rp=(i_inst->txbuf.rp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; - } - i_inst->txbuf.rp=i_inst->txbuf.wp=0; - //ロック解除 - unlockResource(i_inst); - //セーブしたバッファを開放 - for(i=0;i<l;i++){ - NyLPC_cUipService_releaseTxBuf(dlist[i]); - } - return; -} -/** - * TXバッファの再送パケットのACK番号を更新します。 - * ロックして実行してください。 - * @param i_ackno - * ネットワークオーダーのACK番号 - */ -static void updateTxAck(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_ackno) -{ - NyLPC_TUInt8 rp; - struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; - NyLPC_ArgAssert(i_inst!=NULL); - rp=i_inst->txbuf.rp; - while(rp!=i_inst->txbuf.wp){ - updateAckNo(q[rp].packet,i_ackno); - rp=(rp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; - } -} - -/** - * RTOの予測関数 - */ -static void estimateRTO(NyLPC_TcTcpSocket_t* i_inst,int s,int n) -{ - NyLPC_TcStopwatch_t sw; - NyLPC_TUInt32 cr_rtt_min,cr_rtt_max,sk_rto,new_rto,w; - int i; - struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; - NyLPC_cStopwatch_initialize(&sw); - - sk_rto=i_inst->uip_connr.current_rto32; - //ACKされたパケットの個数は? - switch(n){ - case 1: - NyLPC_cStopwatch_set(&sw,q[s].tick_of_sent); - cr_rtt_min=NyLPC_cStopwatch_elapseInMsec(&sw); - if(sk_rto<cr_rtt_min){ - //現在のRTOよりも大きい→再送があった。(再送の理由が回線遅延によるものかわからないので、基本RTOを25%増やす。) - new_rto=sk_rto*10/8; - }else if(sk_rto/4<cr_rtt_min){ - //現在のRTOの1/4< n < 現在のRTO 想定内の変動。1/8 - new_rto=(sk_rto+(cr_rtt_min*3*7))/8; - }else{ - //現在の1/4以下。RTOを再計算。 RTOが大きすぎるので再計算。(計測値を優先した現在値との平均値) - new_rto=(sk_rto+(cr_rtt_min*3*3))/4; - } - break; - default: - //複数のパケットなら、最大と最小の時刻を得る。 - NyLPC_cStopwatch_set(&sw,q[s].tick_of_sent); - cr_rtt_min=cr_rtt_max=NyLPC_cStopwatch_elapseInMsec(&sw); - for(i=1;i<n;i++){ - NyLPC_cStopwatch_set(&sw,q[(s+i)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ].tick_of_sent); - w=NyLPC_cStopwatch_elapseInMsec(&sw); - if(cr_rtt_min>w){ - cr_rtt_min=w; - } - if(cr_rtt_max<w){ - cr_rtt_max=w; - } - } - if(sk_rto<cr_rtt_min && sk_rto<cr_rtt_max){ - //最大値,最小値とも現在のRTTより大きい→低速な回線を検出。 - new_rto=cr_rtt_max*10/8;//最大経過時間の25%増しの時間を設定。 - }else if(sk_rto/4<cr_rtt_min){ - //現在のRTOの1/4< n < 現在のRTO 想定範囲内。1/8の加重平均で速度計算。 - new_rto=(sk_rto+(cr_rtt_min*3*7))/8; - }else{ - //現在の1/4以下。RTOが大きすぎるので再計算。(計測値を優先した加重平均) - new_rto=(sk_rto+(cr_rtt_min*3*3))/4; - } - break; - } - NyLPC_cStopwatch_finalize(&sw); - if(new_rto<UIP_TCP_RTO_MINIMUM){ - new_rto=UIP_TCP_RTO_MINIMUM; - } - i_inst->uip_connr.current_rto32=new_rto; -} - -/** - * TXキューから、入力されたシーケンス番号より前のパケットを除外します。 - * リングバッファのrp->wp-1までをチェックして、sqに等しいi_sq以前のパケットバッファをo_dlistへ返します。 - * - */ -static int updateTxQByIndex(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_sq,void* o_dlist[]) -{ - int rp,n; - struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; - //ロック状態なう - rp=i_inst->txbuf.rp; - n=0; - //This is debug - DEBUG_RTO_LOG(i_inst); - - while(rp!=i_inst->txbuf.wp){ - o_dlist[n]=q[rp].packet; - if(q[rp].ackno==i_sq){ - //i_inst->txbuf.rp->rpのパケットのRTOからbaseRTOの値を再計算。 - estimateRTO(i_inst,i_inst->txbuf.rp,n+1); - i_inst->txbuf.rp=(rp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; - return n+1; - } - n++; - rp=(rp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; - } - return 0; -} - - - -/** - * 空きキューを1個返します。 - * 空きキューの - */ -static struct NyLPC_TcTcpSocket_TxQItem* getTxQ(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TcStopwatch_t* i_timer) -{ - int i; - struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; - do{ - //クローズドに遷移してしまったら、エラーである。 - if(i_inst->tcpstateflags==UIP_CLOSED){ - return NULL; - } - //キューの空きをチェック。wp+1==rpなら、キューがいっぱい。rp==wpなら、キューが空。 - if(((i_inst->txbuf.wp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ)==i_inst->txbuf.rp){ - //一時的なアンロック - unlockResource(i_inst); - //タスクスイッチ - NyLPC_cThread_yield(); - //ロック - lockResource(i_inst); - continue; - } - i=i_inst->txbuf.wp; - i_inst->txbuf.wp=(i+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; - return &(q[i]); - }while(!NyLPC_cStopwatch_isExpired(i_timer)); - //失敗。タイムアウト。 - return NULL; -} - - - - - - -/********************************************************************** - * public 関数 - **********************************************************************/ - -NyLPC_TBool NyLPC_cTcpSocket_initialize(NyLPC_TcTcpSocket_t* i_inst,void* i_rbuf,NyLPC_TUInt16 i_rbuf_len) -{ - int i; - NyLPC_TcUipService_t* srv=_NyLPC_TcUipService_inst; - NyLPC_cBaseSocket_initialize(&(i_inst->_super),NyLPC_TcBaseSocket_TYPEID_TCP_SOCK); - //uipサービスは初期化済であること。 - NyLPC_Assert(NyLPC_TcUipService_isInitService()); - - NyLPC_cFifoBuffer_initialize(&(i_inst->rxbuf),i_rbuf,i_rbuf_len); - // NyLPC_AbortIfNot(NyLPC_cMutex_initialize(&(i_inst->_smutex)));//個別Mutex -// i_inst->_smutex=NyLPC_cIPv4_getSockMutex(&(srv->_tcpv4));//共有Mutex - i_inst->tcpstateflags=UIP_CLOSED; - i_inst->txbuf.rp=i_inst->txbuf.wp=0; - for(i=0;i<NyLPC_TcTcpSocket_NUMBER_OF_TXQ;i++){ - i_inst->txbuf.txq[i].packet=NULL; - } - //管理リストへ登録。 - return NyLPC_cIPv4_addSocket(&(srv->_tcpv4),&(i_inst->_super)); -} -void NyLPC_cTcpSocket_finalize(NyLPC_TcTcpSocket_t* i_inst) -{ - int i; - NyLPC_TcUipService_t* srv=_NyLPC_TcUipService_inst; - NyLPC_Assert(NyLPC_TcUipService_isInitService()); - //uipサービスは初期化済であること。 - if(!NyLPC_cIPv4_removeSocket(&(srv->_tcpv4),&(i_inst->_super))){ - //削除失敗、それは死を意味する。 - NyLPC_Abort(); - } - //開放漏れの保険 - if(i_inst->txbuf.rp!=i_inst->txbuf.wp){ - lockResource(i_inst); - resetTxQWithUnlock(i_inst); - } - for(i=0;i<NyLPC_TcTcpSocket_NUMBER_OF_TXQ;i++){ - i_inst->txbuf.txq[i].packet=NULL; - } - NyLPC_cFifoBuffer_finalize(&(i_inst->rxbuf)); -// NyLPC_cMutex_finalize(&(i_inst->_smutex)); - NyLPC_cBaseSocket_finalize(&(i_inst->_super)); - return; -} - - - -NyLPC_TBool NyLPC_cTcpSocket_listenSyn(NyLPC_TcTcpSocket_t* i_inst,const struct NyLPC_TTcpSocketSynParam* i_lq,NyLPC_TUInt16 i_lport) -{ -// NyLPC_Assert(NyLPC_cMutex_isLocked(i_inst->_smutex)); - lockResource(i_inst); - //ソケットが無効であること。 - if(i_inst->tcpstateflags==UIP_CLOSED) - { - //localipとdefault_mmsは別枠で設定 - /* Fill in the necessary fields for the new connection. */ - i_inst->uip_connr.current_rto32 = UIP_TCP_RTO_INITIAL; - i_inst->uip_connr.lport = i_lport; - i_inst->uip_connr.rport = i_lq->rport; - i_inst->uip_connr.ripaddr=i_lq->srcaddr; - i_inst->uip_connr.snd_nxt32=iss32; - /* rcv_nxt should be the seqno from the incoming packet + 1. */ - i_inst->uip_connr.rcv_nxt32= i_lq->rcv_nxt32; - //MSSの設定 - i_inst->uip_connr.peer_mss=(i_lq->mss!=0)?i_lq->mss:i_inst->uip_connr.default_mss; - i_inst->uip_connr.peer_win=0; - NyLPC_cFifoBuffer_clear(&(i_inst->rxbuf)); - //ここでステータスがかわる。 - i_inst->tcpstateflags = UIP_SYN_RCVD; - //前回のデータが残っていた場合の保険 - if(i_inst->txbuf.rp!=i_inst->txbuf.wp){ - resetTxQWithUnlock(i_inst); - }else{ - unlockResource(i_inst); - } - return NyLPC_TBool_TRUE; - } - unlockResource(i_inst); - return NyLPC_TBool_FALSE; -} - - -/** - * sq番のTxがキューから消え去るのを待ちます。 - * この関数は、アンロック状態でコールしてください。 - * <div> - * パケットがキューからなくなる条件は、以下の2つです。 - * <ul> - * <li>ACKを受信してパケットキューが更新された。</li> - * <li>RSTを受信して(CLOSEDに遷移して)、キューがクリアされた。</li> - * <li>送信タイムアウトで関数が(CLOSEDに遷移させて)キューをクリアした。</li> - * </ul> - * </div> - * @param i_wait_msec - * @return - * 1番目の条件でパケットが消失したときのみ、TRUEを返します。 - * 失敗した場合、TCPステータスがCLOSEDでなければ、RSTを送信してステータスをCLOSEDにします。 - */ -static NyLPC_TBool waitForTxRemove(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_sq,NyLPC_TcStopwatch_t* i_timer) -{ - NyLPC_TUInt8 f; - lockResource(i_inst); - do{ - //パケットが送信中か調べる。 - if(!isPacketAcked(i_inst,i_sq)){ - //まだある場合は、タスクスイッチを繰り返して消失を待つ。 - unlockResource(i_inst); - NyLPC_cThread_yield(); - lockResource(i_inst); - continue; - } - //なくなった場合は、原因を調べる。 - f=i_inst->tcpstateflags; - unlockResource(i_inst); - return (f==UIP_CLOSED)?NyLPC_TBool_FALSE:NyLPC_TBool_TRUE; - }while(!NyLPC_cStopwatch_isExpired(i_timer)); - unlockResource(i_inst); - return NyLPC_TBool_FALSE; -} - - -/** - * 再送信処理をセットして、パケットを送信します。 - * この関数は「アンロック状態で」実行してください。 - * @param i_len - * 送信データサイズを指定します。 - * この番号は、シーケンス番号の加算値ではありませんので、注意をしてください。 - * @return - * <ul> - * <li>n=-1:送信キューへの投入に失敗した。</li> - * <li>n>=0:nバイトのデータを送信キューへの投入することに成功した。</li> - * </ul> - * 送信キューに失敗する理由は2つあります。1つは、TXバッファがフルでタイムアウト。もうひとつは、非同期なコネクリョンのリセットです。 - * 失敗した場合、TCPステータスがCLOSEDでなければ、RSTを送信してステータスをCLOSEDにします。 - */ -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) -{ - struct NyLPC_TcTcpSocket_TxQItem* txq; - NyLPC_TUInt16 s; - void* buf; - NyLPC_TUInt32 next_ack; - //送信バッファを取得 - //@bug オブションパケット送信時に4バイト足りないメモリ要求しない?問題になってないけど。 - for(;;){ - buf=NyLPC_cUipService_allocTxBuf(i_len+(SIZE_OF_IPv4_TCPIP_HEADER),&s); - if(buf!=NULL){ - break; - } - //タイムアウト確認 - if(NyLPC_cStopwatch_isExpired(i_timer)){ - return -1; - } - }; - lockResource(i_inst); - //ペイロードがある場合のみ、相手のwindowサイズが0以上になるのを待つ。 - if(i_len>0){ - while(i_inst->uip_connr.peer_win==0){ - unlockResource(i_inst); - //時間切れならエラー。 - if(NyLPC_cStopwatch_isExpired(i_timer)){ - return -1; - } - NyLPC_cThread_yield(); - lockResource(i_inst); - } - } - //送信キューの取得 - txq=getTxQ(i_inst,i_timer); - //送信キューが取れなかった。 - if(txq==NULL){ - //シーケンス番号をロールバックできないので、エラーとする。 - unlockResource(i_inst); - NyLPC_cUipService_releaseTxBuf(buf); - return -1; - } - - //送信バッファを基準とした送信サイズを計算 - s-=SIZE_OF_IPv4_TCPIP_HEADER; - //送信サイズよりMMSが小さければ、送信サイズを修正 - if(i_inst->uip_connr.peer_mss<s){ - s=i_inst->uip_connr.peer_mss; - } - //送信サイズよりpeerのウインドウサイズが小さければ修正 - if(i_inst->uip_connr.peer_win<s){ - s=i_inst->uip_connr.peer_win; - } - //送信サイズより、データサイズが小さければ、送信サイズを修正 - if(i_len<s){ - s=i_len; - } - //ACK番号の計算 - next_ack=i_inst->uip_connr.snd_nxt32+s+(((i_tcpf&(TCP_FIN|TCP_SYN))!=0x00)?1:0); - txq->rto32=i_inst->uip_connr.current_rto32; - txq->tick_of_sent=NyLPC_cStopwatch_now(); - - //パケットの書き込み - setTxPacket(i_inst,buf,i_tcpf,i_buf,s); - txq->packet=buf; - - //シーケンス番号の更新 - i_inst->uip_connr.snd_nxt32=next_ack; - //Peerのウインドウサイズを更新 - i_inst->uip_connr.peer_win-=s; - //ACK番号の返却 - *o_ack=txq->ackno=NyLPC_HTONL(next_ack); - unlockResource(i_inst); - NyLPC_cUipService_sendIPv4Tx(buf); - return s; -} -/** - * RSTを1フレームだけ送信します。 - * この関数は、クローズドステータスのソケットにしてからコールします。 - * この関数は、アンロック状態でコールしてね。 - */ -static void sendRst(NyLPC_TcTcpSocket_t* i_inst) -{ - void* buf; - - NyLPC_Assert(i_inst->tcpstateflags==UIP_CLOSED); - //ペイロードライタの初期化 - - //@bug バッファが取れるまで通信がブロックするの。ここはなんとかしないと。 - buf=NyLPC_cUipService_allocSysTxBuf(); - lockResource(i_inst); - i_inst->uip_connr.snd_nxt32++; - unlockResource(i_inst); - setTxPacket(i_inst,buf,TCP_RST|TCP_ACK,NULL,0); - NyLPC_cUipService_sendIPv4Tx(buf); - NyLPC_cUipService_releaseTxBuf(buf); - NyLPC_cIPv4Payload_finalize(&ipv4); - return; -} - - - -/** - * 受信データをバッファに書き込む。 - * 十分な空き領域がない場合、失敗する。 - * この関数は、ロックして実行してください。 - */ -static NyLPC_TBool addRecvData(NyLPC_TcTcpSocket_t* i_inst,const void* i_data,NyLPC_TUInt16 i_data_size) -{ - //受信データサイズを確認 - if(NyLPC_cFifoBuffer_getSpace(&(i_inst->rxbuf))>=i_data_size){ - //バッファに格納可能なら、格納。 - NyLPC_cFifoBuffer_push(&(i_inst->rxbuf),i_data,i_data_size); - }else{ - //エラー:ドロップする。 - return NyLPC_TBool_FALSE; - } - - return NyLPC_TBool_TRUE; -} - - - - -/** - * Public function - */ - -NyLPC_TBool NyLPC_cTcpSocket_connect(NyLPC_TcTcpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_peer_port,NyLPC_TUInt32 i_wait_in_msec) -{ - volatile NyLPC_TUInt8 f; - NyLPC_TUInt32 sq; - NyLPC_TcStopwatch_t sw; - NyLPC_TUInt16 lport; - lockResource(i_inst); - //ソケットが無効であること。 - if(i_inst->tcpstateflags!=UIP_CLOSED) - { - NyLPC_OnErrorGoto(Error); - } - //ポート番号の取得(lockResourceが他のソケットと共有なので、重複ポートの割当は起こりえない。でもちょっと注意して) - lport=NyLPC_htons(NyLPC_cIPv4_getNewPortNumber(i_inst->_super._parent_ipv4)); - if(lport==0){ - NyLPC_OnErrorGoto(Error); - } - //connectの為の準備 - - //localipとdefault_mmsは別枠で設定 - /* Fill in the necessary fields for the new connection. */ - i_inst->uip_connr.current_rto32 = UIP_TCP_RTO_CONNECTION_INITIAL;//RTOを短くしてARP発行時の再接続短縮を期待する。 - i_inst->uip_connr.lport = lport; - i_inst->uip_connr.rport = NyLPC_htons(i_peer_port); - i_inst->uip_connr.ripaddr=*i_addr; - i_inst->uip_connr.snd_nxt32=iss32;//should be random - /* rcv_nxt should be the seqno from the incoming packet + 1. */ - i_inst->uip_connr.rcv_nxt32=0; - //MSSの設定 - i_inst->uip_connr.peer_mss=i_inst->uip_connr.default_mss; - i_inst->uip_connr.peer_win=1;//periodicの再送信を期待するために相手のWindowサイズは1と仮定する。 - NyLPC_cFifoBuffer_clear(&(i_inst->rxbuf)); - //ここでステータスがかわる。 - i_inst->tcpstateflags = UIP_SYN_SENT; - //前回のデータが残っていた場合の保険 - if(i_inst->txbuf.rp!=i_inst->txbuf.wp){ - resetTxQWithUnlock(i_inst); - }else{ - unlockResource(i_inst); - } - - NyLPC_cStopwatch_initialize(&sw); - - NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec); - if(sendWithRetransmit(i_inst,TCP_SYN,NULL,0,&sw,&sq)==0){ - //ちょっと待つ。 - NyLPC_cThread_yield(); - //キューにあるTXが消えるのを待つ。 - if(waitForTxRemove(i_inst,sq,&sw)){ - //ACK受信に成功して、TXが消失 - NyLPC_cStopwatch_finalize(&sw); - return NyLPC_TBool_TRUE; - } - } - //ロックして、強制的なステータス遷移 - lockResource(i_inst); - f=i_inst->tcpstateflags; - if(f!=UIP_CLOSED){ - //もし、強制CLOSE遷移であれば、RSTも送信。 - i_inst->tcpstateflags=UIP_CLOSED; - unlockResource(i_inst); - sendRst(i_inst); - }else{ - unlockResource(i_inst); - } - return NyLPC_TBool_FALSE; -Error: - unlockResource(i_inst); - return NyLPC_TBool_FALSE; -} - -/** - * この関数は、UIP_SYN_RCVDステータスのソケットを、ESTABLISHEDへ遷移させます。 - * cTcpListener_listen関数を通過したインスタンスに実行してください。 - * この関数は、アプリケーションが呼び出します。 - * @return - * - */ -NyLPC_TBool NyLPC_cTcpSocket_accept(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_wait_in_msec) -{ - volatile NyLPC_TUInt8 f; - NyLPC_TUInt32 sq; - NyLPC_TcStopwatch_t sw; - - NyLPC_cStopwatch_initialize(&sw); - //ステータスチェック - f=i_inst->tcpstateflags; - switch(f) - { - case UIP_ESTABLISHED: - return NyLPC_TBool_TRUE; - case UIP_SYN_RCVD: - //処理対象 - break; - default: - return NyLPC_TBool_FALSE; - } - NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec); - if(sendWithRetransmit(i_inst,TCP_SYN|TCP_ACK,NULL,0,&sw,&sq)==0){ - //ちょっと待つ。 - NyLPC_cThread_yield(); - //キューにあるTXが消えるのを待つ。 - if(waitForTxRemove(i_inst,sq,&sw)){ - //ACK受信に成功して、TXが消失 - NyLPC_cStopwatch_finalize(&sw); - return NyLPC_TBool_TRUE; - } - } - //ロックして、強制的なステータス遷移 - lockResource(i_inst); - f=i_inst->tcpstateflags; - if(f!=UIP_CLOSED){ - //もし、強制CLOSE遷移であれば、RSTも送信。 - i_inst->tcpstateflags=UIP_CLOSED; - unlockResource(i_inst); - sendRst(i_inst); - }else{ - unlockResource(i_inst); - } - return NyLPC_TBool_FALSE; -} - - -/** - * この関数は、ソケットの受信バッファの読み取り位置と、読み出せるデータサイズを返却します。 - * 関数はポインターを返却するだけで、バッファの読み取り位置をシークしません。 - * シークするにはNyLPC_cTcpSocket_pseekを使います。 - */ -NyLPC_TInt32 NyLPC_cTcpSocket_precv(NyLPC_TcTcpSocket_t* i_inst,const void** o_buf_ptr,NyLPC_TUInt32 i_wait_msec) -{ - volatile NyLPC_TUInt8 st; - NyLPC_TUInt16 rlen; - //タイマを生成 - NyLPC_TcStopwatch_t sw; - NyLPC_cStopwatch_initialize(&sw); - - //ESTABLISHED以外の場合は、エラー。 - NyLPC_cStopwatch_setNow(&sw); - do{ - //読み出しバッファ情報のコピー - //MUTEX LOCK - lockResource(i_inst); - st=i_inst->tcpstateflags; - rlen=NyLPC_cFifoBuffer_getLength(&(i_inst->rxbuf)); - *o_buf_ptr=NyLPC_cFifoBuffer_getPtr(&(i_inst->rxbuf)); - //MUTEX UNLOCK - unlockResource(i_inst); - - //バッファが空の場合は、ステータスチェック。ESTABLISHEDでなければ、エラー(PASVCLOSE等の場合) - switch(st){ - case UIP_ESTABLISHED: - if(rlen>0){ - //バッファにパケットがあれば返却 - NyLPC_cStopwatch_finalize(&sw); - return rlen; - } - break; - case UIP_CLOSE_WAIT: - if(rlen>0){ - //バッファにパケットがあれば返却 - NyLPC_cStopwatch_finalize(&sw); - return rlen; - } - //引き続きエラー処理 - default: - //他の場合はエラー - NyLPC_cStopwatch_finalize(&sw); - return -1; - } - //タスクスイッチ - NyLPC_cThread_yield(); - }while(NyLPC_cStopwatch_elapseInMsec(&sw)<i_wait_msec); - //規定時間内に受信が成功しなかった。 - NyLPC_cStopwatch_finalize(&sw); - return 0; -} -/** - * 受信バッファをシークします。 - * シーク後に、遅延ACKを送出します。 - */ -void NyLPC_cTcpSocket_pseek(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt16 i_seek) -{ - void* buf; - NyLPC_ArgAssert(i_seek<=NyLPC_cFifoBuffer_getLength(&(i_inst->rxbuf))); - if(i_seek==0){ - return; - } - - //ACK送信バッファの取得 - buf=NyLPC_cUipService_allocSysTxBuf(); - - //MUTEX LOCK - lockResource(i_inst); - - //受信バッファを読み出しシーク - NyLPC_cFifoBuffer_pop(&(i_inst->rxbuf),i_seek); - //ACKパケットの生成 - setTxPacket(i_inst,buf,TCP_ACK,NULL,0); - unlockResource(i_inst); - //ACK送信 - NyLPC_cUipService_sendIPv4Tx(buf); - NyLPC_cUipService_releaseTxBuf(buf); - -} - -/** - * See header file. - */ -void* NyLPC_cTcpSocket_allocSendBuf(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_buf_size,NyLPC_TUInt32 i_wait_in_msec) -{ - NyLPC_TUInt16 s; - void* buf; - NyLPC_TcStopwatch_t sw; - - NyLPC_cStopwatch_initialize(&sw); - NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec); - - //送信バッファを取得 - //@bug バッファが取れるまで通信がブロックするの。ここはなんとかしないと。 - for(;;){ - //ESTABLISHED以外に非同期遷移 - if(i_inst->tcpstateflags!=UIP_ESTABLISHED){ - NyLPC_cStopwatch_finalize(&sw); - return NULL; - } - buf=NyLPC_cUipService_allocTxBuf(i_hint+(SIZE_OF_IPv4_TCPIP_HEADER),&s); - if(buf!=NULL){ - break; - } - //タイムアウト時もエラー - if(NyLPC_cStopwatch_isExpired(&sw)){ - NyLPC_cStopwatch_finalize(&sw); - return NULL; - } - } - -//@todo 前段処理と順番を入れ替えて、要求サイズとpeerのwinのうち、小さいほうを割り当てたほうが良くない? -//ここで相手のwin待ちをする理由は、相手に確実に受け取れるサイズを決定する為。 - lockResource(i_inst); - //ペイロードがある場合のみ、相手のwindowサイズが0以上になるのを待つ。 - while(i_inst->uip_connr.peer_win==0){ - unlockResource(i_inst); - //ESTABLISHED以外に非同期遷移 orタイムアウト確認 - if(NyLPC_cStopwatch_isExpired(&sw)||(i_inst->tcpstateflags!=UIP_ESTABLISHED)){ - NyLPC_cUipService_releaseTxBuf(buf); - NyLPC_cStopwatch_finalize(&sw); - return NULL; - } - NyLPC_cThread_yield(); - lockResource(i_inst); - } - //送信バッファを基準とした送信サイズを計算 - s-=SIZE_OF_IPv4_TCPIP_HEADER; - //送信サイズよりMMSが小さければ、送信サイズを修正 - if(i_inst->uip_connr.peer_mss<s){ - s=i_inst->uip_connr.peer_mss; - } - //送信サイズよりpeerのウインドウサイズが小さければ修正 - if(i_inst->uip_connr.peer_win<s){ - s=i_inst->uip_connr.peer_win; - } - unlockResource(i_inst); - //バッファサイズ確定。 - *o_buf_size=s; - NyLPC_cStopwatch_finalize(&sw); - return (NyLPC_TUInt8*)buf+SIZE_OF_IPv4_TCPIP_HEADER; -} -/** - * See Header file. - */ -void NyLPC_cTcpSocket_releaseSendBuf(NyLPC_TcTcpSocket_t* i_inst,void* i_buf_ptr) -{ - NyLPC_cUipService_releaseTxBuf((NyLPC_TUInt8*)i_buf_ptr-SIZE_OF_IPv4_TCPIP_HEADER); -} - - -/** - * 事前にAllocしたTxパケットを送信します。 - * このAPIはゼロコピー送信をサポートするためのものです。 - * @param i_buf_ptr - * allocSendBufで取得したメモリを指定します。 - * @return - * 関数が失敗した場合、i_buf_ptrは「開放されません。」 - */ -NyLPC_TBool NyLPC_cTcpSocket_psend(NyLPC_TcTcpSocket_t* i_inst,void* i_buf_ptr,int i_len,NyLPC_TUInt32 i_wait_in_msec) -{ - struct NyLPC_TcTcpSocket_TxQItem* txq; - void* buf; - NyLPC_TcStopwatch_t sw; - //ESTABLISHEDでなければエラー - if(i_inst->tcpstateflags!=UIP_ESTABLISHED){ - //ESTABLISHEDでなければエラー - return NyLPC_TBool_FALSE; - } - //送信データ0なら何もしない。 - if(i_len<1){ - NyLPC_cTcpSocket_releaseSendBuf(i_inst,i_buf_ptr); - return NyLPC_TBool_TRUE; - } - NyLPC_cStopwatch_initialize(&sw); - NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec); - - //先頭ポインタは、i_buf-sizeof(SIZE_OF_IPv4_TCPIP_HEADER)固定 - buf=(NyLPC_TUInt8*)i_buf_ptr-SIZE_OF_IPv4_TCPIP_HEADER; - lockResource(i_inst); - //送信キューの取得 - txq=getTxQ(i_inst,&sw); - //送信キューが取れなかった。 - if(txq==NULL){ - //シーケンス番号をロールバックできないので、エラーとする。 - unlockResource(i_inst); - NyLPC_cStopwatch_finalize(&sw); - return NyLPC_TBool_FALSE; - } - //ここから先はi_bufの所有権はインスタンスになってる。 - - //IPv4ペイロードの書き込み - - //allocをした時点でwin,mssは考慮されているので、そのままそうしんしる。 - - //ACK番号の計算 - txq->rto32=i_inst->uip_connr.current_rto32; - txq->tick_of_sent=NyLPC_cStopwatch_now(); - //パケットヘッダの生成(ヘッダ長はpreadで定義した値(4+6)*4=40です。) - setTxPacketHeader(i_inst,buf,TCP_ACK|TCP_PSH,i_len); - txq->packet=buf; - - //シーケンス番号の更新 - i_inst->uip_connr.snd_nxt32=i_inst->uip_connr.snd_nxt32+i_len; - //Peerのウインドウサイズを更新 - i_inst->uip_connr.peer_win-=i_len; - //ACK番号の返却 - txq->ackno=NyLPC_HTONL(i_inst->uip_connr.snd_nxt32); - unlockResource(i_inst); - NyLPC_cUipService_sendIPv4Tx(buf); - NyLPC_cStopwatch_finalize(&sw); - return NyLPC_TBool_TRUE; -} - -/** - * See header file. - */ -NyLPC_TInt32 NyLPC_cTcpSocket_send(NyLPC_TcTcpSocket_t* i_inst,const void* i_buf_ptr,NyLPC_TInt32 i_len,NyLPC_TUInt32 i_wait_in_msec) -{ - NyLPC_TInt16 hint; - NyLPC_TUInt16 s; - void* buf; - if(i_len<1){ - return 0; - } - hint=(i_len>32767)?32767:i_len; - buf=NyLPC_cTcpSocket_allocSendBuf(i_inst,hint,&s,i_wait_in_msec); - if(buf==NULL){ - return -1; - } - //送信サイズの計算 - s=((NyLPC_TInt32)s<i_len)?s:(NyLPC_TUInt16)i_len; - memcpy(buf,i_buf_ptr,s); - if(!NyLPC_cTcpSocket_psend(i_inst,buf,s,i_wait_in_msec)){ - NyLPC_cTcpSocket_releaseSendBuf(i_inst,buf); - return -1;//error - } - return s; -} - - -void NyLPC_cTcpSocket_close(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_wait_in_msec) -{ - NyLPC_TcStopwatch_t sw; - volatile NyLPC_TUInt8 f; - NyLPC_TUInt32 sq; - NyLPC_cStopwatch_initialize(&sw); - NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec); - lockResource(i_inst); - - f=i_inst->tcpstateflags; - //ステータスチェック - switch(f) - { - case UIP_CLOSED: - //閉じている。 - goto ReturnWithUnlock; - case UIP_ESTABLISHED: - //アクティブクローズ。 - i_inst->tcpstateflags=UIP_FIN_WAIT_1; - //送信のために一旦解除 - unlockResource(i_inst); - //FINの送信 - if(sendWithRetransmit(i_inst,TCP_FIN|TCP_ACK,NULL,0,&sw,&sq)==0){ - //ちょっと待つ。 - NyLPC_cThread_yield(); - //TXの消去待ち - if(waitForTxRemove(i_inst,sq,&sw)){ - //再ロック - lockResource(i_inst); - //タイムアウトするか、UIP_CLOSED、もしくはTIME_WAITに遷移するのを待つ。(遷移はRxprocで自動的に実行。) - do{ - switch(i_inst->tcpstateflags) - { - case UIP_TIME_WAIT: - i_inst->tcpstateflags=UIP_CLOSED; - case UIP_CLOSED: - NyLPC_Assert(i_inst->txbuf.rp==i_inst->txbuf.wp); - //成功。 - goto ReturnWithUnlock; - case UIP_FIN_WAIT_1: - case UIP_FIN_WAIT_2: - case UIP_CLOSING: - //一時的なアンロック - unlockResource(i_inst); - NyLPC_cThread_yield(); - lockResource(i_inst); - default: - break; - } - }while(!NyLPC_cStopwatch_isExpired(&sw)); - unlockResource(i_inst); - } - } - break; - case UIP_CLOSE_WAIT: - //LAST_ACKへ遷移 - i_inst->tcpstateflags=UIP_LAST_ACK; - //送信のために一旦解除 - unlockResource(i_inst); - if(sendWithRetransmit(i_inst,TCP_FIN|TCP_ACK,NULL,0,&sw,&sq)==0){ - //ちょっと待つ。 - NyLPC_cThread_yield(); - //TXの消去待ち - if(waitForTxRemove(i_inst,sq,&sw)){ - //再ロック - lockResource(i_inst); - //TX消去後にCLOSEDに遷移していればOK - if(i_inst->tcpstateflags==UIP_CLOSED) - { - NyLPC_Assert(i_inst->txbuf.rp==i_inst->txbuf.wp); - goto ReturnWithUnlock; - } - unlockResource(i_inst); - } - } - //エラー。RSTで切断。 - break; - default: - unlockResource(i_inst); - NyLPC_Warning(); - break; - } -// if(i_inst->_smutex._lock_count>0){ -// NyLPC_Warning(); -// } - //このパスに到達するのは、FIN送信/ACKに成功したにも拘らず、規定時間内にCLOSEDに遷移しなかった場合。 - //コネクションを強制遷移して、RST - lockResource(i_inst); - f=i_inst->tcpstateflags; - if(f!=UIP_CLOSED){ - //もし、強制CLOSE遷移であれば、RSTも送信。 - i_inst->tcpstateflags=UIP_CLOSED; - unlockResource(i_inst); - sendRst(i_inst); - }else{ - unlockResource(i_inst); - } - NyLPC_cStopwatch_finalize(&sw); - return; -ReturnWithUnlock: - unlockResource(i_inst); - NyLPC_cStopwatch_finalize(&sw); - return; -} - -/** - * uipサービスタスクが実行する関数です。 - * 定期的に実行する関数。最低でも1s単位で実行してください。 - */ -void NyLPC_cTcpSocket_periodic( - NyLPC_TcTcpSocket_t* i_inst) -{ - int i; - struct NyLPC_TcTcpSocket_TxQItem* q=i_inst->txbuf.txq; - NyLPC_TcStopwatch_t sw; - NyLPC_TUInt32 now; - int rp; - NyLPC_cStopwatch_initialize(&sw); - now=NyLPC_cStopwatch_now(); - //MUTEX LOCK - lockResource(i_inst); - if(i_inst->tcpstateflags==UIP_CLOSED) - { - //CLOSEDなら、バッファ開放。 - resetTxQWithUnlock(i_inst); - }else if(i_inst->txbuf.rp==i_inst->txbuf.wp){ - //再送信パケットがなければ何もしないよ。 - unlockResource(i_inst); - }else if(i_inst->uip_connr.peer_win==0){ - //peer_winが0の場合は何もしない。 - unlockResource(i_inst); - }else{ - //再送信処理 - rp=i_inst->txbuf.rp; - NyLPC_cStopwatch_set(&sw,q[rp].tick_of_sent); - if(NyLPC_cStopwatch_elapseInMsec(&sw)>q[rp].rto32){ - //最古のパケットの送信時間をチェックして、タイムアウトが発生したら、再送時間と送信時刻をセット - //最古パケットRTOを2倍。 - q[rp].rto32*=2; - for(i=rp;i!=i_inst->txbuf.wp;i=(i+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ){ - q[i].tick_of_sent=now; - } - if(q[rp].rto32>UIP_IP_RTO_MAX_RTO){ - //最古のRTOが64秒を超えたら、CLOSED - i_inst->tcpstateflags =UIP_CLOSED; - resetTxQWithUnlock(i_inst); - sendRst(i_inst); - }else{ - //規定時間内なら、再送処理 - for(i=rp;i!=i_inst->txbuf.wp;i=(i+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ){ -// NyLPC_cUipService_sendIPv4Tx(NyLPC_cIPv4Payload_getBuf(&(q[i].data))); - NyLPC_cUipService_sendIPv4Tx(q[i].packet); - } - unlockResource(i_inst); - } - }else{ - unlockResource(i_inst); - } - } - NyLPC_cStopwatch_finalize(&sw); - return; -} -/** - * uipサービスタスクが実行する関数です。 - * サービスの開始を通知します。 - */ -void NyLPC_cTcpSocket_startService(NyLPC_TcTcpSocket_t* i_inst,const NyLPC_TcIPv4Config_t* i_config) -{ - NyLPC_Assert(i_inst->tcpstateflags==UIP_CLOSED);//閉じてなければおかしい。 - i_inst->uip_connr.lipaddr=&(i_config->ip_addr); - i_inst->uip_connr.default_mss=i_config->default_mss; - //NyLPC_cTcpSocket_setSynPayload関数でも実行するけど、IFのリセット時なのでここでもやる。 - NyLPC_cFifoBuffer_clear(&(i_inst->rxbuf)); - return; -} -/** - * uipサービスタスクが実行する関数です。 - * サービスの停止を通知します。 - */ -void NyLPC_cTcpSocket_stopService(NyLPC_TcTcpSocket_t* i_inst) -{ - lockResource(i_inst); - if(i_inst->tcpstateflags==UIP_CLOSED) - { - unlockResource(i_inst); - }else{ - i_inst->tcpstateflags=UIP_CLOSED; - resetTxQWithUnlock(i_inst); - sendRst(i_inst); - } - return; -} - - -void* NyLPC_cTcpSocket_parseRx( - NyLPC_TcTcpSocket_t* i_inst, - const NyLPC_TcIPv4Payload_t* i_ipp) -{ - int i,s; - NyLPC_TUInt16 tmp16; - NyLPC_TUInt16 data_size; - NyLPC_TUInt8 in_tcpflag=i_ipp->payload.tcp->flags; - const void* tcp_data_offset; - NyLPC_TBool is_new_packet; - int num_of_noack; - void* dlist[NyLPC_TcTcpSocket_NUMBER_OF_TXQ]; - void* ret; - - //パラメータの計算 - - tmp16=NyLPC_TTcpHeader_getHeaderLength(i_ipp->payload.tcp); - //TCPペイロードの長さは、IPパケットの長さ-(IPヘッダ+TCPヘッダ) - data_size=NyLPC_TIPv4Header_getPacketLength(i_ipp->header)-NyLPC_TIPv4Header_getHeaderLength(i_ipp->header)-tmp16; - //TCPデータオフセット - tcp_data_offset=i_ipp->payload.rawbuf+tmp16; - - //インスタンスをロックする。 - lockResource(i_inst); - - //RSTのチェック。RST受信時は、状態にかかわらず、CLOSEDステータスに移行する。 - if (in_tcpflag & TCP_RST) - { - i_inst->tcpstateflags =UIP_CLOSED; - goto DROP; - } - - - is_new_packet=NyLPC_ntohl(i_ipp->payload.tcp->seqno32)==i_inst->uip_connr.rcv_nxt32; - - - //OPTIONの反映 - - //MSSの取得 - if(NyLPC_TTcpHeader_getTcpMmsOpt(i_ipp->payload.tcp,&tmp16)){ - //取得で着たら更新 - i_inst->uip_connr.peer_mss=tmp16; - } - //受信パケットを元に、未ACKパケットの数を計算 - num_of_noack=getNumOfSending(i_inst,i_ipp->payload.tcp->ackno32);//i_inst->txbuf.num_of_txq; - - //ステータス毎のACK応答 - switch(i_inst->tcpstateflags) - { - case UIP_SYN_RCVD: - //ACKを受信したら、ESTABLISHEDへ。 - //すべてのパケットをACKしたかで判定。() - if(num_of_noack==0){ - i_inst->tcpstateflags=UIP_ESTABLISHED; - }else{ - //それ以外のパケットはドロップする。 - break;//goto DROP; - } - //新しいパケットがなければ、無応答 - if(!is_new_packet){ - break;//goto DROP; - } - //引き続き、ESTABLISHEDの処理へ。 - case UIP_ESTABLISHED: - if(data_size>0){ - if(is_new_packet){ - if(addRecvData(i_inst,tcp_data_offset,data_size)){ - //通常のACK返却 - i_inst->uip_connr.rcv_nxt32+=data_size; - }else{ - //失敗したときは必要に応じて単純ACK - } - } - } - //どちらにしろ、ACK送信 - if(is_new_packet && (in_tcpflag & TCP_FIN)){ - //FINがあるときは、ステータスをCLOSE_WAITへセットして、ACKを返す。 - i_inst->tcpstateflags = UIP_CLOSE_WAIT; - i_inst->uip_connr.rcv_nxt32++; - } - break; - case UIP_CLOSE_WAIT: - //必要に応じたACK応答 - break; - case UIP_LAST_ACK: - //ACK(by FIN)が得られたなら、CLOSEDへ。 - if(num_of_noack==0){ - i_inst->tcpstateflags=UIP_CLOSED; - } - //必要に応じたACK応答 - break; - case UIP_FIN_WAIT_1: - //FIN受信->CLOSINGへ - if(is_new_packet){ - i_inst->uip_connr.rcv_nxt32+=data_size; - if(in_tcpflag & TCP_FIN){ - i_inst->uip_connr.rcv_nxt32++; - if(num_of_noack==0){ - //FINとACKを受信 - i_inst->tcpstateflags=UIP_TIME_WAIT; - }else{ - //FINのみ - i_inst->tcpstateflags=UIP_CLOSING; - } - } - }else if(num_of_noack==0){ - //ACKのみ - i_inst->tcpstateflags=UIP_FIN_WAIT_2; - } - //必要に応じたACK応答 - break; - case UIP_FIN_WAIT_2: - //FIN受信->TIME_WAITへ(pureACK) - if(is_new_packet && (in_tcpflag & TCP_FIN)){ - i_inst->uip_connr.rcv_nxt32++; - i_inst->tcpstateflags=UIP_TIME_WAIT; - } - break; - case UIP_CLOSING: - //ACK受信したら、TIME_WAITへ - if(num_of_noack==0){ - i_inst->tcpstateflags=UIP_TIME_WAIT; - } - break; - case UIP_CLOSED: - //何もできない。何もしない。 - break; - case UIP_TIME_WAIT: - //最終ACKを送り続ける。 - break; - case UIP_SYN_SENT: - //connect関数実行中しか起動しないステータス - if(num_of_noack==0){ - i_inst->tcpstateflags=UIP_ESTABLISHED; - i_inst->uip_connr.rcv_nxt32=NyLPC_ntohl(i_ipp->payload.tcp->seqno32)+1; - }else{ - //それ以外のパケットはドロップする。 - break;//goto DROP; - } - //ACKを送る。 - break; - default: - goto DROP; - } - //ウインドウサイズを更新 - i_inst->uip_connr.peer_win=NyLPC_ntohs(i_ipp->payload.tcp->wnd16); - - //送信キューから、Peerが受信したデータを削除する。 - if(in_tcpflag & TCP_ACK){ - //再送パケットキューから送信済みのデータを回収(後で開放) - NyLPC_Trace(); - s=updateTxQByIndex(i_inst,i_ipp->payload.tcp->ackno32,dlist); - NyLPC_Trace(); - }else{ - s=0; - } - //新しいパケットがきた場合は、再送キューのACKを更新する。 - if(is_new_packet){ - //再送キューのACKを更新 - updateTxAck(i_inst,NyLPC_htonl(i_inst->uip_connr.rcv_nxt32)); - } - - //送信キューのない - if(((in_tcpflag&(TCP_FIN|TCP_SYN))!=0x00) || - ((!is_new_packet) && (data_size>0))) - { - //ソケットからPureACKを生成 as setPacket(i_inst,i_ipp,TCP_ACK,NULL,0); - ret=NyLPC_cUipService_allocSysTxBuf(); - setTxPacket(i_inst,ret,TCP_ACK,NULL,0); - }else{ - ret=NULL; - } - unlockResource(i_inst); - //取り外したTXメモリの開放 - for(i=0;i<s;i++){ - //取り外したTXメモリを開放 - NyLPC_cUipService_releaseTxBuf(dlist[i]); - } -NyLPC_Trace(); - return ret; -DROP: - //ACKしたパケットを送信キューから削除 - unlockResource(i_inst); -NyLPC_Trace(); - return NULL; -} - - -/** - * 入力されたパケットからRSTパケットを生成して返す。 - */ -void* NyLPC_cTcpSocket_allocTcpReverseRstAck( - const NyLPC_TcIPv4Payload_t* i_src) -{ - struct NyLPC_TIPv4Header* iph; - struct NyLPC_TTcpHeader* tcph; - NyLPC_TUInt8 iph_word=0x05; - NyLPC_TUInt8 tcph_word=(UIP_TCPH_LEN) / 4; - void* txb=NyLPC_cUipService_allocSysTxBuf(); - //IPヘッダの更新 - iph=(struct NyLPC_TIPv4Header*)txb; - iph->vhl=0x40|(0x0f&iph_word); - iph->destipaddr=i_src->header->srcipaddr; - iph->srcipaddr =i_src->header->destipaddr; - NyLPC_TIPv4Header_writeTxIpHeader(iph,UIP_PROTO_TCP); - - //TCPヘッダの更新 - tcph=(struct NyLPC_TTcpHeader*)(((NyLPC_TUInt8*)txb)+NyLPC_TIPv4Header_getHeaderLength(iph)); - - tcph->tcpoffset=(tcph_word<<4); - - tcph->flags = TCP_RST | TCP_ACK; - //sorce & destination port - tcph->srcport = i_src->payload.tcp->destport; - tcph->destport = i_src->payload.tcp->srcport; - //ACK number - tcph->ackno32 = NyLPC_htonl(NyLPC_ntohl(i_src->payload.tcp->seqno32)+1); - //Seq Number - tcph->seqno32 = i_src->payload.tcp->ackno32; - //uip_func_tcp_send_noconn(BUF); - tcph->urgp[0] = tcph->urgp[1] = 0; - tcph->tcpchksum= 0; - - - //最終的なパケットサイズと必要ならペイロードを書き込み - iph->len16=NyLPC_htons((iph_word+tcph_word)*4); - //WND設定 - tcph->wnd16=0; - //Checksumの生成 - tcph->tcpchksum=~(NyLPC_TIPv4Header_makeTcpChecksum(iph)); - iph->ipchksum = ~(NyLPC_TIPv4Header_makeIpChecksum(iph)); - return txb; -} - - - -
--- a/core/uip/NyLPC_cTcpSocket.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,226 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - *********************************************************************************/ -#ifndef NYLPC_CTCPSOCKET_H_ -#define NYLPC_CTCPSOCKET_H_ - - - -#include "NyLPC_uip.h" -#include "NyLPC_os.h" -#include "NyLPC_cIPv4Payload.h" -#include "NyLPC_cBaseSocket.h" - - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -typedef struct NyLPC_TcTcpSocket NyLPC_TcTcpSocket_t; - - -/********************************************************************** - * - * NyLPC_TTcpListenerSynInfo struct - * - **********************************************************************/ - - -struct NyLPC_TTcpSocketSynParam -{ - struct NyLPC_TIPv4Addr srcaddr; - NyLPC_TUInt16 rport; - NyLPC_TUInt16 mss; - NyLPC_TUInt32 rcv_nxt32; -}; - - -/********************************************************************** - * - * NyLPC_TcTcpSocket_TxQItem struct - * - **********************************************************************/ - -/** - * TXキューの数。この値は8未満にしてください。 - */ -#define NyLPC_TcTcpSocket_NUMBER_OF_TXQ 4 - -struct NyLPC_TcTcpSocket_TxQItem -{ - //最終更新時刻 - NyLPC_TUInt32 tick_of_sent; - //このパケットのRTO(秒間隔) - NyLPC_TUInt32 rto32; - void* packet; - //パケットのACK番号。この番号を受信できれば、再送パケットは消去可能である。 - NyLPC_TUInt32 ackno; -}; - -/********************************************************************** - * - * uip_conn struct - * - **********************************************************************/ - -struct uip_conn -{ - struct NyLPC_TIPv4Addr ripaddr; /**< The IP address of the remote host. */ - const struct NyLPC_TIPv4Addr* lipaddr; /**< ローカルIP*/ - NyLPC_TUInt16 lport; /**< The local TCP port, in network byte order. */ - NyLPC_TUInt16 rport; /**< The local remote TCP port, in network byte order. */ - NyLPC_TUInt32 rcv_nxt32; /**< The sequence number that we expect to receive next. */ - NyLPC_TUInt32 snd_nxt32; /**< 送信用sqカウンター*/ - NyLPC_TUInt16 peer_mss; /**< PeerのMSS*/ - NyLPC_TUInt16 default_mss; /**< Peerの初期MMS*/ - /**Peerのウインドウサイズ*/ - NyLPC_TUInt16 peer_win; - NyLPC_TUInt16 _padding; - /**現在ソケットのRTO*/ - NyLPC_TUInt32 current_rto32; -}; - - - - - - - - -/********************************************************************** - * - * NyLPC_TcTcpSocket class - * - **********************************************************************/ - -/** - * uipサービスを使用したTCPソケットクラスです。 - * この関数は2つのタスクから呼び出されます。 - * [uipTask] -> [cTcpSocket] <- [Application] - * ApplicationとuipTaskとの間での排他処理はインスタンスで制御されています。 - * Application側からのコールは内部でuipTaskとの間で排他処理を実行します。 - * Application側からのコールはリエントラントではありません。 - */ - -struct NyLPC_TcTcpSocket -{ - /** Base class*/ - NyLPC_TcBaseSocket_t _super; - //この変数は、uipタスクの実行する関数のみが変更する。 - struct uip_conn uip_connr; - NyLPC_TcFifoBuffer_t rxbuf; - struct{ - NyLPC_TUInt8 rp; - NyLPC_TUInt8 wp; - //送信キュー - struct NyLPC_TcTcpSocket_TxQItem txq[NyLPC_TcTcpSocket_NUMBER_OF_TXQ]; - }txbuf; - volatile NyLPC_TUInt8 tcpstateflags; /**< TCP state and flags. */ -}; - - -#define NyLPC_cTcpSocket_getPeerAddr(i_inst) (&((i_inst)->uip_connr.ripaddr)) -#define NyLPC_cTcpSocket_getPeerPort(i_inst) (((i_inst)->uip_connr.rport)) - -/** - * 初期化関数です。 - * uipserviceは初期化済である必要があります。 - * また、暫定条件として、サービスが停止中である必要もあります。 - * @param i_recv_buf - * 受信バッファを指定します。 - */ -NyLPC_TBool NyLPC_cTcpSocket_initialize(NyLPC_TcTcpSocket_t* i_inst,void* i_rbuf,NyLPC_TUInt16 i_rbuf_len); -/** - * 終期化関数です。 - * uipserviceは初期化済である必要があります。 - * また、暫定条件として、サービスが停止中である必要もあります。 - */ -void NyLPC_cTcpSocket_finalize(NyLPC_TcTcpSocket_t* i_inst); - -NyLPC_TBool NyLPC_cTcpSocket_accept(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_wait_in_msec); -/** - * @return - * 1 - 以上:受信に成功した。 - * 0 - タイムアウト - * -1 - ソケットがクローズしている - */ -NyLPC_TInt32 NyLPC_cTcpSocket_precv(NyLPC_TcTcpSocket_t* i_inst,const void** o_buf_ptr,NyLPC_TUInt32 i_wait_msec); -void NyLPC_cTcpSocket_pseek(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt16 i_seek); -/** - * 送信未達は保障されません。 - * エラーを検出したら、基本的にはソケットをクローズしてください。 - * @param i_wait_msec - * 送信失敗までの待ち時間を指定します。現在は、 - * RTT推定ができないため、TCPの再送を考慮して、最低でも10秒(10000)程度を指定してください。 - * @return - * 送信したバイト数を返します。エラーならば0未満の数を返します。 - * - */ -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); -void NyLPC_cTcpSocket_close(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_wait_in_msec); - - -/** - * NyLPC_cTcpSocket_psendで送信するための送信バッファ準備します。 - * @param i_hint - * 送信を希望するデータサイズを指定します。 - * アロケータは出来る限り希望に沿ってメモリを返します。 - * @param o_buf_size - * 取得できたバッファサイズを返します。 - * @return - * 成功した場合、送信バッファを返します。 - * アプリケーションは、可能な限り速やかにデータを書き込んで、NyLPC_cTcpSocket_psendをコールしてください。 - * @note - * Optionフィールドを持つパケットを送信する場合は、オプションデータサイズの合計をデータサイズに指定して、payloadwriterで調整すること。 - */ -void* NyLPC_cTcpSocket_allocSendBuf(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_buf_size,NyLPC_TUInt32 i_wait_in_msec); - -/** - * NyLPC_cTcpSocket_allocSendBufで確保したメモリを開放します。 - */ -void NyLPC_cTcpSocket_releaseSendBuf(NyLPC_TcTcpSocket_t* i_inst,void* i_buf_ptr); - -/** - * 事前にAllocしたTxパケットを送信します。 - * このAPIはゼロコピー送信をサポートするためのものです。 - * @param i_buf_ptr - * allocSendBufで取得したメモリを指定します。 - * @return - * 失敗した場合、メモリは開放されません。 - */ -NyLPC_TBool NyLPC_cTcpSocket_psend(NyLPC_TcTcpSocket_t* i_inst,void* i_buf_ptr,int i_len,NyLPC_TUInt32 i_wait_in_msec); - -/** - * TCPソケットをクライアントとしてサーバへ接続します。 - */ -NyLPC_TBool NyLPC_cTcpSocket_connect(NyLPC_TcTcpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_peer_port,NyLPC_TUInt32 i_wait_in_msec); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* NYLPC_CTCPSOCKET_H_ */
--- a/core/uip/NyLPC_cTcpSocket_protected.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,113 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - *********************************************************************************/ - -#ifndef NYLPC_CTCPSOCKET_PROTECTED_H_ -#define NYLPC_CTCPSOCKET_PROTECTED_H_ -#include "NyLPC_cIPv4.h" -#include "NyLPC_cTcpSocket.h" -#include "NyLPC_cIPv4Config.h" -#include "NyLPC_cIPv4Payload_protected.h" -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/********************************************************************** - * ステータス値の定義 - **********************************************************************/ -#define UIP_CLOSED 0 -#define UIP_SYN_RCVD 1 -#define UIP_SYN_SENT 2 -#define UIP_ESTABLISHED 3 -#define UIP_FIN_WAIT_1 4 -#define UIP_FIN_WAIT_2 5 -#define UIP_CLOSING 6 -#define UIP_TIME_WAIT 7 -#define UIP_CLOSE_WAIT 8 -#define UIP_LAST_ACK 9 - - - - - - - - -/** - * パース結果をもとに、ソケットのuipconnectionを初期化します。 - * この関数は、cUipServiceからのみコールできます。 - */ -void NyLPC_cTcpSocket_initConnection(NyLPC_TcTcpSocket_t* i_inst,const NyLPC_TcIPv4Config_t* i_config,const NyLPC_TcIPv4Payload_t* i_ipp); - -/** - * TCPペイロードを処理して、応答パケットをペイロードに返します。 - * uipサービスタスクが実行する関数です。 - * @return - * 応答パケットを格納したメモリブロックを返します。 - * このメモリは、NyLPC_cUipService_allocSysTxBuf関数で確保されたメモリです。 - */ -void* NyLPC_cTcpSocket_parseRx( - NyLPC_TcTcpSocket_t* i_inst, - const NyLPC_TcIPv4Payload_t* i_ipp); - -/** - * 定期的に実行する関数。最低でも1s単位で実行してください。 - * uipサービスタスクが実行する関数です。 - */ -void NyLPC_cTcpSocket_periodic( - NyLPC_TcTcpSocket_t* i_inst); - -/** - * CLOSEステータスのソケットを、SYN情報の内容でSYNRECV状態にします。 - * この関数は、NyLPC_TcTcpListenerクラスからコールされます。 - * @return - * 遷移に成功すると、TRUEを返します。 - */ -NyLPC_TBool NyLPC_cTcpSocket_listenSyn(NyLPC_TcTcpSocket_t* i_inst,const struct NyLPC_TTcpSocketSynParam* i_lq,NyLPC_TUInt16 i_lport); - - -/** - * uipサービスタスクが実行する関数です。 - * サービスの開始を通知します。 - * この関数は他のAPIが非同期に実行されないことが保証される状況で使用する必要があります。 - */ -void NyLPC_cTcpSocket_startService(NyLPC_TcTcpSocket_t* i_inst,const NyLPC_TcIPv4Config_t* i_config); - -/** - * uipサービスタスクが実行する関数です。 - * サービスの停止を通知します。 - * この関数は他のAPIが非同期に実行されないことが保証される状況で使用する必要があります。 - */ -void NyLPC_cTcpSocket_stopService(NyLPC_TcTcpSocket_t* i_inst); - - -void* NyLPC_cTcpSocket_allocTcpReverseRstAck( - const NyLPC_TcIPv4Payload_t* i_src); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* NYLPC_CTCPSOCKET_PROTECTED_H_ */
--- a/core/uip/NyLPC_cUdpSocket.c Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,364 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - * - * Parts of this file were leveraged from uIP: - * - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "NyLPC_cUdpSocket_protected.h" -#include "NyLPC_cIPv4Payload_protected.h" -#include "NyLPC_cUipService_protected.h" - -/** - * フラグ値 - */ -#define NyLPC_cUdpSocket_FLAG_BROADCAST 0 - -#define lockResource(i_inst) NyLPC_cMutex_lock(((i_inst)->_smutex)) -#define unlockResource(i_inst) NyLPC_cMutex_unlock(((i_inst)->_smutex)) - -#define SIZE_OF_IPv4_UDPIP_HEADER 28 - - - - -/** - * IP+UDPヘッダサイズを0x05*4+8バイトとして、UDPの送信バッファをセットします。 - */ -static void setUdpTxBufHeader(const NyLPC_TcUdpSocket_t* i_inst,void*i_buf,const struct NyLPC_TIPv4Addr* i_dest_ip,NyLPC_TUInt16 i_dest_port,NyLPC_TUInt8 i_iph_word,NyLPC_TUInt16 i_payload_size) -{ - struct NyLPC_TIPv4Header* header=(struct NyLPC_TIPv4Header*)i_buf; - struct NyLPC_TUdpHeader* udp =(struct NyLPC_TUdpHeader*)(((NyLPC_TUInt8*)i_buf)+i_iph_word*4); - - header->vhl=0x40|(0x0f&i_iph_word); - header->len16=NyLPC_htons(i_payload_size+(i_iph_word*4+8)); - udp->udplen=NyLPC_htons(i_payload_size+(8)); - //IPv4のTxヘッダを書き込む。 - header->destipaddr=*i_dest_ip; - header->srcipaddr =i_inst->uip_udp_conn.lipaddr; - - NyLPC_TIPv4Header_writeTxIpHeader(header,UIP_PROTO_UDP); - - //UDPのTxヘッダを書き込む - //sorce & destination port - udp->srcport = i_inst->uip_udp_conn.lport; - udp->destport = NyLPC_htons(i_dest_port); - udp->udpchksum= 0; - - udp->udpchksum=~(NyLPC_TIPv4Header_makeTcpChecksum(header)); - header->ipchksum = ~(NyLPC_TIPv4Header_makeIpChecksum(header)); -} - - - - -NyLPC_TBool NyLPC_cUdpSocket_initialize(NyLPC_TcUdpSocket_t* i_inst,NyLPC_TUInt16 i_port,void* i_rbuf,NyLPC_TUInt16 i_rbuf_len) -{ - NyLPC_TcUipService_t* srv=_NyLPC_TcUipService_inst; - NyLPC_cBaseSocket_initialize(&(i_inst->_super),NyLPC_TcBaseSocket_TYPEID_UDP_SOCK); - //uipサービスは初期化済であること。 - NyLPC_Assert(NyLPC_TcUipService_isInitService()); - i_inst->_smutex=NyLPC_cIPv4_getSockMutex(&(srv->_tcpv4)); - i_inst->uip_udp_conn.lport=NyLPC_htons(i_port); - i_inst->uip_udp_conn.mcastaddr=NyLPC_TIPv4Addr_ZERO; - i_inst->uip_udp_conn.flags=0x00; - i_inst->as_handler.rx=NULL; - i_inst->as_handler.periodic=NULL; - - NyLPC_cFifoBuffer_initialize(&(i_inst->rxbuf),i_rbuf,i_rbuf_len); - //管理リストへ登録。 - return NyLPC_cIPv4_addSocket(&(srv->_tcpv4),&(i_inst->_super)); -} - -void NyLPC_cUdpSocket_finalize(NyLPC_TcUdpSocket_t* i_inst) -{ - NyLPC_TcUipService_t* srv=_NyLPC_TcUipService_inst; - NyLPC_Assert(NyLPC_TcUipService_isInitService()); - //uipサービスは初期化済であること。 - if(!NyLPC_cIPv4_removeSocket(&(srv->_tcpv4),&(i_inst->_super))){ - //削除失敗、それは死を意味する。 - NyLPC_Abort(); - } - NyLPC_cFifoBuffer_finalize(&(i_inst->rxbuf)); - NyLPC_cBaseSocket_finalize(&(i_inst->_super)); - return; -} -void NyLPC_cUdpSocket_joinMulticast(NyLPC_TcUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr) -{ - i_inst->uip_udp_conn.mcastaddr=*i_addr; -} -void NyLPC_cUdpSocket_setBroadcast(NyLPC_TcUdpSocket_t* i_inst) -{ - NyLPC_TUInt8_setBit(i_inst->uip_udp_conn.flags,NyLPC_cUdpSocket_FLAG_BROADCAST); -} - - - -/** - * この関数は、rxパケットを処理して、ソケットの状態を更新します。 - * uipサービスタスクが実行する関数です。 - * この関数はNyLPC_cTcpSocket_periodicと排他実行すること。 - */ -NyLPC_TBool NyLPC_cUdpSocket_parseRx( - NyLPC_TcUdpSocket_t* i_inst, - const NyLPC_TcIPv4Payload_t* i_ipp) -{ - NyLPC_TUInt16 tmp16; - struct NyLPC_TIPv4RxInfo dheader; - const void* data_offset; - //ブロードキャストの場合、フラグを確認 - if(NyLPC_TIPv4Addr_isEqual(&(i_ipp->header->destipaddr),&NyLPC_TIPv4Addr_BROADCAST)){ - if(!NyLPC_TUInt8_isBitOn(i_inst->uip_udp_conn.flags,NyLPC_cUdpSocket_FLAG_BROADCAST)){ - goto DROP; - } - } - //パラメータの計算 - tmp16=NyLPC_TUdpHeader_getHeaderLength(i_ipp->payload.tcp); - //UDPペイロードの長さは、IPパケットの長さ-(IPヘッダ+UDPヘッダ) - dheader.size=NyLPC_TIPv4Header_getPacketLength(i_ipp->header)-NyLPC_TIPv4Header_getHeaderLength(i_ipp->header)-tmp16; - dheader.peer_ip=i_ipp->header->srcipaddr; - dheader.peer_port=NyLPC_ntohs(i_ipp->payload.udp->srcport); - dheader.ip=i_ipp->header->destipaddr; - dheader.port=NyLPC_ntohs(i_ipp->payload.udp->destport); - if(i_inst->as_handler.rx!=NULL){ - if(!i_inst->as_handler.rx(i_inst,i_ipp->payload.rawbuf+tmp16,&dheader)){ - return NyLPC_TBool_FALSE;//UDPはReturnパケットなし - } - } - //TCPデータオフセット - data_offset=i_ipp->payload.rawbuf+tmp16; - - //インスタンスをロックする。 - lockResource(i_inst); - //受信キューへ追加(データ構造はsize[2]+data[n]).sizeに16ビットの受信サイズ,後続にデータ - - //受信データサイズを確認 - if(NyLPC_cFifoBuffer_getSpace(&(i_inst->rxbuf))<dheader.size+sizeof(struct NyLPC_TIPv4RxInfo)){ - goto DROP; - } - //バッファに格納可能なら、格納。 - NyLPC_cFifoBuffer_push(&(i_inst->rxbuf),&dheader,sizeof(struct NyLPC_TIPv4RxInfo)); - NyLPC_cFifoBuffer_push(&(i_inst->rxbuf),data_offset,dheader.size); - unlockResource(i_inst); - return NyLPC_TBool_FALSE;//UDPはReturnパケットなし -DROP: - unlockResource(i_inst); - return NyLPC_TBool_FALSE; -} - - - -/** - * see Header file - */ -NyLPC_TInt32 NyLPC_cUdpSocket_precv(NyLPC_TcUdpSocket_t* i_inst,const void** o_buf_ptr,const struct NyLPC_TIPv4RxInfo** o_info,NyLPC_TUInt32 i_wait_msec) -{ - NyLPC_TUInt16 rlen; - //タイマを生成 - NyLPC_TcStopwatch_t sw; - NyLPC_cStopwatch_initialize(&sw); - const char* b; - const struct NyLPC_TIPv4RxInfo* rh; - - //ESTABLISHED以外の場合は、エラー。 - NyLPC_cStopwatch_setNow(&sw); - while(NyLPC_cStopwatch_elapseInMsec(&sw)<i_wait_msec) - { - //MUTEX LOCK - lockResource(i_inst); - rlen=NyLPC_cFifoBuffer_getLength(&(i_inst->rxbuf)); - //MUTEX UNLOCK - unlockResource(i_inst); - if(rlen>0){ - //受信キューにデータがあれば返す。 - b=(char*)NyLPC_cFifoBuffer_getPtr(&(i_inst->rxbuf)); - rh=(const struct NyLPC_TIPv4RxInfo*)b; - *o_buf_ptr=b+sizeof(struct NyLPC_TIPv4RxInfo); - if(o_info!=NULL){ - *o_info=rh; - } - return rh->size; - } - //タスクスイッチ - NyLPC_cThread_yield(); - }; - NyLPC_cStopwatch_finalize(&sw); - return 0; -} -/** - * See header file - */ -void NyLPC_cUdpSocket_pseek(NyLPC_TcUdpSocket_t* i_inst) -{ - NyLPC_TUInt16 s; - const struct NyLPC_TIPv4RxInfo* rh; - //シークサイズを決定 - s=NyLPC_cFifoBuffer_getLength(&(i_inst->rxbuf)); - if(s==0){ - return; - } - rh=(const struct NyLPC_TIPv4RxInfo*)NyLPC_cFifoBuffer_getPtr(&(i_inst->rxbuf)); - NyLPC_cFifoBuffer_pop(&(i_inst->rxbuf),rh->size+sizeof(struct NyLPC_TIPv4RxInfo)); -} - -/** - * See header file. - */ -void* NyLPC_cUdpSocket_allocSendBuf(NyLPC_TcUdpSocket_t* i_inst,NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_buf_size,NyLPC_TUInt32 i_wait_in_msec) -{ - NyLPC_TUInt16 s; - void* buf; - NyLPC_TcStopwatch_t sw; - - NyLPC_cStopwatch_initialize(&sw); - NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec); - - //送信バッファを取得 - //@bug バッファが取れるまで通信がブロックするの。ここはなんとかしないと。 - for(;;){ - buf=NyLPC_cUipService_allocTxBuf(i_hint+(SIZE_OF_IPv4_UDPIP_HEADER),&s); - if(buf!=NULL){ - break; - } - //タイムアウト確認 - if(NyLPC_cStopwatch_isExpired(&sw)){ - return NULL; - } - } - //バッファサイズ確定。 - *o_buf_size=s; - NyLPC_cStopwatch_finalize(&sw); - return (NyLPC_TUInt8*)buf+SIZE_OF_IPv4_UDPIP_HEADER; -} -/** - * See Header file. - */ -void NyLPC_cUdpSocket_releaseSendBuf(NyLPC_TcUdpSocket_t* i_inst,void* i_buf_ptr) -{ - NyLPC_cUipService_releaseTxBuf((NyLPC_TUInt8*)i_buf_ptr-SIZE_OF_IPv4_UDPIP_HEADER); -} - -/** - * See header file - */ -NyLPC_TBool NyLPC_cUdpSocket_psend(NyLPC_TcUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_port,void* i_buf_ptr,int i_len) -{ - void* buf; - //ブロードキャストの場合、フラグを確認 - if(NyLPC_TIPv4Addr_isEqual(i_addr,&NyLPC_TIPv4Addr_BROADCAST)){ - if(!NyLPC_TUInt8_isBitOn(i_inst->uip_udp_conn.flags,NyLPC_cUdpSocket_FLAG_BROADCAST)){ - return NyLPC_TBool_FALSE; - } - } - - //先頭ポインタは、i_buf-sizeof(SIZE_OF_IPv4_TCPIP_HEADER)固定 - buf=(NyLPC_TUInt8*)i_buf_ptr-SIZE_OF_IPv4_UDPIP_HEADER; - - lockResource(i_inst); - //IPv4ペイロードの書き込み - setUdpTxBufHeader(i_inst,buf,i_addr,i_port,0x05,i_len); - unlockResource(i_inst); - // !(BroadCast || Multicast)の場合は送信前にARPテーブルをチェックする。 - if(!(NyLPC_TIPv4Addr_isEqual(i_addr,&NyLPC_TIPv4Addr_BROADCAST) || NyLPC_TIPv4Addr_isEqualWithMask(i_addr,&NyLPC_TIPv4Addr_MULTICAST,&NyLPC_TIPv4Addr_MULTICAST_MASK))){ - if(!NyLPC_cUipService_hasArpInfo(i_addr)){ - NyLPC_cUipService_sendArpRequest(i_addr); - NyLPC_cThread_sleep(30); - } - } - NyLPC_cUipService_sendIPv4Tx(buf); - NyLPC_cUipService_releaseTxBuf(buf); - return NyLPC_TBool_TRUE; -} - -/** - * See header file. - */ -NyLPC_TInt32 NyLPC_cUdpSocket_send(NyLPC_TcUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_port,const void* i_buf_ptr,NyLPC_TInt32 i_len,NyLPC_TUInt32 i_wait_in_msec) -{ - NyLPC_TUInt16 s; - int i; - void* buf; - if(i_len<1 || i_len>1200){ - return 0; - } - //バッファの取得確率を上げるために2倍のサイズを要求 - for(i=0;i<3;i++){ - buf=NyLPC_cUdpSocket_allocSendBuf(i_inst,i_len*2,&s,i_wait_in_msec); - if(buf==NULL || s<i_len){ - continue; - } - break; - } - if(buf==NULL){ - return -1; - } - //送信サイズの計算 - memcpy(buf,i_buf_ptr,i_len); - if(!NyLPC_cUdpSocket_psend(i_inst,i_addr,i_port,buf,i_len)){ - NyLPC_cUdpSocket_releaseSendBuf(i_inst,buf); - return -1; - } - return i_len; -} - -void NyLPC_cUdpSocket_startService(NyLPC_TcUdpSocket_t* i_inst,const NyLPC_TcIPv4Config_t* i_config) -{ - i_inst->uip_udp_conn.lipaddr=i_config->ip_addr; - //受信バッファのクリア - NyLPC_cFifoBuffer_clear(&(i_inst->rxbuf)); - return; -} - - -void NyLPC_cUdpSocket_stopService(NyLPC_TcUdpSocket_t* i_inst) -{ - //停止処理? -} -
--- a/core/uip/NyLPC_cUdpSocket.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,159 +0,0 @@ -/* - * NyLPC_cUdpSocket.h - * - * Created on: 2013/05/20 - * Author: nyatla - */ - -#ifndef NYLPC_CUDPSOCKET_H_ -#define NYLPC_CUDPSOCKET_H_ -#include "NyLPC_uip.h" -#include "NyLPC_os.h" -#include "NyLPC_cBaseSocket.h" - - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -typedef struct NyLPC_TcUdpSocket NyLPC_TcUdpSocket_t; -/** - * 受信情報を格納する構造体 - */ -struct NyLPC_TIPv4RxInfo -{ - NyLPC_TUInt16 size;//パケットサイズ - NyLPC_TUInt16 port;//受信ポート - NyLPC_TUInt16 peer_port;//PEERポート - struct NyLPC_TIPv4Addr ip;//受信IP - struct NyLPC_TIPv4Addr peer_ip;//PEERIP -}; - -/** - * Representation of a uIP UDP connection. - */ -struct uip_udp_conn{ - struct NyLPC_TIPv4Addr lipaddr; /**< The IP address of the remote peer. */ - /** マルチキャスとアドレス(ZEROで無効)*/ - struct NyLPC_TIPv4Addr mcastaddr; - NyLPC_TUInt16 lport; /**< The local port number in network byte order. */ - NyLPC_TUInt8 flags; /**フラグ*/ - NyLPC_TUInt8 padding; /***/ -}; - -/** - * 受信時に非同期にコールされるハンドラ - * UIPサービスタスクが実行する。 - * @return - * TRUEならパケットを受信キューへ追加する。FALSEならパケットを受信キューへ追加しない。 - */ -typedef NyLPC_TBool (*NyLPC_TcUdpSocket_onRxHandler)(NyLPC_TcUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info); -/** - * 非同期にコールされるハンドラ。 - * UIPサービスタスクが実行する。 - */ -typedef void (*NyLPC_TcUdpSocket_onPeriodic)(NyLPC_TcUdpSocket_t* i_inst); - -struct NyLPC_TcUdpSocket -{ - NyLPC_TcBaseSocket_t _super; - //この変数は、uipタスクの実行する関数のみが変更する。 - struct uip_udp_conn uip_udp_conn; - NyLPC_TcFifoBuffer_t rxbuf; - NyLPC_TcMutex_t* _smutex; - struct{ - /** 受信ハンドラ。サービス実装に使用する。*/ - NyLPC_TcUdpSocket_onRxHandler rx; - /** 定期実行ハンドラ。サービス実装に使用する。最低保障周期は1s*/ - NyLPC_TcUdpSocket_onPeriodic periodic; - }as_handler; -}; - - - - - -/** - * @param i_rbuf - * 受信バッファアアドレス。サイズは、(最大受信サイズ-4バイト)*キュー数で計算します。 - * @param i_rbuf_len - * 受信バッファのサイズ。 - */ -NyLPC_TBool NyLPC_cUdpSocket_initialize(NyLPC_TcUdpSocket_t* i_inst,NyLPC_TUInt16 i_port,void* i_rbuf,NyLPC_TUInt16 i_rbuf_len); -void NyLPC_cUdpSocket_finalize(NyLPC_TcUdpSocket_t* i_inst); - -/** - * マルチキャストアドレスに参加する。 - * @param i_addr - * 参加するマルチキャストグループを指定する。 - * 同じマルチキャスとグループに参加できるのは、システムの中で1つに限られます。 - * 0を指定した場合、マルチキャスとグループから離脱します。 - */ -void NyLPC_cUdpSocket_joinMulticast(NyLPC_TcUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr); - -/** - * ブロードキャストに参加する。 - */ -void NyLPC_cUdpSocket_setBroadcast(NyLPC_TcUdpSocket_t* i_inst); - - -/** - * この関数は、ソケットの受信バッファの読み取り位置と、読み出せるデータサイズを返却します。 - * 関数はポインターを返却するだけで、バッファの読み取り位置をシークしません。 - * シークするにはNyLPC_cTcpSocket_pseekを使います。 - */ -NyLPC_TInt32 NyLPC_cUdpSocket_precv(NyLPC_TcUdpSocket_t* i_inst,const void** o_buf_ptr,const struct NyLPC_TIPv4RxInfo** o_info,NyLPC_TUInt32 i_wait_msec); -/** - * 受信バッファを次のバッファまでシークします。 - */ -void NyLPC_cUdpSocket_pseek(NyLPC_TcUdpSocket_t* i_inst); - -/** - * 送信バッファを割り当てて返します。 - * 割り当てたメモリは、releaseSendBuf関数か、psend関数を成功させて開放する必要があります。 - * @param i_hint - * 取得したいメモリサイズをセットします。 - * 関数は要求サイズより小さいメモリを返すことがあります。 - */ -void* NyLPC_cUdpSocket_allocSendBuf(NyLPC_TcUdpSocket_t* i_inst,NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_buf_size,NyLPC_TUInt32 i_wait_in_msec); - -void NyLPC_cUdpSocket_releaseSendBuf(NyLPC_TcUdpSocket_t* i_inst,void* i_buf_ptr); - -/** - * 事前にAllocしたTxパケットを送信します。 - * このAPIはゼロコピー送信をサポートするためのものです。 - * @param i_buf_ptr - * allocSendBufで取得したメモリを指定します。 - * @return - * 関数が失敗した場合、i_buf_ptrは「開放されません。」 - */ -NyLPC_TBool NyLPC_cUdpSocket_psend(NyLPC_TcUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_port,void* i_buf_ptr,int i_len); - -/** - * 最大送信サイズは1200バイトです。 - */ -NyLPC_TInt32 NyLPC_cUdpSocket_send(NyLPC_TcUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_port,const void* i_buf_ptr,NyLPC_TInt32 i_len,NyLPC_TUInt32 i_wait_in_msec); - -/** - * 非同期パケットハンドラを設定する。 - */ -#define NyLPC_cUdpSocket_setOnRxHandler(i_inst,i_handler) (i_inst)->as_handler.rx=i_handler; - -/** - * 非同期タイマ呼び出しハンドラを設定する。 - */ -#define NyLPC_cUdpSocket_setOnPeriodicHandler(i_inst,i_handler) (i_inst)->as_handler.periodic=i_handler; - -/** - * ソケットのローカルIPのアドレスを返す。 - * 値はuipが動作中のみ有効。 - */ -#define NyLPC_cUdpSocket_getSockIP(i_inst) (&(i_inst)->uip_udp_conn.lipaddr) - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* NYLPC_CUDPSOCKET_H_ */
--- a/core/uip/NyLPC_cUdpSocket_protected.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -/* - * NyLPC_cUdpSocket.h - * - * Created on: 2013/05/20 - * Author: nyatla - */ - -#ifndef NYLPC_CUDPSOCKET_PROTECTED_H_ -#define NYLPC_CUDPSOCKET_PROTECTED_H_ -#include "NyLPC_cUdpSocket.h" -#include "NyLPC_cIPv4Payload.h" -#include "NyLPC_cIPv4Config.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -/** - * この関数は、rxパケットを処理して、ソケットの状態を更新します。 - * uipサービスタスクが実行する関数です。 - */ -NyLPC_TBool NyLPC_cUdpSocket_parseRx( - NyLPC_TcUdpSocket_t* i_inst, - const NyLPC_TcIPv4Payload_t* i_ipp); - -/** - * uipサービスタスクが実行する関数です。 - * サービスの開始を通知します。 - * この関数は他のAPIが非同期に実行されないことが保証される状況で使用する必要があります。 - */ -void NyLPC_cUdpSocket_startService(NyLPC_TcUdpSocket_t* i_inst,const NyLPC_TcIPv4Config_t* i_config); - -/** - * uipサービスタスクが実行する関数です。 - * サービスの停止を通知します。 - * この関数は他のAPIが非同期に実行されないことが保証される状況で使用する必要があります。 - */ -void NyLPC_cUdpSocket_stopService(NyLPC_TcUdpSocket_t* i_inst); - - -/** - * 定期的に実行する関数。最低でも1s単位で実行してください。 - * uipサービスタスクが実行する関数です。 - */ -#define NyLPC_cUdpSocket_periodic(i_inst) if((i_inst)->as_handler.periodic!=NULL){(i_inst)->as_handler.periodic(i_inst);} - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* NYLPC_CUDPSOCKET_H_ */
--- a/core/uip/NyLPC_cUipService.c Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,628 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - * - * Parts of this file were leveraged from uIP: - * - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "NyLPC_cUipService_protected.h" -#include "NyLPC_cIPv4IComp_protected.h" -#include "NyLPC_cTcpListener_protected.h" -#include "NyLPC_stdlib.h" -#include "NyLPC_uip.h" - - - - - - -/**************************************************** - * UipServiceに関する宣言:その他 - ***************************************************/ -/** - * イーサネットフレームの読み出し構造体 - */ -struct TEthPacket -{ - struct NyLPC_TEthernetIIHeader header; - union{ - struct NyLPC_TArpHeader arp; - struct NyLPC_TIPv4Header ipv4; - }data; -}PACK_STRUCT_END; - - - -/** - * サービスインスタンスのポインタ。サービスが稼働中はインスタンスのポインタが有効です。 - */ -NyLPC_TcUipService_t* _NyLPC_TcUipService_inst=NULL; - -/** - * 唯一のインスタンス - */ -static NyLPC_TcUipService_t _service_instance; - - - - -/** - * uipタスク - */ -static int uipTask(void *pvParameters); - -/** イーサネットドライバからのハンドラ*/ -static void ethernet_handler(void* i_param,NyLPC_TiEthernetDevice_EVENT i_type); - -//-------------------------------------------------------------- - - -static NyLPC_TBool sendIPv4Tx(struct TEthPacket* i_eth_buf); - -//static void sendArpReqest(const struct TEthPacket* i_eth_packet); -static void sendRawEthFrameNL(void* i_buf,NyLPC_TUInt16 i_len); -static void releaseTxBufNL(void* i_buf); - -/**メッセージなし*/ -#define TTaskMessage_MSG_NULL 0x0000 -/**uipコアタスクに、開始要求する*/ -#define TTaskMessage_MSG_RUN 0x0001 -/**uipコアタスクに、停止要求する*/ -#define TTaskMessage_MSG_STOP 0x0002 - - -NyLPC_TcThread_t th; - -NyLPC_TBool NyLPC_cUipService_initialize(void) -{ - NyLPC_TcUipService_t* inst=&_service_instance; - //サービスは停止している事。 - Service must be uninitialized. - NyLPC_Assert(!NyLPC_TcUipService_isInitService()); - //IP処理部分の初期化 - NyLPC_cIPv4_initialize(&(inst->_tcpv4)); - //EMAC割込セマフォ - NyLPC_cSemaphore_initialize(&inst->_emac_semapho); - - inst->_status=0x00; - NyLPC_cStopwatch_initialize(&(inst->_arp_sw)); - NyLPC_cStopwatch_initialize(&(inst->_periodic_sw)); - NyLPC_cIPv4_initialize(&(inst->_tcpv4)); - NyLPC_AbortIfNot(NyLPC_cMutex_initialize(&(inst->_mutex))); - - _NyLPC_TcUipService_inst=inst; - //タスク起動 - NyLPC_cThread_initialize(&th,NyLPC_cUipService_config_STACK_SIZE,NyLPC_TcThread_PRIORITY_SERVICE); - NyLPC_cThread_start(&th,uipTask,NULL); - return NyLPC_TBool_TRUE; -} - - - - - - - -/** - * UIP処理を開始します。 - * この関数はリエントラントではありません。複数のタスクから共有するときには、排他ロックを掛けてください。 - * @param i_ref_config - * このコンフィギュレーションは、stopを実行するまでの間、インスタンスから参照します。外部で保持してください。 - */ -void NyLPC_cUipService_start(const NyLPC_TcIPv4Config_t* i_ref_config) -{ - NyLPC_TcUipService_t* inst=&_service_instance; - NyLPC_Assert(NyLPC_TcUipService_isInitService()); - if(!NyLPC_cUipService_isRun()) - { - //はじめて起動するときに1度だけデバイス取得(タスクスイッチが動いてないと動かないからここで。) - if(inst->_ethif==NULL){ - inst->_ethif=getEthernetDevicePnP(); - } - //コンフィグレーションセット - inst->_ref_config=i_ref_config; - //開始要求セット - NyLPC_TUInt16_setBit(inst->_status,NyLPC_TcUipService_ORDER_START); - //Order実行待ち - while(NyLPC_TUInt16_isBitOn(inst->_status,NyLPC_TcUipService_ORDER_START)){ - NyLPC_cThread_sleep(10); - } - } - return; -} -/** - * UIP処理を停止します。 - * この関数はリエントラントではありません。複数のタスクから共有するときには、排他ロックを掛けてください。 - * いまのところ、ストップシーケンスの実装は良くありません。 - * 再設計が必要。 - */ -void NyLPC_cUipService_stop(void) -{ - NyLPC_TcUipService_t* inst=&_service_instance; - NyLPC_Assert(NyLPC_TcUipService_isInitService()); - if(NyLPC_cUipService_isRun()) - { - NyLPC_TUInt16_setBit(inst->_status,NyLPC_TcUipService_ORDER_STOP); - //Order実行待ち - while(NyLPC_TUInt16_isBitOn(inst->_status,NyLPC_TcUipService_ORDER_STOP)){ - NyLPC_cThread_sleep(10); - } - } - return; -} - - -const char* NyLPC_cUipService_refDeviceName(void) -{ - NyLPC_TcUipService_t* inst=&_service_instance; - return NyLPC_cUipService_isRun()?NyLPC_iEthernetDevice_getDevicName(inst->_ethif):NULL; -} -const NyLPC_TcIPv4Config_t* NyLPC_cUipService_refCurrentConfig(void) -{ - NyLPC_TcUipService_t* inst=&_service_instance; - return inst->_ref_config; -} -/********************************************************************** - * - * </HWコールバックに関わる宣言> - * - *********************************************************************/ - - -//PERIODIC rate -#define PERIODIC_TIMER (1*200) -#define ARP_TIMER (60*1000*10) - - - -/** - * 操作キューを確認して、タスクのステータスをアップデートします。 - * 高速化のため、Proc-Callerを使用していません。複雑なタスク操作をするときには、書き換えてください。 - * @return - * UIPタスクの実行状態 - */ -static NyLPC_TBool updateTaskStatus() -{ - NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst; - if(NyLPC_cUipService_isRun()){ - //開始状態 - if(NyLPC_TUInt16_isBitOn(inst->_status,NyLPC_TcUipService_ORDER_STOP)) - { - //停止操作 - NyLPC_iEthernetDevice_stop(inst->_ethif); - NyLPC_cIPv4_stop(&(inst->_tcpv4)); - NyLPC_cIPv4IComp_finalize(&(inst->_icomp)); - NyLPC_cIPv4Arp_finalize(&(inst->_arp)); - inst->_ref_config=NULL; - NyLPC_TUInt16_unsetBit(inst->_status,NyLPC_TcUipService_STATUSBIT_IS_RUNNING); - NyLPC_TUInt16_unsetBit(inst->_status,NyLPC_TcUipService_ORDER_STOP); - return NyLPC_TBool_FALSE; - } - return NyLPC_TBool_TRUE; - }else{ - //停止状態 - if(NyLPC_TUInt16_isBitOn(inst->_status,NyLPC_TcUipService_ORDER_START)) - { - //TCP,ICOMPの初期化 - NyLPC_cIPv4_start(&(inst->_tcpv4),inst->_ref_config); - NyLPC_cIPv4IComp_initialize(&(inst->_icomp),inst->_ref_config); - //uip_arp_init(msg->start.ref_config); - NyLPC_cIPv4Arp_initialize(&(inst->_arp),inst->_ref_config); - NyLPC_cStopwatch_startExpire(&(inst->_arp_sw),1);//1度ARPを起動するため。 - NyLPC_cStopwatch_startExpire(&(inst->_periodic_sw),PERIODIC_TIMER); - //EtherNETデバイス初期化 - while(!NyLPC_iEthernetDevice_start(inst->_ethif,&(inst->_ref_config->eth_mac),ethernet_handler,inst)); - NyLPC_TUInt16_setBit(inst->_status,NyLPC_TcUipService_STATUSBIT_IS_RUNNING); - NyLPC_TUInt16_unsetBit(inst->_status,NyLPC_TcUipService_ORDER_START); - return NyLPC_TBool_TRUE; - } - return NyLPC_TBool_FALSE; - } -} - -/** - * uipタスクのメインループ - */ -static int uipTask(void *pvParameters) -{ - NyLPC_TUInt16 rx_len,tx_len; - struct TEthPacket* ethbuf; - NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst; - void* r; - (void)pvParameters; - for( ;; ) - { - //タスク状態の更新 - if(!updateTaskStatus()) - { - //RUNステータス以外の時は、ここで終了する。 - NyLPC_cThread_sleep(50); - continue; - } - //イーサネットフレームの取得 - //Ethernet Device Lock(ARPを含む) - NyLPC_cMutex_lock(&(inst->_mutex)); - ethbuf= (struct TEthPacket*)NyLPC_iEthernetDevice_getRxEthFrame(inst->_ethif,&rx_len); - tx_len=0; - while(ethbuf != NULL){ - if(rx_len>0) - { - //ペイロードサイズを計算 - rx_len-=sizeof(struct NyLPC_TEthernetIIHeader); - switch(ethbuf->header.type) - { - case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_IP): - //ARPテーブルの更新 - //uip_arp_ipin(&(ethbuf->header),ethbuf->data.ipv4.srcipaddr); - NyLPC_cIPv4Arp_incomingIp(&inst->_arp,&(ethbuf->header),ethbuf->data.ipv4.srcipaddr); - //Ethernet Device UnLock(NyLPC_cIPv4_rxがallocをコールする可能性があるので一時的にロック解除) - NyLPC_cMutex_unlock(&(inst->_mutex)); - //IPパケットの処理 - r=NyLPC_cIPv4_rx(&(inst->_tcpv4),&(ethbuf->data.ipv4),rx_len); - if(r!=NULL){ - //IPパケットとして送信 - NyLPC_cUipService_sendIPv4Tx(r); - } - //ロックの復帰 - NyLPC_cMutex_lock(&(inst->_mutex)); - if(r!=NULL){ - releaseTxBufNL(r); - } - break; - case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_ARP): - //Ethernet Device UnLock(NyLPC_cIPv4_rxがallocをコールする可能性があるので一時的にロック解除) - NyLPC_cMutex_unlock(&(inst->_mutex)); - r=NyLPC_cIPv4Arp_rx(&inst->_arp,&(ethbuf->data.arp),rx_len,&tx_len); - NyLPC_cMutex_lock(&(inst->_mutex)); - if(r!=NULL){ - sendRawEthFrameNL(r,tx_len); - releaseTxBufNL(r); - } - break; - case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_IPV6): - //uip_process_ipv6(); - break; - default: - break; - } - } - //受信キューを進行。 - NyLPC_iEthernetDevice_nextRxEthFrame(inst->_ethif); - //受信処理 - ethbuf= (struct TEthPacket*)NyLPC_iEthernetDevice_getRxEthFrame(inst->_ethif,&rx_len); - } - //データが無い。 - if(NyLPC_cStopwatch_isExpired(&(inst->_arp_sw))){ - //uip_arp_timer(); - NyLPC_cIPv4Arp_periodic(&inst->_arp); - NyLPC_cStopwatch_startExpire(&(inst->_arp_sw),ARP_TIMER); - } - if(NyLPC_cStopwatch_isExpired(&(inst->_periodic_sw))){ - NyLPC_cMutex_unlock(&(inst->_mutex)); - NyLPC_cIPv4_periodec(&(inst->_tcpv4)); - NyLPC_cMutex_lock(&(inst->_mutex)); - NyLPC_cStopwatch_startExpire(&(inst->_periodic_sw),PERIODIC_TIMER); - } - //リソースロックの解除 - NyLPC_cMutex_unlock(&(inst->_mutex)); - //割込によるセマフォの解除か、タイムアウトで再開する。(タイムアウト値は周期関数の実行レート以下にすること。) - NyLPC_cSemaphore_take(&(_NyLPC_TcUipService_inst->_emac_semapho),PERIODIC_TIMER); - } - return 0; -} - - -/** - * イーサネットドライバからのハンドラ - */ -static void ethernet_handler(void* i_param,NyLPC_TiEthernetDevice_EVENT i_type) -{ - switch(i_type){ - case NyLPC_TiEthernetDevice_EVENT_ON_RX: - //受信系のセマフォブロックの解除 - NyLPC_cSemaphore_giveFromISR(&(((NyLPC_TcUipService_t*)i_param)->_emac_semapho)); - break; - default: - break; - } -} - -/** - * IPv4パケットのpeerIPを問い合わせるARPパケットを送信します。 - * allocを中でコールするから要UNLOCK状態 - */ -void NyLPC_cUipService_sendArpRequest(const struct NyLPC_TIPv4Addr* i_addr) -{ - NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst; - void* p; - NyLPC_TUInt16 tx_len; - struct TEthPacket* ethbuf; - //システムTxBufを得る - ethbuf=(struct TEthPacket*)NyLPC_cUipService_allocSysTxBuf(); - //ARPパケットを作る。 - NyLPC_TArpHeader_setArpRequest(&(ethbuf->data.arp),inst->_ref_config->ip_addr,&(inst->_ref_config->eth_mac),i_addr); - tx_len=NyLPC_TEthernetIIHeader_setArpTx(&(ethbuf->header),&(inst->_ref_config->eth_mac)); - //送信 - p=((struct NyLPC_TEthernetIIHeader*)ethbuf)-1; - - NyLPC_cMutex_lock(&(inst->_mutex)); - NyLPC_iEthernetDevice_sendTxEthFrame(inst->_ethif,p,tx_len); - NyLPC_iEthernetDevice_releaseTxBuf(inst->_ethif,p); - NyLPC_cMutex_unlock(&(inst->_mutex)); -} - - - - -/** - * allocTxBufで取得したペイロードメモリを"IPパケットとして"送信します。 - * @param i_eth_payload - * [NyLPC_TEthernetIIHeader][payload]メモリの、[payload]のアドレスを指定します。 - * 通常は、NyLPC_cUipService_allocTxBufの返却したメモリを指定します。 - */ - -void NyLPC_cUipService_sendIPv4Tx(void* i_eth_payload) -{ - NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst; - void* p=((struct NyLPC_TEthernetIIHeader*)i_eth_payload)-1; - NyLPC_cMutex_lock(&(inst->_mutex)); - //IPパケットの送信を試行 - if(sendIPv4Tx((struct TEthPacket*)p)){ - NyLPC_cMutex_unlock(&(inst->_mutex)); - return; - } - NyLPC_cMutex_unlock(&(inst->_mutex)); - //ARPリクエストを代わりに送信 - NyLPC_cUipService_sendArpRequest(&((struct NyLPC_TIPv4Header*)i_eth_payload)->destipaddr); - return; -} - - -/** - * ARPテーブルに指定したIPがあるかを返します。 - */ -NyLPC_TBool NyLPC_cUipService_hasArpInfo(const struct NyLPC_TIPv4Addr* i_addr) -{ - NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst; - return NyLPC_cIPv4Arp_IPv4toEthAddr(&inst->_arp,*i_addr)!=NULL; -} - -/** - * システム用の送信ペイロードを返します。 - * 関数は必ず成功します。 - */ -void* NyLPC_cUipService_allocSysTxBuf(void) -{ - NyLPC_TUInt16 s; - NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst; - struct TEthPacket* ethbuf; - //排他処理をして、メモリを取得する。SYSTEMメモリはEthernetドライバの解放待ちのみなのでまとめてLOCKしておk - NyLPC_cMutex_lock(&(inst->_mutex)); - for(;;){ - ethbuf=(struct TEthPacket*)NyLPC_iEthernetDevice_allocTxBuf(inst->_ethif,NyLPC_TcEthernetMM_HINT_CTRL_PACKET,&s); - if(ethbuf==NULL){ - NyLPC_cThread_yield(); - continue; - } - break; - } - NyLPC_cMutex_unlock(&(inst->_mutex)); - //イーサネットバッファのアドレスを計算 - return &(ethbuf->data); -} - - - -void* NyLPC_cUipService_allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size) -{ - NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst; - struct TEthPacket* ethbuf; - //排他処理をして、メモリを取得する。 - NyLPC_cMutex_lock(&(inst->_mutex)); - ethbuf=(struct TEthPacket*)NyLPC_iEthernetDevice_allocTxBuf(inst->_ethif,i_hint+sizeof(struct NyLPC_TEthernetIIHeader),o_size); - NyLPC_cMutex_unlock(&(inst->_mutex)); - if(ethbuf==NULL){ - return NULL; - } - //イーサネットバッファのサイズを計算 - *o_size-=sizeof(struct NyLPC_TEthernetIIHeader); - //イーサネットバッファのアドレスを計算 - return &(ethbuf->data); -} - - -void* NyLPC_cUipService_releaseTxBuf(void* i_buf) -{ - //排他処理をして、メモリを開放する。 - NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst; - NyLPC_cMutex_lock(&(inst->_mutex)); - //ペイロードの位置から、メモリブロックを再生。 - NyLPC_iEthernetDevice_releaseTxBuf(inst->_ethif,((struct NyLPC_TEthernetIIHeader*)i_buf)-1); - NyLPC_cMutex_unlock(&(inst->_mutex)); - return NULL; -} - - - - - - - - -/********** - * イーサネットHWのコントロール関数 - */ -/** - * "IPv4パケットを格納した"イーサフレームを送信します。 - * コール前に、必ずロックしてから呼び出してください。 - *//* -static void copyAndSendIPv4Tx(const struct TEthPacket* i_buf) -{ - NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst; - NyLPC_TUInt16 s; - //送信する。 - s=NyLPC_htons(i_buf->data.ipv4.len16)+sizeof(struct NyLPC_TEthernetIIHeader); - memcpy(inst->stx.buf,i_buf,s); - if(!sendIPv4Tx(&(inst->stx.h))){ - //失敗した場合はARPリクエストに変換して再送 -//@todo unchecked PASS! - sendArpReqest(&i_buf->data.ipv4.destipaddr); - } - return; -}*/ -/** - * "IPv4パケットを格納した"イーサフレームを送信します。 - * コール前に、必ずロックしてから呼び出してください。 - */ -/* -static void copyAndSendIPv4Tx(const struct TEthPacket* i_buf) -{ - NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst; - NyLPC_TUInt16 s; - //ACK送信用の自己バッファが空くまで待つ - while(inst->stx.h.is_lock){ - NyLPC_iEthernetDevice_processTx(inst->_ethif); - } - //送信する。 - s=NyLPC_htons(i_buf->data.ipv4.len16)+sizeof(struct NyLPC_TEthernetIIHeader); - memcpy(inst->stx.buf,i_buf,s); - if(!sendIPv4Tx(&(inst->stx.h))){ - //失敗した場合はARPリクエストに変換して再送 -//@todo unchecked PASS! - sendArpReqest(&i_buf->data.ipv4.destipaddr); - } - return; -} -*/ - - -/** - * イーサネットフレームを送信します。 - * この関数はiptaskで実行される関数からのみ使用てください。 - * @i_buf - * イーサネットフレームを格納したメモリです。 - * @i_len - * イーサネットペイロードのサイズです。 - */ -static void sendRawEthFrameNL(void* i_buf,NyLPC_TUInt16 i_len) -{ - NyLPC_iEthernetDevice_sendTxEthFrame( - _NyLPC_TcUipService_inst->_ethif, - ((struct NyLPC_TEthernetIIHeader*)i_buf)-1, - i_len); - return; -} -/** - * ロック状態で使用できるreleaseTxBuf。 - * この関数はiptaskで実行される関数からのみ使用してください。 - */ -static void releaseTxBufNL(void* i_buf) -{ - //ペイロードの位置から、メモリブロックを再生。 - NyLPC_iEthernetDevice_releaseTxBuf( - _NyLPC_TcUipService_inst->_ethif, - ((struct NyLPC_TEthernetIIHeader*)i_buf)-1); - return; -} -/** - * マルチキャスとアドレスへ変換する。 - */ -static void ip2MulticastEmacAddr(const struct NyLPC_TIPv4Addr* i_addr,struct NyLPC_TEthAddr* o_emac) -{ - NyLPC_TUInt32 n=NyLPC_htonl(i_addr->v); - o_emac->addr[0]=0x01; - o_emac->addr[1]=0x00; - o_emac->addr[2]=0x5E; - o_emac->addr[3]=((n>>16) & 0x7f); - o_emac->addr[4]=((n>> 8) & 0xff); - o_emac->addr[5]=(n & 0xff); - return; -}; - -/** - * ペイロードをIPパケットとしてネットワークへ送出します。 - * コール前に、必ずロックしてから呼び出してください。 - * @param i_eth_payload - * allocTxBufで確保したメモリを指定してください。 - * ペイロードには、TCP/IPパケットを格納します。 - */ -static NyLPC_TBool sendIPv4Tx(struct TEthPacket* i_eth_buf) -{ - NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst; - struct NyLPC_TEthAddr emac; - NyLPC_TUInt16 tx_len; - const struct NyLPC_TEthAddr* eth_dest; - //ペイロードのアドレスから、イーサネットフレームバッファのアドレスを復元 - - if(NyLPC_TIPv4Addr_isEqual(&(i_eth_buf->data.ipv4.destipaddr),&NyLPC_TIPv4Addr_BROADCAST)) { - //ブロードキャストならそのまま - eth_dest=&NyLPC_TEthAddr_BROADCAST; - }else if(NyLPC_TIPv4Addr_isEqualWithMask(&(i_eth_buf->data.ipv4.destipaddr),&NyLPC_TIPv4Addr_MULTICAST,&NyLPC_TIPv4Addr_MULTICAST_MASK)){ - //マルチキャスト - ip2MulticastEmacAddr(&(i_eth_buf->data.ipv4.destipaddr),&emac); - eth_dest=&emac; - }else{ - //LocalIP以外ならdefaultRootへ変換 - eth_dest=NyLPC_cIPv4Arp_IPv4toEthAddr( - &inst->_arp, - NyLPC_cIPv4Config_isLocalIP(inst->_ref_config, &(i_eth_buf->data.ipv4.destipaddr))?(i_eth_buf->data.ipv4.destipaddr):(inst->_ref_config->dr_addr)); - //IP->MAC変換をテスト。 - if(eth_dest==NULL){ - return NyLPC_TBool_FALSE; - } - } - //変換可能なら、イーサネットヘッダを更新して、送信処理へ。 - tx_len=NyLPC_TEthernetIIHeader_setIPv4Tx(&(i_eth_buf->header),&(inst->_ref_config->eth_mac),eth_dest); - NyLPC_iEthernetDevice_sendTxEthFrame(inst->_ethif,i_eth_buf,tx_len); - return NyLPC_TBool_TRUE; -} - - - -
--- a/core/uip/NyLPC_cUipService.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,128 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - * - * Parts of this file were leveraged from uIP: - * - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef NyLPC_TcUipService_H_ -#define NyLPC_TcUipService_H_ - - -/********************************************************************** - * Heder files - **********************************************************************/ - -#include "NyLPC_cTcpSocket.h" -#include "NyLPC_cTcpListener.h" -#include "NyLPC_cIPv4IComp.h" -#include "NyLPC_cIPv4Arp.h" -#include "NyLPC_cIPv4.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/********************************************************************** - * - * NyLPC_TcUipService class - * - **********************************************************************/ -/** - * uipタスクを管理する、サービスクラスです。 - */ -typedef struct NyLPC_TcUipService NyLPC_TcUipService_t; - - -/** サービスタスクスタックサイズ - * mdns 256+96(MIN) - * upnp 256+160(MIN) - * mbedのExportしたのをLPCXpressoでコンパイルするときは+192しないと落ちる。 - */ -#ifndef NyLPC_cUipService_config_STACK_SIZE -#define NyLPC_cUipService_config_STACK_SIZE (256+192+192) -#endif - - - - -/** - * \param i_mac_addr - * システムで唯一のUIPサービスを初期化します。1度だけ実行できます。 - */ -NyLPC_TBool NyLPC_cUipService_initialize(void); - -/** - * 処理を開始します。 - * この関数はリエントラントではありません。複数のタスクから共有するときには、排他ロックを掛けてください。 - * @param i_ref_config - * このコンフィギュレーションは、stopを実行するまでの間、インスタンスから参照します。外部で保持してください。 - */ -void NyLPC_cUipService_start(const NyLPC_TcIPv4Config_t* i_ref_config); - -/** - * UIP処理を停止します。 - * この関数はリエントラントではありません。複数のタスクから共有するときには、排他ロックを掛けてください。 - * 関数を使用する前に、全ての非同期ソケット操作を停止してください。 - */ -void NyLPC_cUipService_stop(void); - -/** - * イーサネットデバイスの名前を返します。 - * この関数は、サービスが開始されているときのみ、動作します。 - */ -const char* NyLPC_cUipService_refDeviceName(void); -const NyLPC_TcIPv4Config_t* NyLPC_cUipService_refCurrentConfig(void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif
--- a/core/uip/NyLPC_cUipService_protected.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,159 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - *********************************************************************************/ - -#ifndef NyLPC_uipService_protected_H -#define NyLPC_uipService_protected_H -#include "NyLPC_cUipService.h" -#include "../driver/ethernet/EthDev.h" - -/********************************************************************** - * - * NyLPC_TcUipService_t - * - **********************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -//#define NyLPC_TcUipService_SIZE_OF_REPLY_BUF 128 - - - -struct NyLPC_TcUipService -{ - const NyLPC_TcIPv4Config_t* _ref_config; - volatile NyLPC_TUInt16 _status; /**< ステータスビット*/ - NyLPC_TcSemaphore_t _emac_semapho; /** EMACの制御用セマフォです。*/ - NyLPC_TcStopwatch_t _arp_sw; /**<ARP用のストップウォッチ*/ - NyLPC_TcStopwatch_t _periodic_sw; /**<周期実行用のストップウォッチ*/ - /** ARP処理インスタンス*/ - NyLPC_TcIPv4Arp_t _arp; - /** TCPv4処理インスタンス*/ - NyLPC_TcIPv4_t _tcpv4; - /** ICOMP処理インスタンス*/ - NyLPC_TcIPv4IComp_t _icomp; - /** (Ethernetメモリ排他制御用)*/ - NyLPC_TcMutex_t _mutex; - const struct TiEthernetDevice* _ethif; -}; - - -/** 唯一のサービスインスタンス - Single service instance*/ -extern NyLPC_TcUipService_t* _NyLPC_TcUipService_inst; - -/** - * サービスが初期化済みならtrueです。 - true if service was initialized. - */ -#define NyLPC_TcUipService_isInitService() (_NyLPC_TcUipService_inst!=NULL) -/** - * サービスが稼働中か返します。 - */ -#define NyLPC_cUipService_isRun() NyLPC_TUInt16_isBitOn(_NyLPC_TcUipService_inst->_status,NyLPC_TcUipService_STATUSBIT_IS_RUNNING) - - -/********************************************************************** - * コントロールビットの定義 - **********************************************************************/ -//サービスが実行中の場合1 -#define NyLPC_TcUipService_STATUSBIT_IS_RUNNING 0 -#define NyLPC_TcUipService_ORDER_START 1 -#define NyLPC_TcUipService_ORDER_STOP 2 - - - -#define INST_TYPE_NyLPC_Unknown 0 -#define INST_TYPE_NyLPC_TcTcpListener 1 -#define INST_TYPE_NyLPC_TcTcpSocket 2 - - -/********************************************************************** - * cTcpSocketからコールする関数 - **********************************************************************/ - -/** - * NyLPC_cUipService_allocTxBufが返却するメモリサイズ。 - * - */ -#define NyLPC_cUipService_SYS_TX_BUF_SIZE (64-sizeof(struct NyLPC_TEthernetIIHeader)) - - -/** - * IPv4パケットをネットワークに送信します。 - * この関数は、リエントラントを許容します。 - * @param i_eth_payload - * NyLPC_cUipService_getTxFrame、または、NyLPC_cUipService_recvIPv4Rxで得たバッファに、 - * IPv4パケットを書きこんだものを指定してください。 - */ -void NyLPC_cUipService_sendIPv4Tx(void* i_eth_payload); - -/** - * 送信ペイロードメモリを返します。 - * この関数は、リエントラントを許容します。 - * @param i_hint - * 取得したいメモリサイズを指定します。(このサイズは、イーサネットヘッダのサイズを含みません。) - * このサイズよりも小さなサイズが割り当てられることがあります。 - * @param o_size - * 取得メモリのイーサネットヘッダを除いたペイロード部分の長さ - * @return - * 成功:IPペイロードのためのメモリブロックを返します。/失敗:NULL - * メモリは、[TEthPacket][payload]の構造で返されます。 - */ -void* NyLPC_cUipService_allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size); - -/** - * システム用の小さな送信ペイロードメモリを返します。 - * この関数は、リエントラントを許容します。 - * 返却するメモリブロックのサイズが小さいこと、メモリが確実に返される点がNyLPC_cUipService_allocTxBufと異なります。 - * この関数が返すメモリのサイズは、NyLPC_cUipService_SYS_TX_BUF_SIZEの値です。 - * 関数を使用するコードでは開始時に1度だけNyLPC_cUipService_SYS_TX_BUF_SIZEの値を確認して下さい。 - */ -void* NyLPC_cUipService_allocSysTxBuf(void); - -/** - * allocTxbufで確保したメモリを開放します。 - */ -void* NyLPC_cUipService_releaseTxBuf(void* i_buf); - -/** - * 指定したIPアドレスを要求するARPリクエストを発行します。 - */ -void NyLPC_cUipService_sendArpRequest(const struct NyLPC_TIPv4Addr* i_addr); - -/** - * ARPテーブルに指定したIPがあるかを返します。 - */ -NyLPC_TBool NyLPC_cUipService_hasArpInfo(const struct NyLPC_TIPv4Addr* i_addr); - - - - - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif
--- a/core/uip/NyLPC_uip.c Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,431 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - * - * Parts of this file were leveraged from uIP: - * - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "NyLPC_uip.h" - - - -const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_ZERO={0x00000000}; -const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_ALL ={0xffffffff}; -const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_BROADCAST = { 0xffffffff }; -const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_MULTICAST = NyLPC_TIPv4Addr_pack(224,0,0,0); -const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_MULTICAST_MASK = NyLPC_TIPv4Addr_pack(224,0,0,0); -const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_APIPA_MASK = NyLPC_TIPv4Addr_pack(255,255,0,0); - -NyLPC_TInt16 NyLPC_TIPv4Addr_toString(const struct NyLPC_TIPv4Addr* i_ip,NyLPC_TChar* i_buf) -{ - NyLPC_TUInt32 ip; - NyLPC_TChar* p=i_buf; - NyLPC_TUInt8 v; - NyLPC_TInt8 l; - //IPをホストオーダーにする。 - ip=NyLPC_NTOHL(i_ip->v); - for(l=3;l>=0;l--){ - v=(ip>>(8*l))&0xff; - if(v>=100){ - *p=(v/100)+'0'; - p++; - } - if(v>=10){ - *p=((v%100)/10)+'0'; - p++; - } - *p=(v%10)+'0'; - *(p+1)='.'; - p+=2; - } - *(p-1)='\0'; - return p-i_buf-1; -} - - -NyLPC_TUInt16 NyLPC_uip_chksum(NyLPC_TUInt16 sum, const NyLPC_TUInt8 *data, NyLPC_TUInt16 len) -{ - NyLPC_TUInt16 t; - const NyLPC_TUInt8 *dataptr; - const NyLPC_TUInt8 *last_byte; - - dataptr = data; - last_byte = data + len - 1; - - while (dataptr < last_byte) { /* At least two more bytes */ - t = (dataptr[0] << 8) + dataptr[1]; - sum += t; - if (sum < t) { - sum++; /* carry */ - } - dataptr += 2; - } - - if (dataptr == last_byte) { - t = (dataptr[0] << 8) + 0; - sum += t; - if (sum < t) { - sum++; /* carry */ - } - } - - /* Return sum in host byte order. */ - return sum; -} - -/*-------------------------------------------------------------------------------- - * - * struct NyLPC_TEthernetIIHeader - * - *------------------------------------------------------------------------------*/ - -/** - * Ethernetヘッダの内容を、ARPパケットの内容に一致するように書き換えます。 - * i_structの後方にあるものと仮定します。 - * 戻り値は、フレームの長さです。 - */ -NyLPC_TUInt16 NyLPC_TEthernetIIHeader_setArpTx( - struct NyLPC_TEthernetIIHeader* i_struct, - const struct NyLPC_TEthAddr* i_my_eth_addr) -{ - struct NyLPC_TArpHeader* arph=(struct NyLPC_TArpHeader*)(((NyLPC_TUInt8*)i_struct)+sizeof(struct NyLPC_TEthernetIIHeader)); - - i_struct->type = NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_ARP); - switch(arph->opcode){ - case NyLPC_HTONS(ARP_REPLY): - memcpy(i_struct->src.addr, i_my_eth_addr->addr, 6); - memcpy(i_struct->dest.addr, arph->dhwaddr.addr, 6); - break; - case NyLPC_HTONS(ARP_REQUEST): - memset(i_struct->dest.addr, 0xff, 6); - memcpy(i_struct->src.addr, i_my_eth_addr->addr, 6); - break; - } - return sizeof(struct NyLPC_TEthernetIIHeader)+sizeof(struct NyLPC_TArpHeader); -} - -/** - * イーサネットヘッダをIPv4向けにセットアップする。 - * 関数は、ペイロードをIPv4ヘッダとして、フレームサイズを計算する。 - */ -NyLPC_TUInt16 NyLPC_TEthernetIIHeader_setIPv4Tx( - struct NyLPC_TEthernetIIHeader* i_eth, - const struct NyLPC_TEthAddr* i_src_eth_addr, - const struct NyLPC_TEthAddr* i_dest_eth_addr) -{ - struct NyLPC_TIPv4Header* iph=(struct NyLPC_TIPv4Header*)(((NyLPC_TUInt8*)i_eth)+sizeof(struct NyLPC_TEthernetIIHeader)); - - i_eth->type = NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_IP); - /* Build an ethernet header. */ - memcpy(i_eth->dest.addr,i_dest_eth_addr, 6); - memcpy(i_eth->src.addr, i_src_eth_addr->addr, 6); - - - //IPフラグメントに応じたサイズ計算 - switch(iph->proto){ - case UIP_PROTO_TCP: - return sizeof(struct NyLPC_TEthernetIIHeader)+NyLPC_htons(iph->len16); - case UIP_PROTO_UDP: - return sizeof(struct NyLPC_TEthernetIIHeader)+NyLPC_htons(iph->len16); - case UIP_PROTO_ICMP: - return sizeof(struct NyLPC_TEthernetIIHeader)+NyLPC_htons(iph->len16); - } - return 0; -} -/*-------------------------------------------------------------------------------- - * - * struct NyLPC_TIPv4Header - * - *------------------------------------------------------------------------------*/ - -/** - * based on uip_ipchksum - */ -NyLPC_TUInt16 NyLPC_TIPv4Header_makeIpChecksum(const struct NyLPC_TIPv4Header* ip_header) -{ - NyLPC_TUInt16 sum; - sum = NyLPC_uip_chksum(0, (const NyLPC_TUInt8 *)ip_header,NyLPC_TIPv4Header_getHeaderLength(ip_header)); - return (sum == 0) ? 0xffff : NyLPC_htons(sum); -} - - - -NyLPC_TBool NyLPC_TIPv4Header_isCorrectIpCheckSum(const struct NyLPC_TIPv4Header* ip_header) -{ - return (NyLPC_TIPv4Header_makeIpChecksum(ip_header)==0xffff); -} - -NyLPC_TBool NyLPC_cIPv4Packet_isCorrectTcpCheckSum(const struct NyLPC_TIPv4Header* ip_header) -{ - return (NyLPC_TIPv4Header_makeTcpChecksum(ip_header) == 0xffff); -} - - - - -/** - * TCPチェックサムを計算します。 - * ペイロードはIPヘッダの後方に連続して存在する物と仮定します。 - * i_lenは、ペイロード長さ - */ -NyLPC_TUInt16 NyLPC_TIPv4Header_makeTcpChecksum( - const struct NyLPC_TIPv4Header* i_iph) -{ - NyLPC_TUInt16 sum; - NyLPC_TUInt16 iph_len=NyLPC_TIPv4Header_getHeaderLength(i_iph); - NyLPC_TUInt16 len = NyLPC_ntohs((i_iph)->len16)- iph_len; - NyLPC_ArgAssert(i_iph!=NULL); - /*TCP疑似ヘッダ部分*/ - /* IP protocol and length fields. This addition cannot carry. */ - sum = len + i_iph->proto; - /* Sum IP source and destination addresses. */ - sum = NyLPC_uip_chksum(sum, (NyLPC_TUInt8 *) &(i_iph->srcipaddr), 2 * sizeof(struct NyLPC_TIPv4Addr)); - /* Sum TCP header and data. */ - sum = NyLPC_uip_chksum(sum, (((NyLPC_TUInt8 *)(i_iph))+iph_len),len); - // sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], i_len_of_data); - return (sum == 0) ? 0xffff : NyLPC_htons(sum); -} - -static NyLPC_TUInt16 pid=0x3939; -/** - * IPヘッダを送信パケット用に設定する。 - * ipid16にはコールされるたびに新しい値を設定する。 - * ipcecksumには0を設定する。 - * この関数は、パケットサイズ,ローカルIP/リモートIPの設定はしない。 - */ -void NyLPC_TIPv4Header_writeTxIpHeader( - struct NyLPC_TIPv4Header* i_struct, - NyLPC_TUInt8 i_proto) -{ - //IPパケットのセット - i_struct->proto=i_proto; - i_struct->ttl = UIP_DEFAULT_IP_TTL; - i_struct->tos = 0; - i_struct->ipid16=(pid++); - i_struct->ipoffset=0;//NyLPC_HTONS(0|0x4000); - i_struct->ipchksum = 0; -} -/*-------------------------------------------------------------------------------- - * - * struct NyLPC_TIPv6Header - * - *------------------------------------------------------------------------------*/ -#define IPV6_HEADER_SIZE 40 -/** - * IPヘッダーを作って埋める関数 - */ -void NyLPC_TIPv6Header_setSendHeader( - struct NyLPC_TIPv6Header* i_iph, - uip_ip6addr_t i_src, - uip_ip6addr_t i_dest, - NyLPC_TUInt8 i_proto, - NyLPC_TUInt8 i_ttl, - NyLPC_TUInt16 i_len) -{ - i_iph->srcipaddr=i_src; - i_iph->destipaddr=i_dest; - i_iph->proto=i_proto; - i_iph->ttl = i_ttl; - i_iph->vtc = 0x60; - i_iph->tcflow = 0x00; - i_iph->flow = 0x00; - i_iph->len16= NyLPC_htons(i_len - IPV6_HEADER_SIZE); - return; -} - - -/** - * チェックサムは、TCP疑似ヘッダから計算。 - * i_tcpiphの送信/受信アドレス、ProtocolID,DATAフィールドは有効であること。 - */ -NyLPC_TUInt16 NyLPC_TIPv6Header_makeTcpChecksum( - struct NyLPC_TIPv6Header* i_iph, - NyLPC_TUInt16 i_len) -{ - NyLPC_TUInt16 sum; - NyLPC_TUInt16 len; - len = i_len; - /*TCP疑似ヘッダ部分*/ - /* IP protocol and length fields. This addition cannot carry. */ - sum = len + i_iph->proto; - /* Sum IP source and destination addresses. */ - sum = NyLPC_uip_chksum(sum, (NyLPC_TUInt8 *) &(i_iph->srcipaddr), 2 * sizeof(uip_ip6addr_t)); - /* Sum TCP header and data. */ - sum = NyLPC_uip_chksum(sum, (((NyLPC_TUInt8 *)(i_iph))+IPV6_HEADER_SIZE),len); - // sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], i_len_of_data); - return (sum == 0) ? 0xffff : NyLPC_htons(sum); -} - - - -/*-------------------------------------------------------------------------------- - * - * struct NyLPC_TTcpHeader - * - *------------------------------------------------------------------------------*/ - - -/** - * MMSオプションの値を返す。 - */ -NyLPC_TBool NyLPC_TTcpHeader_getTcpMmsOpt( - const struct NyLPC_TTcpHeader* i_struct,NyLPC_TUInt16* o_val) -{ - NyLPC_TUInt8* opt; - opt=NyLPC_TTcpHeader_getTcpOptFragmentPtr(i_struct,TCP_OPT_MSS); - if(opt!=NULL){ - if (*(opt+1) == TCP_OPT_MSS_LEN) - { - // An MSS option with the right option length. - *o_val = ((NyLPC_TUInt16) (*(opt+2)) << 8) | (NyLPC_TUInt16) (*(opt + 3)); - //And we are done processing options. - return NyLPC_TBool_TRUE; - } - } - return NyLPC_TBool_FALSE; -} - -#define DEFAULT_TCP_HEADER_LEN 20 -/** - * TCPフラグメントのポインタを返す。 - */ -NyLPC_TUInt8* NyLPC_TTcpHeader_getTcpOptFragmentPtr( - const struct NyLPC_TTcpHeader* i_struct, - NyLPC_TUInt8 i_opt_id) -{ - NyLPC_TUInt8 opt; - int c; - NyLPC_TUInt8* opt_buf=((NyLPC_TUInt8*)(i_struct+1)); - - /* Parse the TCP MSS option, if present. */ - if ((i_struct->tcpoffset & 0xf0) > 0x50){ - for (c = 0; c < ((i_struct->tcpoffset >> 4) - 5) << 2;) - { - opt=opt_buf[c]; - if(opt==i_opt_id){ - return opt_buf+c;//found! - } - switch(opt) - { - case TCP_OPT_NOOP: - continue;//NOP option. - case TCP_OPT_END: - return NULL;//End of options. - default: - // All other options have a length field, so that we easily can skip past them. - if (opt_buf[1 + c] == 0) { - // If the length field is zero, the options are malformed and we don't process them further. - NyLPC_OnErrorGoto(ERROR_INVALID_OPTION); - } - c += opt_buf[1 + c]; - } - } - } -ERROR_INVALID_OPTION: - return NULL; -} -/* - * Optionパラメタを書きだす。 - */ -void NyLPC_TTcpHeader_setMmsOpt(NyLPC_TUInt8* i_opt_addr,NyLPC_TUInt16 i_mms) -{ - i_opt_addr[0] = TCP_OPT_MSS; - i_opt_addr[1] = TCP_OPT_MSS_LEN; - i_opt_addr[2] = (i_mms) / 256; - i_opt_addr[3] = (i_mms) & 255; - return; -} - - -NyLPC_TUInt16 NyLPC_TTcpHeader_getHeaderLength(const struct NyLPC_TTcpHeader* ip_header) -{ - return (ip_header->tcpoffset>>4)*4; -} -/*-------------------------------------------------------------------------------- - * - * struct NyLPC_TUdpHeader - * - *------------------------------------------------------------------------------*/ - - - -/*-------------------------------------------------------------------------------- - * - * struct NyLPC_TArpHeader - * - *------------------------------------------------------------------------------*/ -/** - * i_req_addrを問い合わせるARP_REQUESTを生成します。 - */ -void NyLPC_TArpHeader_setArpRequest( - struct NyLPC_TArpHeader* i_struct, - const struct NyLPC_TIPv4Addr i_saddr, - const struct NyLPC_TEthAddr* i_srceth, - const struct NyLPC_TIPv4Addr* i_req_addr) -{ - memset(i_struct->dhwaddr.addr, 0x00, 6); - memcpy(i_struct->shwaddr.addr, i_srceth, 6); - i_struct->dipaddr=*i_req_addr; - i_struct->sipaddr=i_saddr; - i_struct->opcode = NyLPC_HTONS(ARP_REQUEST); /* ARP request. */ - i_struct->hwtype = NyLPC_HTONS(ARP_HWTYPE_ETH); - i_struct->protocol = NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_IP); - i_struct->hwlen = 6; - i_struct->protolen = 4; - return; -} - -/*-------------------------------------------------------------------------------- - * - * class IPv4Route - * - *------------------------------------------------------------------------------*/ - -
--- a/core/uip/NyLPC_uip.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,474 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - * - * Parts of this file were leveraged from uIP: - * - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef NyLPC_uip_h -#define NyLPC_uip_h -#include "../include/NyLPC_config.h" -#include "../include/NyLPC_stdlib.h" -#include "NyLPC_uip_ethernet.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#define UIP_PROTO_ICMP 1 -#define UIP_PROTO_TCP 6 -#define UIP_PROTO_UDP 17 -#define UIP_PROTO_ICMP6 58 - -#define ARP_REQUEST 1 -#define ARP_REPLY 2 -#define ARP_HWTYPE_ETH 1 - - -#ifndef PACK_STRUCT_END - #define PACK_STRUCT_END __attribute((packed)) -#endif - -/********************************************************************** - * - * - * - **********************************************************************/ - -/** - * IPアドレスを格納します。 - * IPアドレスは、ネットワークオーダーで設定します。 - */ -struct NyLPC_TIPv4Addr -{ - NyLPC_TUInt32 v; -}PACK_STRUCT_END; -extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_ZERO; -extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_ALL; -extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_BROADCAST; -extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_MULTICAST; -extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_MULTICAST_MASK; -extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_APIPA_MASK; - -/** - * addr1とaddr2が全く同じであるかをテストします。 - * \hideinitializer - */ -#define NyLPC_TIPv4Addr_isEqual(v1,v2) ((v1)->v==(v2)->v) -/** - * addr1とaddr2をmaskでマスクした結果を比較します。 - * \hideinitializer - */ -#define NyLPC_TIPv4Addr_isEqualWithMask(addr1, addr2, mask) ((((addr1)->v) & ((mask)->v))==(((addr2)->v) & ((mask)->v))) - -/** - * 変数にIP v4アドレスをセットします。 - * 次のように使います。 - \code - NyLPC_TIPv4Addr ip; - NyLPC_TIpv4Addr_set(&ip,1,2,3,4); - \endcode - */ -#define NyLPC_TIPv4Addr_set(s,a0,a1,a2,a3) (s)->v=NyLPC_htonl((0xff000000&(((NyLPC_TUInt32)(a0))<<24))|(0x00ff0000&(((NyLPC_TUInt32)(a1))<<16))|(0x0000ff00&(((NyLPC_TUInt32)(a2))<<8))|(0x000000ff&((NyLPC_TUInt32)(a3)))) -#define NyLPC_TIPv4Addr_pack(a0,a1,a2,a3) {NyLPC_HTONL((0xff000000&(((NyLPC_TUInt32)(a0))<<24))|(0x00ff0000&(((NyLPC_TUInt32)(a1))<<16))|(0x0000ff00&(((NyLPC_TUInt32)(a2))<<8))|(0x000000ff&((NyLPC_TUInt32)(a3))))} - -/** - * IPアドレスを文字列に変換して返します。 - */ -NyLPC_TInt16 NyLPC_TIPv4Addr_toString(const struct NyLPC_TIPv4Addr* i_ip,NyLPC_TChar* i_buf); - - - - - -struct uip_ip6addr -{ - NyLPC_TUInt16 v[8]; -}PACK_STRUCT_END; - -typedef struct uip_ip6addr uip_ip6addr_t; - -NyLPC_TUInt16 NyLPC_uip_chksum(NyLPC_TUInt16 sum, const NyLPC_TUInt8 *data, NyLPC_TUInt16 len); - - - - -/** - * TTL - */ -#define UIP_DEFAULT_IP_TTL 64 - - - -/** - * The maximum number of times a segment should be retransmitted - * before the connection should be aborted. - * - * This should not be changed. - */ -#define UIP_MAXRTX 8 - - - - - -# if UIP_BYTE_ORDER == NyLPC_ENDIAN_BIG -# define NyLPC_HTONS(n) (n) -# define NyLPC_htons(n) (n) -# define NyLPC_ntohs(n) (n) -# define NyLPC_htonl(n) (n) -# define NyLPC_ntohl(n) (n) -# define NyLPC_HTONS(n) (n) -# define NyLPC_NTOHS(n) (n) -# else -# define NyLPC_htonl(n) NyLPC_TUInt32_bswap(n) -# define NyLPC_ntohl(n) NyLPC_TUInt32_bswap(n) -# define NyLPC_htons(n) NyLPC_TUInt16_bswap(n) -# define NyLPC_ntohs(n) NyLPC_TUInt16_bswap(n) -# define NyLPC_HTONS(n) NyLPC_TUInt16_BSWAP(n) -# define NyLPC_NTOHS(n) NyLPC_TUInt16_BSWAP(n) -# define NyLPC_NTOHL(n) NyLPC_TUInt32_BSWAP(n) -# define NyLPC_HTONL(n) NyLPC_TUInt32_BSWAP(n) -#endif /* NyLPC_HTONS */ - - - - -/********************************************************************** - * - * struct NyLPC_TEthernetIIHeader - * - **********************************************************************/ - -#define NyLPC_TEthernetIIHeader_TYPE_IP 0x0800 -#define NyLPC_TEthernetIIHeader_TYPE_ARP 0x0806 -#define NyLPC_TEthernetIIHeader_TYPE_IPV6 0x86DD -//#define UIP_ETHTYPE_IP 0x0800 -//#define UIP_ETHTYPE_ARP 0x0806 -//#define UIP_ETHTYPE_IP6 0x86dd - -struct NyLPC_TEthernetIIHeader -{ - struct NyLPC_TEthAddr dest; - struct NyLPC_TEthAddr src; - NyLPC_TUInt16 type; -}PACK_STRUCT_END; - - -NyLPC_TUInt16 NyLPC_TEthernetIIHeader_setArpTx( - struct NyLPC_TEthernetIIHeader* i_struct, - const struct NyLPC_TEthAddr* i_my_eth_addr); - -NyLPC_TUInt16 NyLPC_TEthernetIIHeader_setIPv4Tx( - struct NyLPC_TEthernetIIHeader* i_eth, - const struct NyLPC_TEthAddr* i_src_eth_addr, - const struct NyLPC_TEthAddr* i_dest_eth_addr); -/********************************************************************** - * - * struct NyLPC_TIPv4Header - * - **********************************************************************/ - - -/** - * IPパケットヘッダのメモリマップ構造体 - * 値はすべてネットワークオーダーです。 - */ -struct NyLPC_TIPv4Header -{ - NyLPC_TUInt8 vhl; - NyLPC_TUInt8 tos; - NyLPC_TUInt16 len16; - NyLPC_TUInt16 ipid16; - NyLPC_TUInt16 ipoffset; - NyLPC_TUInt8 ttl; - NyLPC_TUInt8 proto; - NyLPC_TUInt16 ipchksum; - struct NyLPC_TIPv4Addr srcipaddr; - struct NyLPC_TIPv4Addr destipaddr; -}PACK_STRUCT_END; - - - - -NyLPC_TBool NyLPC_TIPv4Header_isCorrectIpCheckSum( - const struct NyLPC_TIPv4Header* ip_header); - -NyLPC_TBool NyLPC_cIPv4Packet_isCorrectTcpCheckSum( - const struct NyLPC_TIPv4Header* ip_header); - -NyLPC_TUInt16 NyLPC_TIPv4Header_makeIpChecksum(const struct NyLPC_TIPv4Header* ip_header); - - -NyLPC_TUInt16 NyLPC_TIPv4Header_makeTcpChecksum( - const struct NyLPC_TIPv4Header* i_iph); - -#define NyLPC_TIPv4Header_isDestAddrEqual(i_struct,i_addr) ((i_struct)->destipaddr==(i_addr)) -#define NyLPC_TIPv4Header_isSrcAddrEqual(i_struct,i_addr) ((i_struct)->srcipaddr==(i_addr)) - -/** - * IPヘッダの長さを返す。 - */ -#define NyLPC_TIPv4Header_getHeaderLength(i_iph) (((i_iph)->vhl & 0x0f)*4) -/** - * IPパケット全体の長さを返す。 - */ -#define NyLPC_TIPv4Header_getPacketLength(i_iph) (NyLPC_ntohs((i_iph)->len16)) - -/** - * IPヘッダを送信パケット用に設定する。 - * ipid16にはコールされるたびに新しい値を設定する。 - * ipcecksumには0を設定する。 - * この関数は、パケットサイズ,ローカルIP/リモートIPの設定はしない。 - */ -void NyLPC_TIPv4Header_writeTxIpHeader( - struct NyLPC_TIPv4Header* i_struct, - NyLPC_TUInt8 i_proto); -/********************************************************************** - * - * struct NyLPC_TIPv6Header - * - **********************************************************************/ - - -struct NyLPC_TIPv6Header -{ - /* IPv6 header. */ - NyLPC_TUInt8 vtc; - NyLPC_TUInt8 tcflow; - NyLPC_TUInt16 flow; - NyLPC_TUInt8 len16; - NyLPC_TUInt8 proto, ttl; - uip_ip6addr_t srcipaddr; - uip_ip6addr_t destipaddr; -}PACK_STRUCT_END; - -void NyLPC_TIPv6Header_setSendHeader( - struct NyLPC_TIPv6Header* i_iph, - uip_ip6addr_t i_src, - uip_ip6addr_t i_dest, - NyLPC_TUInt8 i_proto, - NyLPC_TUInt8 i_ttl, - NyLPC_TUInt16 i_len); - -NyLPC_TUInt16 NyLPC_TIPv6Header_makeTcpChecksum( - struct NyLPC_TIPv6Header* i_iph, - NyLPC_TUInt16 i_len); - -#define NyLPC_TIPv6Header_isDestAddrEqual(i_struct,i_addr) (memcmp((i_struct)->destipaddr,(i_addr),sizeof(uip_ip6addr_t))) -#define NyLPC_TIPv6Header_isSrcAddrEqual(i_struct,i_addr) (memcmp(i_struct)->srcipaddr,(i_addr),sizeof(uip_ip6addr_t))) -/********************************************************************** - * - * struct NyLPC_TTcpHeader - * - **********************************************************************/ -#define TCP_OPT_END 0 /* End of TCP options list */ -#define TCP_OPT_NOOP 1 /* "No-operation" TCP option */ -#define TCP_OPT_MSS 2 /* Maximum segment size TCP option */ -#define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */ - -/** - * TCP/IPヘッダのメモリマップ構造体 - * マルチバイトの値は、全てネットワークオーダーです。 - */ -struct NyLPC_TTcpHeader -{ - //TCP header. - NyLPC_TUInt16 srcport; - NyLPC_TUInt16 destport; - NyLPC_TUInt32 seqno32; - NyLPC_TUInt32 ackno32; - NyLPC_TUInt8 tcpoffset; - NyLPC_TUInt8 flags; - NyLPC_TUInt16 wnd16; - NyLPC_TUInt16 tcpchksum; - NyLPC_TUInt8 urgp[2]; -// NyLPC_TUInt8 optdata[4]; -} PACK_STRUCT_END; - - -NyLPC_TUInt8* NyLPC_TTcpHeader_getTcpOptFragmentPtr( - const struct NyLPC_TTcpHeader* i_struct, - NyLPC_TUInt8 i_opt_id); - -NyLPC_TBool NyLPC_TTcpHeader_getTcpMmsOpt( - const struct NyLPC_TTcpHeader* i_struct,NyLPC_TUInt16* o_val); - -/** - * この関数は、TCPヘッダの長さを返します。ヘッダの長さは、i_structのフィールドから計算します。 - * @param i_struct - * 構造体のアドレス。 - */ -NyLPC_TUInt16 NyLPC_TTcpHeader_getHeaderLength(const struct NyLPC_TTcpHeader* i_struct); - -/** - * この関数は、指定したアドレスに、mmsオプション値を書き込みます。 - */ -void NyLPC_TTcpHeader_setMmsOpt(NyLPC_TUInt8* i_opt_addr,NyLPC_TUInt16 i_mms); - - -/********************************************************************** - * - * struct NyLPC_TUdpHeader - * - **********************************************************************/ - -/** - * UDP/IPヘッダのメモリマップ構造体 - */ -struct NyLPC_TUdpHeader -{ - NyLPC_TUInt16 srcport; - NyLPC_TUInt16 destport; - NyLPC_TUInt16 udplen; - NyLPC_TUInt16 udpchksum; -} PACK_STRUCT_END; - -/** - * UDPヘッダの長さを返す。 - */ -#define NyLPC_TUdpHeader_getHeaderLength(i_struct) (8) - -/********************************************************************** - * - * struct NyLPC_TIcmpipHeader - * - **********************************************************************/ - - -struct NyLPC_TIcmpHeader -{ - /* ICMP (echo) header. */ - NyLPC_TUInt8 type, icode; - NyLPC_TUInt16 icmpchksum; - #if !UIP_CONF_IPV6 - NyLPC_TUInt16 id, seqno; - #else /* !UIP_CONF_IPV6 */ - NyLPC_TUInt8 flags, reserved1, reserved2, reserved3; - NyLPC_TUInt8 icmp6data[16]; - NyLPC_TUInt8 options[1]; - #endif /* !UIP_CONF_IPV6 */ -} PACK_STRUCT_END; - -/********************************************************************** - * - * struct NyLPC_TIcmpipHeader - * - **********************************************************************/ - -struct NyLPC_TArpHeader -{ - NyLPC_TUInt16 hwtype; - NyLPC_TUInt16 protocol; - NyLPC_TUInt8 hwlen; - NyLPC_TUInt8 protolen; - NyLPC_TUInt16 opcode; - struct NyLPC_TEthAddr shwaddr; - struct NyLPC_TIPv4Addr sipaddr; - struct NyLPC_TEthAddr dhwaddr; - struct NyLPC_TIPv4Addr dipaddr; -} PACK_STRUCT_END; - - -/** - * i_req_addrを問い合わせるARP_REQUESTを生成します。 - */ -void NyLPC_TArpHeader_setArpRequest( - struct NyLPC_TArpHeader* i_struct, - const struct NyLPC_TIPv4Addr i_saddr, - const struct NyLPC_TEthAddr* i_srceth, - const struct NyLPC_TIPv4Addr* i_req_addr); - - -typedef struct NyLPC_TcEthernetIIPayload NyLPC_TcEthernetIIPayload_t; - - - - -/********************************************************************** - * - * NyLPC_TIPv6Payload - * - **********************************************************************/ - - -struct NyLPC_TIPv6Payload -{ - struct NyLPC_TIPv6Header* header; - union{ - void* rawbuf; - void* tcp; - void* udp; - void* icmp6; - }payload; -}; - -struct NyLPC_TcEthernetIIPayload -{ - struct NyLPC_TEthernetIIHeader* header; - union{ - void* rawbuf; - struct NyLPC_TArpHeader* arp; - struct NyLPC_TIPv4Payload* ipv4; - struct NyLPC_TIPv6Payload* ipv6; - }payload; - NyLPC_TUInt16 len; -}; - - - - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif
--- a/core/uip/NyLPC_uip_ethernet.c Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - * - * Parts of this file were leveraged from uIP: - * - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "NyLPC_uip_ethernet.h" - -const struct NyLPC_TEthAddr NyLPC_TEthAddr_BROADCAST = { { 0xff, 0xff, 0xff,0xff, 0xff, 0xff } }; -
--- a/core/uip/NyLPC_uip_ethernet.h Thu Nov 13 14:06:19 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -/********************************************************************************* - * PROJECT: MiMic - * -------------------------------------------------------------------------------- - * - * This file is part of MiMic - * Copyright (C)2011 Ryo Iizuka - * - * MiMic is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * For further information please contact. - * http://nyatla.jp/ - * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> - * - * - * Parts of this file were leveraged from uIP: - * - * Copyright (c) 2001-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef NyLPC_uip_ethernet_h -#define NyLPC_uip_ethernet_h -#include "../include/NyLPC_config.h" -#include "../include/NyLPC_stdlib.h" -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -#ifndef PACK_STRUCT_END - #define PACK_STRUCT_END __attribute((packed)) -#endif - -/********************************************************************** - * - * struct NyLPC_TEthAddr - * - **********************************************************************/ - -/** - * この構造体は、48bitのイーサネットアドレスを格納します。 - */ -struct NyLPC_TEthAddr -{ - NyLPC_TUInt8 addr[6]; -}PACK_STRUCT_END; - - -/** - * 構造体にEthernetアドレスをセットします。 - * 次のように使います。 - \code - struct NyLPC_TEthAddr en=NyLPC_TEthAddr_pack(1,2,3,4,5,6); - \endcode - */ -#define NyLPC_TEthAddr_pack(a1,a2,a3,a4,a5,a6) {{(a1),(a2),(a3),(a4),(a5),(a6)}} -/** - * 変数にEthernetアドレスをセットします。 - * 次のように使います。 - \code - struct NyLPC_TEthAddr en; - NyLPC_TEthAddr_set(&en,1,2,3,4,5,6); - \endcode - */ -#define NyLPC_TEthAddr_set(v,a1,a2,a3,a4,a5,a6) {(v)->addr[0]=(a1);(v)->addr[1]=(a2);(v)->addr[2]=(a3);(v)->addr[3]=(a4);(v)->addr[4]=(a5);(v)->addr[5]=(a6);} - -extern const struct NyLPC_TEthAddr NyLPC_TEthAddr_BROADCAST; - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif -
--- a/core/utils/NyLPC_cUuid.h Thu Nov 13 14:06:19 2014 +0000 +++ b/core/utils/NyLPC_cUuid.h Wed Nov 19 14:45:17 2014 +0000 @@ -26,7 +26,7 @@ #ifndef NYLPC_CUUID_H_ #define NYLPC_CUUID_H_ #include "NyLPC_stdlib.h" -#include "NyLPC_uipService.h" +#include "NyLPC_netif.h" #ifdef __cplusplus
--- a/mbed/Httpd.cpp Thu Nov 13 14:06:19 2014 +0000 +++ b/mbed/Httpd.cpp Wed Nov 19 14:45:17 2014 +0000 @@ -1,5 +1,6 @@ #include "Httpd.h" #include "HttpdConnection.h" +#include "mbed.h" namespace MiMic { char Httpd::_shared_buf[SIZE_OF_HTTP_BUF]; @@ -11,7 +12,9 @@ } Httpd::Httpd(int i_port_number) { - NyLPC_cHttpd_initialize((NyLPC_TcHttpd_t*)(&this->_inst),(NyLPC_TUInt16)i_port_number); + if(!NyLPC_cHttpd_initialize((NyLPC_TcHttpd_t*)(&this->_inst),(NyLPC_TUInt16)i_port_number)){ + mbed_die(); + } this->_inst._parent=this; this->_inst.super.function.onRequest=onRequestHandler; } @@ -43,4 +46,4 @@ return 0; } -} \ No newline at end of file +}
--- a/mbed/Net.cpp Thu Nov 13 14:06:19 2014 +0000 +++ b/mbed/Net.cpp Wed Nov 19 14:45:17 2014 +0000 @@ -1,4 +1,3 @@ -#pragma once //////////////////////////////////////////////////////////////////////////////// // Net.h //////////////////////////////////////////////////////////////////////////////// @@ -13,13 +12,13 @@ Net::Net() { - NyLPC_cNet_initialize(&(this->_inst)); + NyLPC_cNetIf_initialize(); this->_mdns=NULL; this->_upnp=NULL; } Net::~Net() { - NyLPC_cNet_finalize(&(this->_inst)); + NyLPC_cNetIf_finalize(); } void Net::start(NetConfig& i_cfg) { @@ -29,15 +28,13 @@ for(;;){ //DHCP if((base_cfg->tcp_mode & NyLPC_TcNetConfig_IPV4_FLAG_MODE_DHCP)!=0){ - if(NyLPC_cNet_requestAddrDhcp(&(this->_inst),&(base_cfg->super),3)){ + if(NyLPC_cNetIf_requestAddrDhcp(&(base_cfg->super),3)){ break; } } //AUTOIP if((base_cfg->tcp_mode & NyLPC_TcNetConfig_IPV4_FLAG_MODE_AUTOIP)!=0){ - NyLPC_TcApipa_t apipa; - NyLPC_cApipa_initialize(&apipa); - if(NyLPC_cApipa_requestAddr(&apipa,&(base_cfg->super),3)){ + if(NyLPC_cNetIf_requestAddrApipa(&(base_cfg->super),3)){ break; } } @@ -54,14 +51,14 @@ NyLPC_cUPnP_initialize(this->_upnp,i_cfg.getHttpPort(),UPNP_ROOT_PATH,i_cfg.refUPnPDevDesc()); } - NyLPC_cNet_start(&(this->_inst),base_cfg); + NyLPC_cNetIf_start(&(base_cfg->super)); if(this->_upnp!=NULL){ NyLPC_cUPnP_start(this->_upnp); } } void Net::stop() { - NyLPC_cNet_stop(&(this->_inst)); + NyLPC_cNetIf_stop(); //stop mDNS if(this->_mdns!=NULL){ NyLPC_cMDnsServer_finalize(this->_mdns); @@ -70,4 +67,4 @@ } } -} \ No newline at end of file +}
--- a/mbed/Net.h Thu Nov 13 14:06:19 2014 +0000 +++ b/mbed/Net.h Wed Nov 19 14:45:17 2014 +0000 @@ -20,8 +20,6 @@ NyLPC_TcMDnsServer_t* _mdns; NyLPC_TcUPnP_t* _upnp; public: - NyLPC_TcNet_t _inst; - public: /** * The constructor. * Must be call after the RTOS started. @@ -43,4 +41,4 @@ */ const NyLPC_TcUPnP_t* refUPnPInstance()const{return this->_upnp;} }; -} \ No newline at end of file +}
--- a/mbed/NetConfig.cpp Thu Nov 13 14:06:19 2014 +0000 +++ b/mbed/NetConfig.cpp Wed Nov 19 14:45:17 2014 +0000 @@ -1,7 +1,6 @@ #include "NetConfig.h" -#include "NyLPC_uip.h" #include "NyLPC_flash.h" -#include "NyLPC_uip_ethernet.h" +#include "NyLPC_netif.h" #include "utils/PlatformInfo.h" #include <stdio.h> #include <stdlib.h>
--- a/mbed/TcpSocket.cpp Thu Nov 13 14:06:19 2014 +0000 +++ b/mbed/TcpSocket.cpp Wed Nov 19 14:45:17 2014 +0000 @@ -1,36 +1,28 @@ -#pragma once //////////////////////////////////////////////////////////////////////////////// // TcpSocket.h //////////////////////////////////////////////////////////////////////////////// #include "TcpSocket.h" - +#include "mbed.h" namespace MiMic { #define TIMEOUT_IN_MSEC (5*1000) - TcpSocket::TcpSocket(void* i_rx_buf,unsigned short i_rx_buf_size) + TcpSocket::TcpSocket() { - this->_private_rx=NULL; - NyLPC_cTcpSocket_initialize(&this->_inst,i_rx_buf,i_rx_buf_size); + this->_inst=NyLPC_cNetIf_createTcpSocketEx(NyLPC_TSocketType_TCP_NORMAL); + if(this->_inst==NULL){ + mbed_die(); + } } - TcpSocket::TcpSocket(unsigned short i_rx_buf_size) - { - this->_private_rx=malloc(i_rx_buf_size); - NyLPC_cTcpSocket_initialize(&this->_inst,this->_private_rx,i_rx_buf_size); - } - TcpSocket::~TcpSocket() { - NyLPC_cTcpSocket_finalize(&this->_inst); - if(this->_private_rx!=NULL){ - free(this->_private_rx); - } + NyLPC_iTcpSocket_finalize(this->_inst); } bool TcpSocket::connect(const IpAddr& i_addr,unsigned short i_port) { - return NyLPC_cTcpSocket_connect(&this->_inst,&(i_addr.addr.v4),i_port,TIMEOUT_IN_MSEC)?true:false; + return NyLPC_iTcpSocket_connect(this->_inst,&(i_addr.addr.v4),i_port,TIMEOUT_IN_MSEC)?true:false; } bool TcpSocket::send(const void* i_tx,unsigned short i_tx_size) @@ -38,7 +30,7 @@ int l,t; l=i_tx_size; while(l>0){ - t=NyLPC_cTcpSocket_send(&this->_inst,((const char*)i_tx)+(i_tx_size-l),l,TIMEOUT_IN_MSEC); + t=NyLPC_iTcpSocket_send(this->_inst,((const char*)i_tx)+(i_tx_size-l),l,TIMEOUT_IN_MSEC); if(t<0){ return false; } @@ -49,22 +41,22 @@ bool TcpSocket::canRecv() { const void* rx; - return NyLPC_cTcpSocket_precv(&this->_inst,&rx,0)>0; + return NyLPC_iTcpSocket_precv(this->_inst,&rx,0)>0; } int TcpSocket::precv(const void* &i_rx) { - return NyLPC_cTcpSocket_precv(&this->_inst,&i_rx,TIMEOUT_IN_MSEC); + return NyLPC_iTcpSocket_precv(this->_inst,&i_rx,TIMEOUT_IN_MSEC); } int TcpSocket::precv(const char* &i_rx) { - return NyLPC_cTcpSocket_precv(&this->_inst,(const void**)&i_rx,TIMEOUT_IN_MSEC); + return NyLPC_iTcpSocket_precv(this->_inst,(const void**)&i_rx,TIMEOUT_IN_MSEC); } void TcpSocket::pseek(unsigned short i_rx_seek) { - NyLPC_cTcpSocket_pseek(&this->_inst,i_rx_seek); + NyLPC_iTcpSocket_pseek(this->_inst,i_rx_seek); } void TcpSocket::close() { - return NyLPC_cTcpSocket_close(&this->_inst,TIMEOUT_IN_MSEC); + return NyLPC_iTcpSocket_close(this->_inst,TIMEOUT_IN_MSEC); } -} \ No newline at end of file +}
--- a/mbed/TcpSocket.h Thu Nov 13 14:06:19 2014 +0000 +++ b/mbed/TcpSocket.h Wed Nov 19 14:45:17 2014 +0000 @@ -3,7 +3,7 @@ // TcpSocket.h //////////////////////////////////////////////////////////////////////////////// -#include "NyLPC_net.h" +#include "NyLPC_netif.h" #include "IpAddr.h" namespace MiMic @@ -15,15 +15,13 @@ class TcpSocket { private: - NyLPC_TcTcpSocket_t _inst; - void* _private_rx; + NyLPC_TiTcpSocket_t* _inst; public: /** wrapped base LPC class.*/ - NyLPC_TcTcpSocket_t* refBaseInstance(){return &this->_inst;} + NyLPC_TiTcpSocket_t* refBaseInstance(){return this->_inst;} public: - TcpSocket(unsigned short i_rx_buf_size=(unsigned short)512); - TcpSocket(void* i_rx_buf,unsigned short i_rx_buf_size); + TcpSocket(); virtual ~TcpSocket(); /** * @param i_host_addr
--- a/mbed/UdpSocket.cpp Thu Nov 13 14:06:19 2014 +0000 +++ b/mbed/UdpSocket.cpp Wed Nov 19 14:45:17 2014 +0000 @@ -3,7 +3,7 @@ //////////////////////////////////////////////////////////////////////////////// #include "UdpSocket.h" - +#include "mbed.h" @@ -11,38 +11,38 @@ { #define TIMEOUT_IN_MSEC (2*1000) - UdpSocket::UdpSocket(unsigned short i_port,unsigned short i_rx_buf_size) + void UdpSocket::rxhandler(NyLPC_TiUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info) { - this->_private_rx=malloc(i_rx_buf_size); - NyLPC_cUdpSocket_initialize(&this->_inst,i_port,this->_private_rx,i_rx_buf_size); - } - UdpSocket::UdpSocket(unsigned short i_port,void* i_rx_buf,unsigned short i_rx_buf_size) - { - this->_private_rx=NULL; - NyLPC_cUdpSocket_initialize(&this->_inst,i_port,i_rx_buf,i_rx_buf_size); + UdpSocket* sock=(UdpSocket*)i_inst->_tag; + sock->onRxHandler(i_buf,i_info); } - UdpSocket::UdpSocket(unsigned short i_port,void* i_rx_handler) + UdpSocket::UdpSocket(unsigned short i_port,bool i_nobuffer) { + if(i_nobuffer){ + this->_inst=NyLPC_cNetIf_createUdpSocketEx(i_port,NyLPC_TSocketType_UDP_NOBUF); + }else{ + this->_inst=NyLPC_cNetIf_createUdpSocketEx(i_port,NyLPC_TSocketType_UDP_NORMAL); + } + if(this->_inst==NULL){ + mbed_die(); + } } UdpSocket::~UdpSocket() { - NyLPC_cUdpSocket_finalize(&this->_inst); - if(this->_private_rx!=NULL){ - free(this->_private_rx); - } + NyLPC_iUdpSocket_finalize(this->_inst); } bool UdpSocket::canRecv() { const void* rx; const struct NyLPC_TIPv4RxInfo* info; - return NyLPC_cUdpSocket_precv(&this->_inst,&rx,&info,TIMEOUT_IN_MSEC)>0; + return NyLPC_iUdpSocket_precv(this->_inst,&rx,&info,TIMEOUT_IN_MSEC)>0; } int UdpSocket::precvFrom(const void* &i_rx,IpAddr* i_peer_host,unsigned short* i_port) { const struct NyLPC_TIPv4RxInfo* info; - int rs=NyLPC_cUdpSocket_precv(&this->_inst,&i_rx,&info,TIMEOUT_IN_MSEC); + int rs=NyLPC_iUdpSocket_precv(this->_inst,&i_rx,&info,TIMEOUT_IN_MSEC); if(rs>1){ if(i_peer_host!=NULL){ i_peer_host->setIPv4(info->peer_ip); @@ -56,7 +56,7 @@ int UdpSocket::precvFrom(const char* &i_rx,IpAddr* i_peer_host,unsigned short* i_port) { const struct NyLPC_TIPv4RxInfo* info; - int rs=NyLPC_cUdpSocket_precv(&this->_inst,(const void**)&i_rx,&info,TIMEOUT_IN_MSEC); + int rs=NyLPC_iUdpSocket_precv(this->_inst,(const void**)&i_rx,&info,TIMEOUT_IN_MSEC); if(rs>1){ if(i_peer_host!=NULL){ i_peer_host->setIPv4(info->peer_ip); @@ -70,23 +70,23 @@ void UdpSocket::precvNext(void) { - NyLPC_cUdpSocket_pseek(&this->_inst); + NyLPC_iUdpSocket_pseek(this->_inst); } bool UdpSocket::sendTo(const IpAddr& i_host,unsigned short i_port,const void* i_tx,unsigned short i_tx_size) { - int r=NyLPC_cUdpSocket_send(&this->_inst,&i_host.addr.v4,i_port,i_tx,i_tx_size,TIMEOUT_IN_MSEC); + int r=NyLPC_iUdpSocket_send(this->_inst,&i_host.addr.v4,i_port,i_tx,i_tx_size,TIMEOUT_IN_MSEC); return (r==i_tx_size); } void UdpSocket::joinMulticast(const IpAddr& i_host) { - NyLPC_cUdpSocket_joinMulticast(&this->_inst,&i_host.addr.v4); + NyLPC_iUdpSocket_joinMulticast(this->_inst,&i_host.addr.v4); } void UdpSocket::setBroadcast(void) { - NyLPC_cUdpSocket_setBroadcast(&this->_inst); + NyLPC_iUdpSocket_setBroadcast(this->_inst); } -} \ No newline at end of file +}
--- a/mbed/UdpSocket.h Thu Nov 13 14:06:19 2014 +0000 +++ b/mbed/UdpSocket.h Wed Nov 19 14:45:17 2014 +0000 @@ -8,6 +8,7 @@ namespace MiMic { + class UdpSocket; /** * Udp Socket Class. * The class is used by Net constructor. @@ -15,34 +16,27 @@ class UdpSocket { private: - NyLPC_TcUdpSocket_t _inst; - void* _private_rx; + NyLPC_TiUdpSocket_t* _inst; public: /** wrapped base LPC class.*/ - NyLPC_TcUdpSocket_t* refBaseInstance(){return &this->_inst;} - + NyLPC_TiUdpSocket_t* refBaseInstance(){return this->_inst;} + public: /** + * Create standard UDP socket. * @param i_port * port number. - * @param i_rx_buf_size - * Size of the receive memory to allocate on heap + * @param i_nobuffer + * false(default) - + * UDP packets will be receive to internal buffer. It can be access by precvFrom/precvNext function. + * It is accepts only "Short" packet. + * MUST BE SET NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX 1 or more when MiMicIPNetInterface using. + * true - + * UDP packets will be handled to onRxHandler function. + * It is accepts "Full size" packet. + * MUST BE SET NyLPC_cMiMicIpNetIf_config_UDPSOCKET_NB_MAX 1 or more when MiMicIPNetInterface using. */ - UdpSocket(unsigned short i_port,unsigned short i_rx_buf_size=(unsigned short)512); - /** - * @param i_port - * port number. - * @param i_rx_buffer - * allocated memory for receiving. - * @param i_rx_buf_size - * Size of the i_rx_buf - */ - UdpSocket(unsigned short i_port,void* i_rx_buf,unsigned short i_rx_buf_size); - /** - * This constructor accepts "large" packet by asynchronous handler. - * Must be override "onRxHandler" function. - */ - UdpSocket(unsigned short i_port,void* i_rx_handler); + UdpSocket(unsigned short i_port,bool i_nobuffer=false); virtual ~UdpSocket(); /** * This function return recieved data and size. @@ -66,6 +60,14 @@ bool sendTo(const IpAddr& i_host,unsigned short i_port,const void* i_tx,unsigned short i_tx_size); void joinMulticast(const IpAddr& i_host); void setBroadcast(void); + protected: + /** + * callback function. + * MUST be override when used callback constructor. + */ + virtual void onRxHandler(const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info){}; + static void rxhandler(NyLPC_TiUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info); + }; }