Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of libMiMic by
NyLPC_cMiMicIpNetIf.c
00001 /********************************************************************************* 00002 * PROJECT: MiMic 00003 * -------------------------------------------------------------------------------- 00004 * 00005 * This file is part of MiMic 00006 * Copyright (C)2011 Ryo Iizuka 00007 * 00008 * MiMic is free software: you can redistribute it and/or modify 00009 * it under the terms of the GNU Lesser General Public License as published 00010 * by the Free Software Foundation, either version 3 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public License 00019 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00020 * 00021 * For further information please contact. 00022 * http://nyatla.jp/ 00023 * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> 00024 * 00025 * 00026 * Parts of this file were leveraged from uIP: 00027 * 00028 * Copyright (c) 2001-2003, Adam Dunkels. 00029 * All rights reserved. 00030 * 00031 * Redistribution and use in source and binary forms, with or without 00032 * modification, are permitted provided that the following conditions 00033 * are met: 00034 * 1. Redistributions of source code must retain the above copyright 00035 * notice, this list of conditions and the following disclaimer. 00036 * 2. Redistributions in binary form must reproduce the above copyright 00037 * notice, this list of conditions and the following disclaimer in the 00038 * documentation and/or other materials provided with the distribution. 00039 * 3. The name of the author may not be used to endorse or promote 00040 * products derived from this software without specific prior 00041 * written permission. 00042 * 00043 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 00044 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00045 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00046 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 00047 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00048 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00049 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00050 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00051 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00052 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00053 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00054 */ 00055 //#include "NyLPC_cIPv4IComp_protected.h" 00056 //#include "NyLPC_cTcpListener_protected.h" 00057 #include "NyLPC_cMiMicIpNetIf_protected.h" 00058 #include "NyLPC_stdlib.h" 00059 #include "../NyLPC_NetIf_ip_types.h" 00060 #include "NyLPC_cIPv4IComp_protected.h" 00061 #include "NyLPC_cMiMicIpTcpSocket_protected.h" 00062 #include "NyLPC_cMiMicIpUdpSocket_protected.h" 00063 #include "NyLPC_cMiMicIpTcpListener_protected.h" 00064 00065 00066 00067 00068 00069 /**************************************************** 00070 * UipServiceに関する宣言:その他 00071 ***************************************************/ 00072 /** 00073 * イーサネットフレームの読み出し構造体 00074 */ 00075 struct TEthPacket 00076 { 00077 struct NyLPC_TEthernetIIHeader header; 00078 union{ 00079 struct NyLPC_TArpHeader arp; 00080 struct NyLPC_TIPv4Header ipv4; 00081 }data; 00082 }PACK_STRUCT_END; 00083 00084 00085 00086 /** 00087 * サービスインスタンスのポインタ。サービスが稼働中はインスタンスのポインタが有効です。 00088 */ 00089 NyLPC_TcMiMicIpNetIf_t* _NyLPC_TcMiMicIpNetIf_inst=NULL; 00090 00091 00092 00093 /** 00094 * uipタスク 00095 */ 00096 static int uipTask(void *pvParameters); 00097 00098 /** イーサネットドライバからのハンドラ*/ 00099 static void ethernet_handler(void* i_param,NyLPC_TiEthernetDevice_EVENT i_type); 00100 00101 //-------------------------------------------------------------- 00102 00103 00104 static NyLPC_TBool sendIPv4Tx(struct TEthPacket* i_eth_buf); 00105 00106 //static void sendArpReqest(const struct TEthPacket* i_eth_packet); 00107 static void sendRawEthFrameNL(void* i_buf,NyLPC_TUInt16 i_len); 00108 static void releaseTxBufNL(void* i_buf); 00109 00110 /**メッセージなし*/ 00111 #define TTaskMessage_MSG_NULL 0x0000 00112 /**uipコアタスクに、開始要求する*/ 00113 #define TTaskMessage_MSG_RUN 0x0001 00114 /**uipコアタスクに、停止要求する*/ 00115 #define TTaskMessage_MSG_STOP 0x0002 00116 00117 00118 static NyLPC_TcThread_t th; 00119 00120 NyLPC_TBool NyLPC_cMiMicIpNetIf_initialize(NyLPC_TcMiMicIpNetIf_t* i_inst) 00121 { 00122 //サービスは停止している事。 - Service must be uninitialized. 00123 NyLPC_Assert(!NyLPC_cMiMicIpNetIf_isInitService()); 00124 //IP処理部分の初期化 00125 NyLPC_cIPv4_initialize(&(i_inst->_tcpv4)); 00126 //EMAC割込セマフォ 00127 NyLPC_cSemaphore_initialize(&i_inst->_emac_semapho); 00128 00129 i_inst->_status=0x00; 00130 NyLPC_cStopwatch_initialize(&(i_inst->_arp_sw)); 00131 NyLPC_cStopwatch_initialize(&(i_inst->_periodic_sw)); 00132 NyLPC_AbortIfNot(NyLPC_cMutex_initialize(&(i_inst->_mutex))); 00133 00134 _NyLPC_TcMiMicIpNetIf_inst=i_inst; 00135 //タスク起動 00136 NyLPC_cThread_initialize(&th,NyLPC_cMiMicIpNetIf_config_STACK_SIZE,NyLPC_TcThread_PRIORITY_SERVICE); 00137 NyLPC_cThread_start(&th,uipTask,NULL); 00138 return NyLPC_TBool_TRUE; 00139 } 00140 00141 00142 00143 00144 00145 00146 00147 /** 00148 * UIP処理を開始します。 00149 * この関数はリエントラントではありません。複数のタスクから共有するときには、排他ロックを掛けてください。 00150 * @param i_ref_config 00151 * このコンフィギュレーションは、stopを実行するまでの間、インスタンスから参照します。外部で保持してください。 00152 */ 00153 void NyLPC_cMiMicIpNetIf_start(const NyLPC_TcIPv4Config_t* i_ref_config) 00154 { 00155 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; 00156 NyLPC_Assert(NyLPC_cMiMicIpNetIf_isInitService()); 00157 if(!NyLPC_cMiMicIpNetIf_isRun()) 00158 { 00159 //はじめて起動するときに1度だけデバイス取得(タスクスイッチが動いてないと動かないからここで。) 00160 if(inst->_ethif==NULL){ 00161 inst->_ethif=getEthernetDevicePnP(); 00162 } 00163 //コンフィグレーションセット 00164 inst->_netinfo.current_config=i_ref_config; 00165 //開始要求セット 00166 NyLPC_TUInt16_setBit(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_START); 00167 //Order実行待ち 00168 while(NyLPC_TUInt16_isBitOn(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_START)){ 00169 NyLPC_cThread_sleep(10); 00170 } 00171 //デバイス情報の追記 00172 inst->_netinfo.device_name=NyLPC_iEthernetDevice_getDevicName(inst->_ethif); 00173 } 00174 return; 00175 } 00176 /** 00177 * UIP処理を停止します。 00178 * この関数はリエントラントではありません。複数のタスクから共有するときには、排他ロックを掛けてください。 00179 * いまのところ、ストップシーケンスの実装は良くありません。 00180 * 再設計が必要。 00181 */ 00182 void NyLPC_cMiMicIpNetIf_stop(void) 00183 { 00184 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; 00185 NyLPC_Assert(NyLPC_cMiMicIpNetIf_isInitService()); 00186 if(NyLPC_cMiMicIpNetIf_isRun()) 00187 { 00188 NyLPC_TUInt16_setBit(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_STOP); 00189 //Order実行待ち 00190 while(NyLPC_TUInt16_isBitOn(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_STOP)){ 00191 NyLPC_cThread_sleep(10); 00192 } 00193 } 00194 return; 00195 } 00196 00197 static const struct NyLPC_TNetInterfaceInfo* NyLPC_cMiMicIpNetIf_getInterfaceInfo(void) 00198 { 00199 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; 00200 return &inst->_netinfo; 00201 } 00202 00203 /********************************************************************** 00204 * 00205 * </HWコールバックに関わる宣言> 00206 * 00207 *********************************************************************/ 00208 00209 00210 //PERIODIC rate 00211 #define PERIODIC_TIMER (1*200) 00212 #define ARP_TIMER (60*1000*10) 00213 00214 00215 00216 /** 00217 * 操作キューを確認して、タスクのステータスをアップデートします。 00218 * 高速化のため、Proc-Callerを使用していません。複雑なタスク操作をするときには、書き換えてください。 00219 * @return 00220 * UIPタスクの実行状態 00221 */ 00222 static NyLPC_TBool updateTaskStatus() 00223 { 00224 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; 00225 if(NyLPC_cMiMicIpNetIf_isRun()){ 00226 //開始状態 00227 if(NyLPC_TUInt16_isBitOn(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_STOP)) 00228 { 00229 //停止操作 00230 NyLPC_iEthernetDevice_stop(inst->_ethif); 00231 NyLPC_cIPv4_stop(&(inst->_tcpv4)); 00232 NyLPC_cIPv4IComp_finalize(&(inst->_icomp)); 00233 NyLPC_cIPv4Arp_finalize(&(inst->_arp)); 00234 // inst->_ref_config=NULL; 00235 NyLPC_TUInt16_unsetBit(inst->_status,NyLPC_TcMiMicIpNetIf_STATUSBIT_IS_RUNNING); 00236 NyLPC_TUInt16_unsetBit(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_STOP); 00237 return NyLPC_TBool_FALSE; 00238 } 00239 return NyLPC_TBool_TRUE; 00240 }else{ 00241 //停止状態 00242 if(NyLPC_TUInt16_isBitOn(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_START)) 00243 { 00244 //TCP,ICOMPの初期化 00245 NyLPC_cIPv4_start(&(inst->_tcpv4),inst->_netinfo.current_config); 00246 NyLPC_cIPv4IComp_initialize(&(inst->_icomp),inst->_netinfo.current_config); 00247 //uip_arp_init(msg->start.ref_config); 00248 NyLPC_cIPv4Arp_initialize(&(inst->_arp),inst->_netinfo.current_config); 00249 NyLPC_cStopwatch_startExpire(&(inst->_arp_sw),1);//1度ARPを起動するため。 00250 NyLPC_cStopwatch_startExpire(&(inst->_periodic_sw),PERIODIC_TIMER); 00251 //EtherNETデバイス初期化 00252 while(!NyLPC_iEthernetDevice_start(inst->_ethif,&(inst->_netinfo.current_config->eth_mac),ethernet_handler,inst)); 00253 NyLPC_TUInt16_setBit(inst->_status,NyLPC_TcMiMicIpNetIf_STATUSBIT_IS_RUNNING); 00254 NyLPC_TUInt16_unsetBit(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_START); 00255 return NyLPC_TBool_TRUE; 00256 } 00257 return NyLPC_TBool_FALSE; 00258 } 00259 } 00260 00261 /** 00262 * uipタスクのメインループ 00263 */ 00264 static int uipTask(void *pvParameters) 00265 { 00266 NyLPC_TUInt16 rx_len,tx_len; 00267 struct TEthPacket* ethbuf; 00268 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; 00269 void* r; 00270 (void)pvParameters; 00271 for( ;; ) 00272 { 00273 //タスク状態の更新 00274 if(!updateTaskStatus()) 00275 { 00276 //RUNステータス以外の時は、ここで終了する。 00277 NyLPC_cThread_sleep(50); 00278 continue; 00279 } 00280 //イーサネットフレームの取得 00281 //Ethernet Device Lock(ARPを含む) 00282 NyLPC_cMutex_lock(&(inst->_mutex)); 00283 ethbuf= (struct TEthPacket*)NyLPC_iEthernetDevice_getRxEthFrame(inst->_ethif,&rx_len); 00284 tx_len=0; 00285 while(ethbuf != NULL){ 00286 if(rx_len>0) 00287 { 00288 //ペイロードサイズを計算 00289 rx_len-=sizeof(struct NyLPC_TEthernetIIHeader); 00290 switch(ethbuf->header.type) 00291 { 00292 case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_IP): 00293 //ARPテーブルの更新 00294 //uip_arp_ipin(&(ethbuf->header),ethbuf->data.ipv4.srcipaddr); 00295 NyLPC_cIPv4Arp_incomingIp(&inst->_arp,&(ethbuf->header),ethbuf->data.ipv4.srcipaddr); 00296 //Ethernet Device UnLock(NyLPC_cIPv4_rxがallocをコールする可能性があるので一時的にロック解除) 00297 NyLPC_cMutex_unlock(&(inst->_mutex)); 00298 //IPパケットの処理 00299 r=NyLPC_cIPv4_rx(&(inst->_tcpv4),&(ethbuf->data.ipv4),rx_len); 00300 if(r!=NULL){ 00301 //IPパケットとして送信 00302 NyLPC_cMiMicIpNetIf_sendIPv4Tx(r); 00303 } 00304 //ロックの復帰 00305 NyLPC_cMutex_lock(&(inst->_mutex)); 00306 if(r!=NULL){ 00307 releaseTxBufNL(r); 00308 } 00309 break; 00310 case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_ARP): 00311 //Ethernet Device UnLock(NyLPC_cIPv4_rxがallocをコールする可能性があるので一時的にロック解除) 00312 NyLPC_cMutex_unlock(&(inst->_mutex)); 00313 r=NyLPC_cIPv4Arp_rx(&inst->_arp,&(ethbuf->data.arp),rx_len,&tx_len); 00314 NyLPC_cMutex_lock(&(inst->_mutex)); 00315 if(r!=NULL){ 00316 sendRawEthFrameNL(r,tx_len); 00317 releaseTxBufNL(r); 00318 } 00319 break; 00320 case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_IPV6): 00321 //uip_process_ipv6(); 00322 break; 00323 default: 00324 break; 00325 } 00326 } 00327 //受信キューを進行。 00328 NyLPC_iEthernetDevice_nextRxEthFrame(inst->_ethif); 00329 //受信処理 00330 ethbuf= (struct TEthPacket*)NyLPC_iEthernetDevice_getRxEthFrame(inst->_ethif,&rx_len); 00331 } 00332 //データが無い。 00333 if(NyLPC_cStopwatch_isExpired(&(inst->_arp_sw))){ 00334 //uip_arp_timer(); 00335 NyLPC_cIPv4Arp_periodic(&inst->_arp); 00336 NyLPC_cStopwatch_startExpire(&(inst->_arp_sw),ARP_TIMER); 00337 } 00338 if(NyLPC_cStopwatch_isExpired(&(inst->_periodic_sw))){ 00339 NyLPC_cMutex_unlock(&(inst->_mutex)); 00340 NyLPC_cIPv4_periodec(&(inst->_tcpv4)); 00341 NyLPC_cMutex_lock(&(inst->_mutex)); 00342 NyLPC_cStopwatch_startExpire(&(inst->_periodic_sw),PERIODIC_TIMER); 00343 } 00344 //リソースロックの解除 00345 NyLPC_cMutex_unlock(&(inst->_mutex)); 00346 //割込によるセマフォの解除か、タイムアウトで再開する。(タイムアウト値は周期関数の実行レート以下にすること。) 00347 NyLPC_cSemaphore_take(&(_NyLPC_TcMiMicIpNetIf_inst->_emac_semapho),PERIODIC_TIMER); 00348 } 00349 return 0; 00350 } 00351 00352 00353 /** 00354 * イーサネットドライバからのハンドラ 00355 */ 00356 static void ethernet_handler(void* i_param,NyLPC_TiEthernetDevice_EVENT i_type) 00357 { 00358 switch(i_type){ 00359 case NyLPC_TiEthernetDevice_EVENT_ON_RX: 00360 //受信系のセマフォブロックの解除 00361 NyLPC_cSemaphore_giveFromISR(&(((NyLPC_TcMiMicIpNetIf_t*)i_param)->_emac_semapho)); 00362 break; 00363 default: 00364 break; 00365 } 00366 } 00367 00368 /** 00369 * IPv4パケットのpeerIPを問い合わせるARPパケットを送信します。 00370 * allocを中でコールするから要UNLOCK状態 00371 */ 00372 void NyLPC_cMiMicIpNetIf_sendArpRequest(const struct NyLPC_TIPv4Addr* i_addr) 00373 { 00374 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; 00375 NyLPC_TUInt16 tx_len; 00376 struct TEthPacket* ethbuf; 00377 //システムTXメモリを得てイーサフレームのポインタを復元 00378 ethbuf=(struct TEthPacket*)(((struct NyLPC_TEthernetIIHeader*)NyLPC_cMiMicIpNetIf_allocSysTxBuf()-1)); 00379 //ARPパケットを作る。 00380 NyLPC_TArpHeader_setArpRequest(&(ethbuf->data.arp),inst->_netinfo.current_config->ip_addr,&(inst->_netinfo.current_config->eth_mac),i_addr); 00381 tx_len=NyLPC_TEthernetIIHeader_setArpTx(&(ethbuf->header),&(inst->_netinfo.current_config->eth_mac)); 00382 //送信 00383 NyLPC_cMutex_lock(&(inst->_mutex)); 00384 NyLPC_iEthernetDevice_sendTxEthFrame(inst->_ethif,ethbuf,tx_len); 00385 NyLPC_iEthernetDevice_releaseTxBuf(inst->_ethif,ethbuf);//NyLPC_cMiMicIpNetIf_releaseTxBufの代用だから元のイーサフレームメモリの値で開放 00386 NyLPC_cMutex_unlock(&(inst->_mutex)); 00387 } 00388 00389 00390 00391 00392 /** 00393 * allocTxBufで取得したペイロードメモリを"IPパケットとして"送信します。 00394 * @param i_eth_payload 00395 * [NyLPC_TEthernetIIHeader][payload]メモリの、[payload]のアドレスを指定します。 00396 * 通常は、NyLPC_cUipService_allocTxBufの返却したメモリを指定します。 00397 */ 00398 00399 void NyLPC_cMiMicIpNetIf_sendIPv4Tx(void* i_eth_payload) 00400 { 00401 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; 00402 void* p=((struct NyLPC_TEthernetIIHeader*)i_eth_payload)-1; 00403 NyLPC_cMutex_lock(&(inst->_mutex)); 00404 //IPパケットの送信を試行 00405 if(sendIPv4Tx((struct TEthPacket*)p)){ 00406 NyLPC_cMutex_unlock(&(inst->_mutex)); 00407 return; 00408 } 00409 NyLPC_cMutex_unlock(&(inst->_mutex)); 00410 //ARPリクエストを代わりに送信 00411 { 00412 //LocalIP以外ならdefaultRootへ変換 00413 NyLPC_TBool isLocal = NyLPC_cIPv4Config_isLocalIP(inst->_netinfo.current_config, &((struct NyLPC_TIPv4Header*)i_eth_payload)->destipaddr); 00414 NyLPC_cMiMicIpNetIf_sendArpRequest(isLocal ? &((struct NyLPC_TIPv4Header*)i_eth_payload)->destipaddr : &(inst->_netinfo.current_config->dr_addr)); 00415 } 00416 return; 00417 } 00418 00419 00420 /** 00421 * ARPテーブルに指定したIPがあるかを返します。 00422 */ 00423 NyLPC_TBool NyLPC_cMiMicIpNetIf_hasArpInfo(const struct NyLPC_TIPv4Addr* i_addr) 00424 { 00425 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; 00426 return NyLPC_cIPv4Arp_IPv4toEthAddr(&inst->_arp,*i_addr)!=NULL; 00427 } 00428 00429 /** 00430 * システム用の送信ペイロードを返します。 00431 * 関数は必ず成功します。 00432 */ 00433 void* NyLPC_cMiMicIpNetIf_allocSysTxBuf(void) 00434 { 00435 NyLPC_TUInt16 s; 00436 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; 00437 struct TEthPacket* ethbuf; 00438 //排他処理をして、メモリを取得する。SYSTEMメモリはEthernetドライバの解放待ちのみなのでまとめてLOCKしておk 00439 NyLPC_cMutex_lock(&(inst->_mutex)); 00440 for(;;){ 00441 ethbuf=(struct TEthPacket*)NyLPC_iEthernetDevice_allocTxBuf(inst->_ethif,NyLPC_TcEthernetMM_HINT_CTRL_PACKET,&s); 00442 if(ethbuf==NULL){ 00443 NyLPC_cThread_yield(); 00444 continue; 00445 } 00446 break; 00447 } 00448 NyLPC_cMutex_unlock(&(inst->_mutex)); 00449 //イーサネットバッファのアドレスを計算 00450 return &(ethbuf->data); 00451 } 00452 00453 00454 00455 void* NyLPC_cMiMicIpNetIf_allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size) 00456 { 00457 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; 00458 struct TEthPacket* ethbuf; 00459 //排他処理をして、メモリを取得する。 00460 NyLPC_cMutex_lock(&(inst->_mutex)); 00461 ethbuf=(struct TEthPacket*)NyLPC_iEthernetDevice_allocTxBuf(inst->_ethif,i_hint+sizeof(struct NyLPC_TEthernetIIHeader),o_size); 00462 NyLPC_cMutex_unlock(&(inst->_mutex)); 00463 if(ethbuf==NULL){ 00464 return NULL; 00465 } 00466 //イーサネットバッファのサイズを計算 00467 *o_size-=sizeof(struct NyLPC_TEthernetIIHeader); 00468 //イーサネットバッファのアドレスを計算 00469 return &(ethbuf->data); 00470 } 00471 00472 00473 void* NyLPC_cMiMicIpNetIf_releaseTxBuf(void* i_buf) 00474 { 00475 //排他処理をして、メモリを開放する。 00476 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; 00477 NyLPC_cMutex_lock(&(inst->_mutex)); 00478 //ペイロードの位置から、メモリブロックを再生。 00479 NyLPC_iEthernetDevice_releaseTxBuf(inst->_ethif,((struct NyLPC_TEthernetIIHeader*)i_buf)-1); 00480 NyLPC_cMutex_unlock(&(inst->_mutex)); 00481 return NULL; 00482 } 00483 00484 00485 00486 00487 00488 00489 00490 00491 00492 /** 00493 * イーサネットフレームを送信します。 00494 * この関数はiptaskで実行される関数からのみ使用てください。 00495 * @i_buf 00496 * イーサネットフレームを格納したメモリです。 00497 * @i_len 00498 * イーサネットペイロードのサイズです。 00499 */ 00500 static void sendRawEthFrameNL(void* i_buf,NyLPC_TUInt16 i_len) 00501 { 00502 NyLPC_iEthernetDevice_sendTxEthFrame( 00503 _NyLPC_TcMiMicIpNetIf_inst->_ethif, 00504 ((struct NyLPC_TEthernetIIHeader*)i_buf)-1, 00505 i_len); 00506 return; 00507 } 00508 /** 00509 * ロック状態で使用できるreleaseTxBuf。 00510 * この関数はiptaskで実行される関数からのみ使用してください。 00511 */ 00512 static void releaseTxBufNL(void* i_buf) 00513 { 00514 //ペイロードの位置から、メモリブロックを再生。 00515 NyLPC_iEthernetDevice_releaseTxBuf( 00516 _NyLPC_TcMiMicIpNetIf_inst->_ethif, 00517 ((struct NyLPC_TEthernetIIHeader*)i_buf)-1); 00518 return; 00519 } 00520 /** 00521 * マルチキャスとアドレスへ変換する。 00522 */ 00523 static void ip2MulticastEmacAddr(const struct NyLPC_TIPv4Addr* i_addr,struct NyLPC_TEthAddr* o_emac) 00524 { 00525 NyLPC_TUInt32 n=NyLPC_htonl(i_addr->v); 00526 o_emac->addr[0]=0x01; 00527 o_emac->addr[1]=0x00; 00528 o_emac->addr[2]=0x5E; 00529 o_emac->addr[3]=((n>>16) & 0x7f); 00530 o_emac->addr[4]=((n>> 8) & 0xff); 00531 o_emac->addr[5]=(n & 0xff); 00532 return; 00533 }; 00534 00535 /** 00536 * ペイロードをIPパケットとしてネットワークへ送出します。 00537 * コール前に、必ずロックしてから呼び出してください。 00538 * @param i_eth_payload 00539 * allocTxBufで確保したメモリを指定してください。 00540 * ペイロードには、TCP/IPパケットを格納します。 00541 */ 00542 static NyLPC_TBool sendIPv4Tx(struct TEthPacket* i_eth_buf) 00543 { 00544 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; 00545 struct NyLPC_TEthAddr emac; 00546 NyLPC_TUInt16 tx_len; 00547 const struct NyLPC_TEthAddr* eth_dest; 00548 //ペイロードのアドレスから、イーサネットフレームバッファのアドレスを復元 00549 00550 if(NyLPC_TIPv4Addr_isEqual(&(i_eth_buf->data.ipv4.destipaddr),&NyLPC_TIPv4Addr_BROADCAST)) { 00551 //ブロードキャストならそのまま 00552 eth_dest=&NyLPC_TEthAddr_BROADCAST; 00553 }else if(NyLPC_TIPv4Addr_isEqualWithMask(&(i_eth_buf->data.ipv4.destipaddr),&NyLPC_TIPv4Addr_MULTICAST,&NyLPC_TIPv4Addr_MULTICAST_MASK)){ 00554 //マルチキャスト 00555 ip2MulticastEmacAddr(&(i_eth_buf->data.ipv4.destipaddr),&emac); 00556 eth_dest=&emac; 00557 }else{ 00558 //LocalIP以外ならdefaultRootへ変換 00559 eth_dest=NyLPC_cIPv4Arp_IPv4toEthAddr( 00560 &inst->_arp, 00561 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)); 00562 //IP->MAC変換をテスト。 00563 if(eth_dest==NULL){ 00564 return NyLPC_TBool_FALSE; 00565 } 00566 } 00567 //変換可能なら、イーサネットヘッダを更新して、送信処理へ。 00568 tx_len=NyLPC_TEthernetIIHeader_setIPv4Tx(&(i_eth_buf->header),&(inst->_netinfo.current_config->eth_mac),eth_dest); 00569 NyLPC_iEthernetDevice_sendTxEthFrame(inst->_ethif,i_eth_buf,tx_len); 00570 return NyLPC_TBool_TRUE; 00571 } 00572 00573 static NyLPC_TBool isInitService(void) 00574 { 00575 return _NyLPC_TcMiMicIpNetIf_inst!=NULL; 00576 } 00577 00578 //-------------------------------------------------------------------------------- 00579 // 00580 // NetIF Interface 00581 // 00582 //-------------------------------------------------------------------------------- 00583 00584 00585 //-------------------------------------------------------------------------------- 00586 // ソケットテーブル 00587 //-------------------------------------------------------------------------------- 00588 00589 #define FLAGS_USED 0x00000001 00590 00591 struct TTcpTable 00592 { 00593 NyLPC_TUInt32 flags; 00594 NyLPC_TcMiMicIpTcpSocket_t socket; 00595 NyLPC_TUInt8 rxbuf[NyLPC_cMiMicIpNetIf_config_TCPSOCKET_RX_BUFFER_SIZE]; 00596 }; 00597 struct TUdpTable 00598 { 00599 NyLPC_TUInt32 flags; 00600 NyLPC_TcMiMicIpUdpSocket_t socket; 00601 NyLPC_TUInt8 rxbuf[NyLPC_cMiMicIpNetIf_config_UDPSOCKET_RX_BUFFER_SIZE]; 00602 }; 00603 struct TUdpNBTable 00604 { 00605 NyLPC_TUInt32 flags; 00606 NyLPC_TcMiMicIpUdpSocket_t socket; 00607 }; 00608 struct TTcpListenerTable 00609 { 00610 NyLPC_TUInt32 flags; 00611 NyLPC_TcMiMicIpTcpListener_t listener; 00612 }; 00613 00614 00615 00616 static struct TTcpTable tcp_socket_table[NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX]; 00617 static struct TUdpTable udp_socket_table[NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX]; 00618 static struct TUdpNBTable udp_socket_nb_table[NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX]; 00619 static struct TTcpListenerTable tcp_listener_table[NyLPC_cMiMicIpNetIf_config_TCPLISTENER_MAX]; 00620 00621 NyLPC_TcMiMicIpTcpListener_t* NyLPC_cMiMicIpNetIf_getListenerByPeerPort(NyLPC_TUInt16 i_port) 00622 { 00623 int i; 00624 //一致するポートを検索して、acceptをコールする。 00625 for(i=NyLPC_cMiMicIpNetIf_config_TCPLISTENER_MAX-1;i>=0;i--){ 00626 if((tcp_listener_table[i].flags&FLAGS_USED)==0){ 00627 continue; 00628 } 00629 if(tcp_listener_table[i].listener._port!=i_port){ 00630 continue; 00631 } 00632 return &tcp_listener_table[i].listener; 00633 } 00634 return NULL; 00635 } 00636 00637 /** 00638 * 指定番号のTCPポートが未使用かを返す。 00639 * @return 00640 * i_lport番のポートが未使用であればTRUE 00641 */ 00642 NyLPC_TBool NyLPC_cMiMicIpNetIf_isClosedTcpPort(NyLPC_TUInt16 i_lport) 00643 { 00644 int i; 00645 //未使用のTCPソケット? 00646 for(i=NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX-1;i>=0;i--){ 00647 if( ((tcp_socket_table[i].flags&FLAGS_USED)!=0) && 00648 (NyLPC_cMiMicIpTcpSocket_getLocalPort(&tcp_socket_table[i].socket)==i_lport)&& 00649 (!NyLPC_cMiMicIpTcpSocket_isClosed(&tcp_socket_table[i].socket))){ 00650 //ポート使用中 00651 return NyLPC_TBool_FALSE; 00652 } 00653 } 00654 for(i=NyLPC_cMiMicIpNetIf_config_TCPLISTENER_MAX-1;i>=0;i--){ 00655 if( ((tcp_listener_table[i].flags&FLAGS_USED)!=0) && 00656 (NyLPC_cMiMicIpTcpListener_getLocalPort(&tcp_listener_table[i].listener)==i_lport)){ 00657 //ポート使用中 00658 return NyLPC_TBool_FALSE; 00659 } 00660 } 00661 return NyLPC_TBool_TRUE; 00662 } 00663 00664 /** 00665 * 条件に一致する、アクティブなTCPソケットオブジェクトを取得します。 00666 * この関数は、ローカルIPが一致していると仮定して検索をします。 00667 * @param i_rip 00668 * リモートIPアドレスを指定します。 00669 */ 00670 NyLPC_TcMiMicIpTcpSocket_t* NyLPC_cMiMicIpNetIf_getMatchTcpSocket( 00671 NyLPC_TUInt16 i_lport,struct NyLPC_TIPv4Addr i_rip,NyLPC_TUInt16 i_rport) 00672 { 00673 NyLPC_TcMiMicIpTcpSocket_t* tp; 00674 int i; 00675 //一致するポートを検索 00676 for(i=NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX-1;i>=0;i--){ 00677 if((tcp_socket_table[i].flags&FLAGS_USED)==0){ 00678 continue; 00679 } 00680 if(NyLPC_cMiMicIpTcpSocket_isClosed(&tcp_socket_table[i].socket)){ 00681 continue; 00682 } 00683 tp=&tcp_socket_table[i].socket; 00684 //パラメータの一致チェック 00685 if(i_lport!=tp->uip_connr.lport || i_rport!= tp->uip_connr.rport || i_rip.v!=tp->uip_connr.ripaddr.v) 00686 { 00687 continue; 00688 } 00689 return tp; 00690 } 00691 return NULL; 00692 } 00693 NyLPC_TcMiMicIpUdpSocket_t* NyLPC_cMiMicIpNetIf_getMatchUdpSocket( 00694 NyLPC_TUInt16 i_lport) 00695 { 00696 int i; 00697 for(i=NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX-1;i>=0;i--){ 00698 if((udp_socket_table[i].flags&FLAGS_USED)==0){ 00699 continue; 00700 } 00701 if(i_lport!=udp_socket_table[i].socket.uip_udp_conn.lport){ 00702 continue; 00703 } 00704 //unicast 00705 return &udp_socket_table[i].socket; 00706 } 00707 for(i=NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX-1;i>=0;i--){ 00708 if((udp_socket_nb_table[i].flags&FLAGS_USED)==0){ 00709 continue; 00710 } 00711 if(i_lport!=udp_socket_nb_table[i].socket.uip_udp_conn.lport){ 00712 continue; 00713 } 00714 //unicast 00715 return &udp_socket_nb_table[i].socket; 00716 } 00717 return NULL; 00718 } 00719 NyLPC_TcMiMicIpUdpSocket_t* NyLPC_cMiMicIpNetIf_getMatchMulticastUdpSocket( 00720 const struct NyLPC_TIPv4Addr* i_mcast_ip, 00721 NyLPC_TUInt16 i_lport) 00722 { 00723 int i; 00724 for(i=NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX-1;i>=0;i--){ 00725 if((udp_socket_table[i].flags&FLAGS_USED)==0){ 00726 continue; 00727 } 00728 if(i_lport!=udp_socket_table[i].socket.uip_udp_conn.lport || (!NyLPC_TIPv4Addr_isEqual(i_mcast_ip,&(udp_socket_table[i].socket.uip_udp_conn.mcastaddr)))) 00729 { 00730 continue; 00731 } 00732 return &udp_socket_table[i].socket; 00733 } 00734 for(i=NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX-1;i>=0;i--){ 00735 if((udp_socket_nb_table[i].flags&FLAGS_USED)==0){ 00736 continue; 00737 } 00738 if(i_lport!=udp_socket_nb_table[i].socket.uip_udp_conn.lport || (!NyLPC_TIPv4Addr_isEqual(i_mcast_ip,&(udp_socket_nb_table[i].socket.uip_udp_conn.mcastaddr)))) 00739 { 00740 continue; 00741 } 00742 return &udp_socket_nb_table[i].socket; 00743 } 00744 return NULL; 00745 } 00746 00747 00748 void NyLPC_cMiMicIpNetIf_callPeriodic(void) 00749 { 00750 int i; 00751 for(i=NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX-1;i>=0;i--){ 00752 if((udp_socket_table[i].flags&FLAGS_USED)!=0){ 00753 NyLPC_cMiMicIpUdpSocket_periodic(&udp_socket_table[i].socket); 00754 } 00755 } 00756 for(i=NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX-1;i>=0;i--){ 00757 if((udp_socket_nb_table[i].flags&FLAGS_USED)!=0){ 00758 NyLPC_cMiMicIpUdpSocket_periodic(&udp_socket_nb_table[i].socket); 00759 } 00760 } 00761 for(i=NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX-1;i>=0;i--){ 00762 if((tcp_socket_table[i].flags&FLAGS_USED)!=0){ 00763 NyLPC_cMiMicIpTcpSocket_periodic(&tcp_socket_table[i].socket); 00764 } 00765 } 00766 } 00767 void NyLPC_cMiMicIpNetIf_callSocketStart( 00768 const NyLPC_TcIPv4Config_t* i_cfg) 00769 { 00770 int i; 00771 for(i=NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX-1;i>=0;i--){ 00772 if((udp_socket_table[i].flags&FLAGS_USED)!=0){ 00773 NyLPC_cMiMicIpUdpSocket_startService(&udp_socket_table[i].socket,i_cfg); 00774 } 00775 } 00776 for(i=NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX-1;i>=0;i--){ 00777 if((udp_socket_nb_table[i].flags&FLAGS_USED)!=0){ 00778 NyLPC_cMiMicIpUdpSocket_startService(&udp_socket_nb_table[i].socket,i_cfg); 00779 } 00780 } 00781 for(i=NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX-1;i>=0;i--){ 00782 if((tcp_socket_table[i].flags&FLAGS_USED)!=0){ 00783 NyLPC_cMiMicIpTcpSocket_startService(&tcp_socket_table[i].socket,i_cfg); 00784 } 00785 } 00786 } 00787 void NyLPC_cMiMicIpNetIf_callSocketStop(void) 00788 { 00789 int i; 00790 for(i=NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX-1;i>=0;i--){ 00791 if((udp_socket_table[i].flags&FLAGS_USED)!=0){ 00792 NyLPC_cMiMicIpUdpSocket_stopService(&udp_socket_table[i].socket); 00793 } 00794 } 00795 for(i=NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX-1;i>=0;i--){ 00796 if((udp_socket_nb_table[i].flags&FLAGS_USED)!=0){ 00797 NyLPC_cMiMicIpUdpSocket_stopService(&udp_socket_nb_table[i].socket); 00798 } 00799 } 00800 for(i=NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX-1;i>=0;i--){ 00801 if((tcp_socket_table[i].flags&FLAGS_USED)!=0){ 00802 NyLPC_cMiMicIpTcpSocket_stopService(&tcp_socket_table[i].socket); 00803 } 00804 } 00805 } 00806 00807 00808 00809 //-------------------------------------------------------------------------------- 00810 // インタフェイス関数 00811 00812 static NyLPC_TiTcpSocket_t* createTcpSocetEx(NyLPC_TSocketType i_socktype) 00813 { 00814 NyLPC_TUInt16 i; 00815 switch(i_socktype){ 00816 case NyLPC_TSocketType_TCP_HTTP: 00817 case NyLPC_TSocketType_TCP_NORMAL: 00818 //空きソケットの探索 00819 for(i=0;i<NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX;i++){ 00820 //未使用なソケットを得る 00821 if((tcp_socket_table[i].flags&FLAGS_USED)==0){ 00822 if(!NyLPC_cMiMicIpTcpSocket_initialize(&tcp_socket_table[i].socket,tcp_socket_table[i].rxbuf,NyLPC_cMiMicIpNetIf_config_TCPSOCKET_RX_BUFFER_SIZE)){ 00823 return NULL; 00824 } 00825 //ソケットを使用中に 00826 tcp_socket_table[i].flags|=FLAGS_USED; 00827 return &(tcp_socket_table[i].socket._super); 00828 } 00829 } 00830 break; 00831 default: 00832 break; 00833 } 00834 return NULL; 00835 } 00836 00837 static NyLPC_TiUdpSocket_t* createUdpSocetEx(NyLPC_TUInt16 i_port,NyLPC_TSocketType i_socktype) 00838 { 00839 NyLPC_TUInt16 i; 00840 switch(i_socktype){ 00841 case NyLPC_TSocketType_UDP_NORMAL: 00842 //空きソケットの探索 00843 for(i=0;i<NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX;i++){ 00844 //未使用なソケットを得る 00845 if((udp_socket_table[i].flags&FLAGS_USED)==0){ 00846 if(!NyLPC_cMiMicIpUdpSocket_initialize(&udp_socket_table[i].socket,i_port,udp_socket_table[i].rxbuf,NyLPC_cMiMicIpNetIf_config_UDPSOCKET_RX_BUFFER_SIZE)){ 00847 return NULL; 00848 } 00849 udp_socket_table[i].flags|=FLAGS_USED; 00850 return &(udp_socket_table[i].socket._super); 00851 } 00852 } 00853 break; 00854 case NyLPC_TSocketType_UDP_NOBUF: 00855 //空きソケットの探索 00856 for(i=0;i<NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX;i++){ 00857 //未使用なソケットを得る 00858 if((udp_socket_nb_table[i].flags&FLAGS_USED)==0){ 00859 if(!NyLPC_cMiMicIpUdpSocket_initialize(&udp_socket_nb_table[i].socket,i_port,NULL,0)){ 00860 return NULL; 00861 } 00862 udp_socket_nb_table[i].flags|=FLAGS_USED; 00863 return &(udp_socket_nb_table[i].socket._super); 00864 } 00865 } 00866 break; 00867 default: 00868 break; 00869 } 00870 return NULL; 00871 } 00872 static NyLPC_TiTcpListener_t* createTcpListener(NyLPC_TUInt16 i_port) 00873 { 00874 NyLPC_TUInt16 i; 00875 //空きソケットの探索 00876 for(i=0;i<NyLPC_cMiMicIpNetIf_config_TCPLISTENER_MAX;i++){ 00877 //未使用なソケットを得る 00878 if((tcp_listener_table[i].flags&FLAGS_USED)==0){ 00879 if(!NyLPC_cMiMicIpTcpListener_initialize(&tcp_listener_table[i].listener,i_port)){ 00880 return NULL; 00881 } 00882 //ソケットを使用中に 00883 tcp_listener_table[i].flags|=FLAGS_USED; 00884 return &(tcp_listener_table[i].listener._super); 00885 } 00886 } 00887 return NULL; 00888 } 00889 00890 00891 static const struct NyLPC_TiNetInterface_Interface _interface= 00892 { 00893 createTcpSocetEx, 00894 createUdpSocetEx, 00895 createTcpListener, 00896 NyLPC_cMiMicIpNetIf_start, 00897 NyLPC_cMiMicIpNetIf_stop, 00898 NyLPC_cMiMicIpNetIf_sendArpRequest, 00899 NyLPC_cMiMicIpNetIf_hasArpInfo, 00900 isInitService,//NyLPC_TiNetInterface_isInitService isinitservice; 00901 NyLPC_cMiMicIpNetIf_getInterfaceInfo 00902 }; 00903 //-------------------------------------------------------------------------------- 00904 // インスタンスのリリース(protected) 00905 00906 void NyLPC_cMiMicIpNetIf_releaseTcpSocketMemory(const NyLPC_TcMiMicIpTcpSocket_t* i_inst) 00907 { 00908 NyLPC_TUInt16 i; 00909 //空きソケットの探索 00910 for(i=0;i<NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX;i++){ 00911 if((&tcp_socket_table[i].socket)==i_inst){ 00912 tcp_socket_table[i].flags&=~FLAGS_USED; 00913 return; 00914 } 00915 } 00916 return; 00917 } 00918 void NyLPC_cMiMicIpNetIf_releaseUdpSocketMemory(const NyLPC_TcMiMicIpUdpSocket_t* i_inst) 00919 { 00920 NyLPC_TUInt16 i; 00921 for(i=0;i<NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX;i++){ 00922 if((&udp_socket_table[i].socket)==i_inst){ 00923 udp_socket_table[i].flags&=~FLAGS_USED; 00924 return; 00925 } 00926 } 00927 for(i=0;i<NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX;i++){ 00928 if((&udp_socket_nb_table[i].socket)==i_inst){ 00929 udp_socket_nb_table[i].flags&=~FLAGS_USED; 00930 return; 00931 } 00932 } 00933 return; 00934 } 00935 void NyLPC_cMiMicIpNetIf_releaseTcpListenerMemory(const NyLPC_TcMiMicIpTcpListener_t* i_inst) 00936 { 00937 NyLPC_TUInt16 i; 00938 //空きソケットの探索 00939 for(i=0;i<NyLPC_cMiMicIpNetIf_config_TCPLISTENER_MAX;i++){ 00940 if((&tcp_listener_table[i].listener)==i_inst){ 00941 tcp_listener_table[i].flags&=~FLAGS_USED; 00942 return; 00943 } 00944 } 00945 return; 00946 } 00947 00948 static NyLPC_TcMiMicIpNetIf_t _netif; 00949 00950 const struct NyLPC_TiNetInterface_Interface* NyLPC_cMiMicIpNetIf_getNetInterface(void) 00951 { 00952 NyLPC_cMiMicIpNetIf_initialize(&_netif); 00953 return &_interface; 00954 } 00955 00956 00957
Generated on Tue Jul 12 2022 16:22:58 by
