This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088
Dependents: MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more
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 NyLPC_cMiMicIpNetIf_sendArpRequest(&((struct NyLPC_TIPv4Header*)i_eth_payload)->destipaddr); 00412 return; 00413 } 00414 00415 00416 /** 00417 * ARPテーブルに指定したIPがあるかを返します。 00418 */ 00419 NyLPC_TBool NyLPC_cMiMicIpNetIf_hasArpInfo(const struct NyLPC_TIPv4Addr* i_addr) 00420 { 00421 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; 00422 return NyLPC_cIPv4Arp_IPv4toEthAddr(&inst->_arp,*i_addr)!=NULL; 00423 } 00424 00425 /** 00426 * システム用の送信ペイロードを返します。 00427 * 関数は必ず成功します。 00428 */ 00429 void* NyLPC_cMiMicIpNetIf_allocSysTxBuf(void) 00430 { 00431 NyLPC_TUInt16 s; 00432 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; 00433 struct TEthPacket* ethbuf; 00434 //排他処理をして、メモリを取得する。SYSTEMメモリはEthernetドライバの解放待ちのみなのでまとめてLOCKしておk 00435 NyLPC_cMutex_lock(&(inst->_mutex)); 00436 for(;;){ 00437 ethbuf=(struct TEthPacket*)NyLPC_iEthernetDevice_allocTxBuf(inst->_ethif,NyLPC_TcEthernetMM_HINT_CTRL_PACKET,&s); 00438 if(ethbuf==NULL){ 00439 NyLPC_cThread_yield(); 00440 continue; 00441 } 00442 break; 00443 } 00444 NyLPC_cMutex_unlock(&(inst->_mutex)); 00445 //イーサネットバッファのアドレスを計算 00446 return &(ethbuf->data); 00447 } 00448 00449 00450 00451 void* NyLPC_cMiMicIpNetIf_allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size) 00452 { 00453 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; 00454 struct TEthPacket* ethbuf; 00455 //排他処理をして、メモリを取得する。 00456 NyLPC_cMutex_lock(&(inst->_mutex)); 00457 ethbuf=(struct TEthPacket*)NyLPC_iEthernetDevice_allocTxBuf(inst->_ethif,i_hint+sizeof(struct NyLPC_TEthernetIIHeader),o_size); 00458 NyLPC_cMutex_unlock(&(inst->_mutex)); 00459 if(ethbuf==NULL){ 00460 return NULL; 00461 } 00462 //イーサネットバッファのサイズを計算 00463 *o_size-=sizeof(struct NyLPC_TEthernetIIHeader); 00464 //イーサネットバッファのアドレスを計算 00465 return &(ethbuf->data); 00466 } 00467 00468 00469 void* NyLPC_cMiMicIpNetIf_releaseTxBuf(void* i_buf) 00470 { 00471 //排他処理をして、メモリを開放する。 00472 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; 00473 NyLPC_cMutex_lock(&(inst->_mutex)); 00474 //ペイロードの位置から、メモリブロックを再生。 00475 NyLPC_iEthernetDevice_releaseTxBuf(inst->_ethif,((struct NyLPC_TEthernetIIHeader*)i_buf)-1); 00476 NyLPC_cMutex_unlock(&(inst->_mutex)); 00477 return NULL; 00478 } 00479 00480 00481 00482 00483 00484 00485 00486 00487 00488 /** 00489 * イーサネットフレームを送信します。 00490 * この関数はiptaskで実行される関数からのみ使用てください。 00491 * @i_buf 00492 * イーサネットフレームを格納したメモリです。 00493 * @i_len 00494 * イーサネットペイロードのサイズです。 00495 */ 00496 static void sendRawEthFrameNL(void* i_buf,NyLPC_TUInt16 i_len) 00497 { 00498 NyLPC_iEthernetDevice_sendTxEthFrame( 00499 _NyLPC_TcMiMicIpNetIf_inst->_ethif, 00500 ((struct NyLPC_TEthernetIIHeader*)i_buf)-1, 00501 i_len); 00502 return; 00503 } 00504 /** 00505 * ロック状態で使用できるreleaseTxBuf。 00506 * この関数はiptaskで実行される関数からのみ使用してください。 00507 */ 00508 static void releaseTxBufNL(void* i_buf) 00509 { 00510 //ペイロードの位置から、メモリブロックを再生。 00511 NyLPC_iEthernetDevice_releaseTxBuf( 00512 _NyLPC_TcMiMicIpNetIf_inst->_ethif, 00513 ((struct NyLPC_TEthernetIIHeader*)i_buf)-1); 00514 return; 00515 } 00516 /** 00517 * マルチキャスとアドレスへ変換する。 00518 */ 00519 static void ip2MulticastEmacAddr(const struct NyLPC_TIPv4Addr* i_addr,struct NyLPC_TEthAddr* o_emac) 00520 { 00521 NyLPC_TUInt32 n=NyLPC_htonl(i_addr->v); 00522 o_emac->addr[0]=0x01; 00523 o_emac->addr[1]=0x00; 00524 o_emac->addr[2]=0x5E; 00525 o_emac->addr[3]=((n>>16) & 0x7f); 00526 o_emac->addr[4]=((n>> 8) & 0xff); 00527 o_emac->addr[5]=(n & 0xff); 00528 return; 00529 }; 00530 00531 /** 00532 * ペイロードをIPパケットとしてネットワークへ送出します。 00533 * コール前に、必ずロックしてから呼び出してください。 00534 * @param i_eth_payload 00535 * allocTxBufで確保したメモリを指定してください。 00536 * ペイロードには、TCP/IPパケットを格納します。 00537 */ 00538 static NyLPC_TBool sendIPv4Tx(struct TEthPacket* i_eth_buf) 00539 { 00540 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst; 00541 struct NyLPC_TEthAddr emac; 00542 NyLPC_TUInt16 tx_len; 00543 const struct NyLPC_TEthAddr* eth_dest; 00544 //ペイロードのアドレスから、イーサネットフレームバッファのアドレスを復元 00545 00546 if(NyLPC_TIPv4Addr_isEqual(&(i_eth_buf->data.ipv4.destipaddr),&NyLPC_TIPv4Addr_BROADCAST)) { 00547 //ブロードキャストならそのまま 00548 eth_dest=&NyLPC_TEthAddr_BROADCAST; 00549 }else if(NyLPC_TIPv4Addr_isEqualWithMask(&(i_eth_buf->data.ipv4.destipaddr),&NyLPC_TIPv4Addr_MULTICAST,&NyLPC_TIPv4Addr_MULTICAST_MASK)){ 00550 //マルチキャスト 00551 ip2MulticastEmacAddr(&(i_eth_buf->data.ipv4.destipaddr),&emac); 00552 eth_dest=&emac; 00553 }else{ 00554 //LocalIP以外ならdefaultRootへ変換 00555 eth_dest=NyLPC_cIPv4Arp_IPv4toEthAddr( 00556 &inst->_arp, 00557 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)); 00558 //IP->MAC変換をテスト。 00559 if(eth_dest==NULL){ 00560 return NyLPC_TBool_FALSE; 00561 } 00562 } 00563 //変換可能なら、イーサネットヘッダを更新して、送信処理へ。 00564 tx_len=NyLPC_TEthernetIIHeader_setIPv4Tx(&(i_eth_buf->header),&(inst->_netinfo.current_config->eth_mac),eth_dest); 00565 NyLPC_iEthernetDevice_sendTxEthFrame(inst->_ethif,i_eth_buf,tx_len); 00566 return NyLPC_TBool_TRUE; 00567 } 00568 00569 static NyLPC_TBool isInitService(void) 00570 { 00571 return _NyLPC_TcMiMicIpNetIf_inst!=NULL; 00572 } 00573 00574 //-------------------------------------------------------------------------------- 00575 // 00576 // NetIF Interface 00577 // 00578 //-------------------------------------------------------------------------------- 00579 00580 00581 //-------------------------------------------------------------------------------- 00582 // ソケットテーブル 00583 //-------------------------------------------------------------------------------- 00584 00585 #define FLAGS_USED 0x00000001 00586 00587 struct TTcpTable 00588 { 00589 NyLPC_TUInt32 flags; 00590 NyLPC_TcMiMicIpTcpSocket_t socket; 00591 NyLPC_TUInt8 rxbuf[NyLPC_cMiMicIpNetIf_config_TCPSOCKET_RX_BUFFER_SIZE]; 00592 }; 00593 struct TUdpTable 00594 { 00595 NyLPC_TUInt32 flags; 00596 NyLPC_TcMiMicIpUdpSocket_t socket; 00597 NyLPC_TUInt8 rxbuf[NyLPC_cMiMicIpNetIf_config_UDPSOCKET_RX_BUFFER_SIZE]; 00598 }; 00599 struct TUdpNBTable 00600 { 00601 NyLPC_TUInt32 flags; 00602 NyLPC_TcMiMicIpUdpSocket_t socket; 00603 }; 00604 struct TTcpListenerTable 00605 { 00606 NyLPC_TUInt32 flags; 00607 NyLPC_TcMiMicIpTcpListener_t listener; 00608 }; 00609 00610 00611 00612 static struct TTcpTable tcp_socket_table[NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX]; 00613 static struct TUdpTable udp_socket_table[NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX]; 00614 static struct TUdpNBTable udp_socket_nb_table[NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX]; 00615 static struct TTcpListenerTable tcp_listener_table[NyLPC_cMiMicIpNetIf_config_TCPLISTENER_MAX]; 00616 00617 NyLPC_TcMiMicIpTcpListener_t* NyLPC_cMiMicIpNetIf_getListenerByPeerPort(NyLPC_TUInt16 i_port) 00618 { 00619 int i; 00620 //一致するポートを検索して、acceptをコールする。 00621 for(i=NyLPC_cMiMicIpNetIf_config_TCPLISTENER_MAX-1;i>=0;i--){ 00622 if((tcp_listener_table[i].flags&FLAGS_USED)==0){ 00623 continue; 00624 } 00625 if(tcp_listener_table[i].listener._port!=i_port){ 00626 continue; 00627 } 00628 return &tcp_listener_table[i].listener; 00629 } 00630 return NULL; 00631 } 00632 00633 /** 00634 * 指定番号のTCPポートが未使用かを返す。 00635 * @return 00636 * i_lport番のポートが未使用であればTRUE 00637 */ 00638 NyLPC_TBool NyLPC_cMiMicIpNetIf_isClosedTcpPort(NyLPC_TUInt16 i_lport) 00639 { 00640 int i; 00641 //未使用のTCPソケット? 00642 for(i=NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX-1;i>=0;i--){ 00643 if( ((tcp_socket_table[i].flags&FLAGS_USED)!=0) && 00644 (NyLPC_cMiMicIpTcpSocket_getLocalPort(&tcp_socket_table[i].socket)==i_lport)&& 00645 (!NyLPC_cMiMicIpTcpSocket_isClosed(&tcp_socket_table[i].socket))){ 00646 //ポート使用中 00647 return NyLPC_TBool_FALSE; 00648 } 00649 } 00650 for(i=NyLPC_cMiMicIpNetIf_config_TCPLISTENER_MAX-1;i>=0;i--){ 00651 if( ((tcp_listener_table[i].flags&FLAGS_USED)!=0) && 00652 (NyLPC_cMiMicIpTcpListener_getLocalPort(&tcp_listener_table[i].listener)==i_lport)){ 00653 //ポート使用中 00654 return NyLPC_TBool_FALSE; 00655 } 00656 } 00657 return NyLPC_TBool_TRUE; 00658 } 00659 00660 /** 00661 * 条件に一致する、アクティブなTCPソケットオブジェクトを取得します。 00662 * この関数は、ローカルIPが一致していると仮定して検索をします。 00663 * @param i_rip 00664 * リモートIPアドレスを指定します。 00665 */ 00666 NyLPC_TcMiMicIpTcpSocket_t* NyLPC_cMiMicIpNetIf_getMatchTcpSocket( 00667 NyLPC_TUInt16 i_lport,struct NyLPC_TIPv4Addr i_rip,NyLPC_TUInt16 i_rport) 00668 { 00669 NyLPC_TcMiMicIpTcpSocket_t* tp; 00670 int i; 00671 //一致するポートを検索 00672 for(i=NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX-1;i>=0;i--){ 00673 if((tcp_socket_table[i].flags&FLAGS_USED)==0){ 00674 continue; 00675 } 00676 if(NyLPC_cMiMicIpTcpSocket_isClosed(&tcp_socket_table[i].socket)){ 00677 continue; 00678 } 00679 tp=&tcp_socket_table[i].socket; 00680 //パラメータの一致チェック 00681 if(i_lport!=tp->uip_connr.lport || i_rport!= tp->uip_connr.rport || i_rip.v!=tp->uip_connr.ripaddr.v) 00682 { 00683 continue; 00684 } 00685 return tp; 00686 } 00687 return NULL; 00688 } 00689 NyLPC_TcMiMicIpUdpSocket_t* NyLPC_cMiMicIpNetIf_getMatchUdpSocket( 00690 NyLPC_TUInt16 i_lport) 00691 { 00692 int i; 00693 for(i=NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX-1;i>=0;i--){ 00694 if((udp_socket_table[i].flags&FLAGS_USED)==0){ 00695 continue; 00696 } 00697 if(i_lport!=udp_socket_table[i].socket.uip_udp_conn.lport){ 00698 continue; 00699 } 00700 //unicast 00701 return &udp_socket_table[i].socket; 00702 } 00703 for(i=NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX-1;i>=0;i--){ 00704 if((udp_socket_nb_table[i].flags&FLAGS_USED)==0){ 00705 continue; 00706 } 00707 if(i_lport!=udp_socket_nb_table[i].socket.uip_udp_conn.lport){ 00708 continue; 00709 } 00710 //unicast 00711 return &udp_socket_nb_table[i].socket; 00712 } 00713 return NULL; 00714 } 00715 NyLPC_TcMiMicIpUdpSocket_t* NyLPC_cMiMicIpNetIf_getMatchMulticastUdpSocket( 00716 const struct NyLPC_TIPv4Addr* i_mcast_ip, 00717 NyLPC_TUInt16 i_lport) 00718 { 00719 int i; 00720 for(i=NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX-1;i>=0;i--){ 00721 if((udp_socket_table[i].flags&FLAGS_USED)==0){ 00722 continue; 00723 } 00724 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)))) 00725 { 00726 continue; 00727 } 00728 return &udp_socket_table[i].socket; 00729 } 00730 for(i=NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX-1;i>=0;i--){ 00731 if((udp_socket_nb_table[i].flags&FLAGS_USED)==0){ 00732 continue; 00733 } 00734 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)))) 00735 { 00736 continue; 00737 } 00738 return &udp_socket_nb_table[i].socket; 00739 } 00740 return NULL; 00741 } 00742 00743 00744 void NyLPC_cMiMicIpNetIf_callPeriodic(void) 00745 { 00746 int i; 00747 for(i=NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX-1;i>=0;i--){ 00748 if((udp_socket_table[i].flags&FLAGS_USED)!=0){ 00749 NyLPC_cMiMicIpUdpSocket_periodic(&udp_socket_table[i].socket); 00750 } 00751 } 00752 for(i=NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX-1;i>=0;i--){ 00753 if((udp_socket_nb_table[i].flags&FLAGS_USED)!=0){ 00754 NyLPC_cMiMicIpUdpSocket_periodic(&udp_socket_nb_table[i].socket); 00755 } 00756 } 00757 for(i=NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX-1;i>=0;i--){ 00758 if((tcp_socket_table[i].flags&FLAGS_USED)!=0){ 00759 NyLPC_cMiMicIpTcpSocket_periodic(&tcp_socket_table[i].socket); 00760 } 00761 } 00762 } 00763 void NyLPC_cMiMicIpNetIf_callSocketStart( 00764 const NyLPC_TcIPv4Config_t* i_cfg) 00765 { 00766 int i; 00767 for(i=NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX-1;i>=0;i--){ 00768 if((udp_socket_table[i].flags&FLAGS_USED)!=0){ 00769 NyLPC_cMiMicIpUdpSocket_startService(&udp_socket_table[i].socket,i_cfg); 00770 } 00771 } 00772 for(i=NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX-1;i>=0;i--){ 00773 if((udp_socket_nb_table[i].flags&FLAGS_USED)!=0){ 00774 NyLPC_cMiMicIpUdpSocket_startService(&udp_socket_nb_table[i].socket,i_cfg); 00775 } 00776 } 00777 for(i=NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX-1;i>=0;i--){ 00778 if((tcp_socket_table[i].flags&FLAGS_USED)!=0){ 00779 NyLPC_cMiMicIpTcpSocket_startService(&tcp_socket_table[i].socket,i_cfg); 00780 } 00781 } 00782 } 00783 void NyLPC_cMiMicIpNetIf_callSocketStop(void) 00784 { 00785 int i; 00786 for(i=NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX-1;i>=0;i--){ 00787 if((udp_socket_table[i].flags&FLAGS_USED)!=0){ 00788 NyLPC_cMiMicIpUdpSocket_stopService(&udp_socket_table[i].socket); 00789 } 00790 } 00791 for(i=NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX-1;i>=0;i--){ 00792 if((udp_socket_nb_table[i].flags&FLAGS_USED)!=0){ 00793 NyLPC_cMiMicIpUdpSocket_stopService(&udp_socket_nb_table[i].socket); 00794 } 00795 } 00796 for(i=NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX-1;i>=0;i--){ 00797 if((tcp_socket_table[i].flags&FLAGS_USED)!=0){ 00798 NyLPC_cMiMicIpTcpSocket_stopService(&tcp_socket_table[i].socket); 00799 } 00800 } 00801 } 00802 00803 00804 00805 //-------------------------------------------------------------------------------- 00806 // インタフェイス関数 00807 00808 static NyLPC_TiTcpSocket_t* createTcpSocetEx(NyLPC_TSocketType i_socktype) 00809 { 00810 NyLPC_TUInt16 i; 00811 switch(i_socktype){ 00812 case NyLPC_TSocketType_TCP_HTTP: 00813 case NyLPC_TSocketType_TCP_NORMAL: 00814 //空きソケットの探索 00815 for(i=0;i<NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX;i++){ 00816 //未使用なソケットを得る 00817 if((tcp_socket_table[i].flags&FLAGS_USED)==0){ 00818 if(!NyLPC_cMiMicIpTcpSocket_initialize(&tcp_socket_table[i].socket,tcp_socket_table[i].rxbuf,NyLPC_cMiMicIpNetIf_config_TCPSOCKET_RX_BUFFER_SIZE)){ 00819 return NULL; 00820 } 00821 //ソケットを使用中に 00822 tcp_socket_table[i].flags|=FLAGS_USED; 00823 return &(tcp_socket_table[i].socket._super); 00824 } 00825 } 00826 break; 00827 default: 00828 break; 00829 } 00830 return NULL; 00831 } 00832 00833 static NyLPC_TiUdpSocket_t* createUdpSocetEx(NyLPC_TUInt16 i_port,NyLPC_TSocketType i_socktype) 00834 { 00835 NyLPC_TUInt16 i; 00836 switch(i_socktype){ 00837 case NyLPC_TSocketType_UDP_NORMAL: 00838 //空きソケットの探索 00839 for(i=0;i<NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX;i++){ 00840 //未使用なソケットを得る 00841 if((udp_socket_table[i].flags&FLAGS_USED)==0){ 00842 if(!NyLPC_cMiMicIpUdpSocket_initialize(&udp_socket_table[i].socket,i_port,udp_socket_table[i].rxbuf,NyLPC_cMiMicIpNetIf_config_UDPSOCKET_RX_BUFFER_SIZE)){ 00843 return NULL; 00844 } 00845 udp_socket_table[i].flags|=FLAGS_USED; 00846 return &(udp_socket_table[i].socket._super); 00847 } 00848 } 00849 break; 00850 case NyLPC_TSocketType_UDP_NOBUF: 00851 //空きソケットの探索 00852 for(i=0;i<NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX;i++){ 00853 //未使用なソケットを得る 00854 if((udp_socket_nb_table[i].flags&FLAGS_USED)==0){ 00855 if(!NyLPC_cMiMicIpUdpSocket_initialize(&udp_socket_nb_table[i].socket,i_port,NULL,0)){ 00856 return NULL; 00857 } 00858 udp_socket_nb_table[i].flags|=FLAGS_USED; 00859 return &(udp_socket_nb_table[i].socket._super); 00860 } 00861 } 00862 break; 00863 default: 00864 break; 00865 } 00866 return NULL; 00867 } 00868 static NyLPC_TiTcpListener_t* createTcpListener(NyLPC_TUInt16 i_port) 00869 { 00870 NyLPC_TUInt16 i; 00871 //空きソケットの探索 00872 for(i=0;i<NyLPC_cMiMicIpNetIf_config_TCPLISTENER_MAX;i++){ 00873 //未使用なソケットを得る 00874 if((tcp_listener_table[i].flags&FLAGS_USED)==0){ 00875 if(!NyLPC_cMiMicIpTcpListener_initialize(&tcp_listener_table[i].listener,i_port)){ 00876 return NULL; 00877 } 00878 //ソケットを使用中に 00879 tcp_listener_table[i].flags|=FLAGS_USED; 00880 return &(tcp_listener_table[i].listener._super); 00881 } 00882 } 00883 return NULL; 00884 } 00885 00886 00887 static const struct NyLPC_TiNetInterface_Interface _interface= 00888 { 00889 createTcpSocetEx, 00890 createUdpSocetEx, 00891 createTcpListener, 00892 NyLPC_cMiMicIpNetIf_start, 00893 NyLPC_cMiMicIpNetIf_stop, 00894 NyLPC_cMiMicIpNetIf_sendArpRequest, 00895 NyLPC_cMiMicIpNetIf_hasArpInfo, 00896 isInitService,//NyLPC_TiNetInterface_isInitService isinitservice; 00897 NyLPC_cMiMicIpNetIf_getInterfaceInfo 00898 }; 00899 //-------------------------------------------------------------------------------- 00900 // インスタンスのリリース(protected) 00901 00902 void NyLPC_cMiMicIpNetIf_releaseTcpSocketMemory(const NyLPC_TcMiMicIpTcpSocket_t* i_inst) 00903 { 00904 NyLPC_TUInt16 i; 00905 //空きソケットの探索 00906 for(i=0;i<NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX;i++){ 00907 if((&tcp_socket_table[i].socket)==i_inst){ 00908 tcp_socket_table[i].flags&=~FLAGS_USED; 00909 return; 00910 } 00911 } 00912 return; 00913 } 00914 void NyLPC_cMiMicIpNetIf_releaseUdpSocketMemory(const NyLPC_TcMiMicIpUdpSocket_t* i_inst) 00915 { 00916 NyLPC_TUInt16 i; 00917 for(i=0;i<NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX;i++){ 00918 if((&udp_socket_table[i].socket)==i_inst){ 00919 udp_socket_table[i].flags&=~FLAGS_USED; 00920 return; 00921 } 00922 } 00923 for(i=0;i<NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX;i++){ 00924 if((&udp_socket_nb_table[i].socket)==i_inst){ 00925 udp_socket_nb_table[i].flags&=~FLAGS_USED; 00926 return; 00927 } 00928 } 00929 return; 00930 } 00931 void NyLPC_cMiMicIpNetIf_releaseTcpListenerMemory(const NyLPC_TcMiMicIpTcpListener_t* i_inst) 00932 { 00933 NyLPC_TUInt16 i; 00934 //空きソケットの探索 00935 for(i=0;i<NyLPC_cMiMicIpNetIf_config_TCPLISTENER_MAX;i++){ 00936 if((&tcp_listener_table[i].listener)==i_inst){ 00937 tcp_listener_table[i].flags&=~FLAGS_USED; 00938 return; 00939 } 00940 } 00941 return; 00942 } 00943 00944 static NyLPC_TcMiMicIpNetIf_t _netif; 00945 00946 const struct NyLPC_TiNetInterface_Interface* NyLPC_cMiMicIpNetIf_getNetInterface(void) 00947 { 00948 NyLPC_cMiMicIpNetIf_initialize(&_netif); 00949 return &_interface; 00950 } 00951 00952 00953
Generated on Tue Jul 12 2022 15:46:16 by 1.7.2