1 /*********************************************************************************
\r
3 * --------------------------------------------------------------------------------
\r
5 * This file is part of MiMic
\r
6 * Copyright (C)2011 Ryo Iizuka
\r
8 * MiMic is free software: you can redistribute it and/or modify
\r
9 * it under the terms of the GNU Lesser General Public License as published
\r
10 * by the Free Software Foundation, either version 3 of the License, or
\r
11 * (at your option) any later version.
\r
13 * This program is distributed in the hope that it will be useful,
\r
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
16 * GNU General Public License for more details.
\r
18 * You should have received a copy of the GNU Lesser General Public License
\r
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
\r
21 * For further information please contact.
\r
23 * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
\r
26 * Parts of this file were leveraged from uIP:
\r
28 * Copyright (c) 2001-2003, Adam Dunkels.
\r
29 * All rights reserved.
\r
31 * Redistribution and use in source and binary forms, with or without
\r
32 * modification, are permitted provided that the following conditions
\r
34 * 1. Redistributions of source code must retain the above copyright
\r
35 * notice, this list of conditions and the following disclaimer.
\r
36 * 2. Redistributions in binary form must reproduce the above copyright
\r
37 * notice, this list of conditions and the following disclaimer in the
\r
38 * documentation and/or other materials provided with the distribution.
\r
39 * 3. The name of the author may not be used to endorse or promote
\r
40 * products derived from this software without specific prior
\r
41 * written permission.
\r
43 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
\r
44 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
\r
45 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
\r
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
\r
47 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\r
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
\r
49 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
\r
50 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
\r
51 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
\r
52 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
\r
53 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
55 #include "NyLPC_cIPv4IComp_protected.h"
\r
56 #include "NyLPC_cTcpListener_protected.h"
\r
57 #include "NyLPC_stdlib.h"
\r
58 #include "NyLPC_uip.h"
\r
64 /****************************************************
\r
65 * UipServiceに関する宣言:タスクメッセージ
\r
66 ***************************************************/
\r
68 #define TTaskMsg_NOP 0
\r
69 #define TTaskMsg_START 1
\r
70 #define TTaskMsg_STOP 2
\r
79 const NyLPC_TcIPv4Config_t* ref_config;
\r
84 /****************************************************
\r
85 * UipServiceに関する宣言:その他
\r
86 ***************************************************/
\r
88 * イーサネットフレームの読み出し構造体
\r
92 struct NyLPC_TEthernetIIHeader header;
\r
94 struct NyLPC_TArpHeader arp;
\r
95 struct NyLPC_TIPv4Header ipv4;
\r
102 * サービスインスタンスのポインタ。サービスが稼働中はインスタンスのポインタが有効です。
104 NyLPC_TcUipService_t* _NyLPC_TcUipService_inst=NULL;
\r
109 static NyLPC_TcUipService_t _service_instance;
\r
117 static int uipTask(void *pvParameters);
\r
119 //--------------------------------------------------------------
\r
122 static NyLPC_TBool sendIPv4Tx(struct NyLPC_TTxBufferHeader* i_eth_buf);
\r
123 static void copyAndSendIPv4Tx(const struct TEthPacket* i_buf);
\r
124 static void sendArpReqest(const struct TEthPacket* i_eth_packet);
\r
125 static void sendRawEthFrame(void* i_buf,NyLPC_TUInt16 i_len);
\r
126 static void emacIsrHandler(unsigned long i_status);
\r
129 #define TTaskMessage_MSG_NULL 0x0000
\r
130 /**uipコアタスクに、開始要求する*/
\r
131 #define TTaskMessage_MSG_RUN 0x0001
\r
132 /**uipコアタスクに、停止要求する*/
\r
133 #define TTaskMessage_MSG_STOP 0x0002
\r
136 NyLPC_TcThread_t th;
\r
138 NyLPC_TBool NyLPC_cUipService_initialize(void)
\r
140 NyLPC_TcUipService_t* inst=&_service_instance;
\r
141 //サービスは停止している事。 - Service must be uninitialized.
\r
142 NyLPC_Assert(!NyLPC_TcUipService_isInitService());
\r
144 NyLPC_cIPv4_initialize(&(inst->_tcpv4));
\r
146 NyLPC_cIsr_setEnetISR(emacIsrHandler);
\r
148 NyLPC_cSemaphore_initialize(&inst->_emac_semapho);
\r
150 inst->_task_cmd=NULL;
\r
151 inst->_status=NyLPC_TcUipService_STATUS_STOP;
\r
152 NyLPC_cStopwatch_initialize(&(inst->_arp_sw));
\r
153 NyLPC_cStopwatch_initialize(&(inst->_periodic_sw));
\r
154 NyLPC_cIPv4_initialize(&(inst->_tcpv4));
\r
155 NyLPC_AbortIfNot(NyLPC_cMutex_initialize(&(inst->_mutex)));
\r
157 _NyLPC_TcUipService_inst=inst;
\r
158 inst->stx.h.is_lock=NyLPC_TUInt8_FALSE;
\r
161 NyLPC_cThread_initialize(&th,NyLPC_TcUipService_config_STACK_SIZE,NyLPC_TcThread_PRIORITY_SERVICE);
\r
162 NyLPC_cThread_start(&th,uipTask,NULL);
\r
163 return NyLPC_TBool_TRUE;
\r
174 * この関数はリエントラントではありません。複数のタスクから共有するときには、排他ロックを掛けてください。
\r
175 * @param i_ref_config
\r
176 * このコンフィギュレーションは、stopを実行するまでの間、インスタンスから参照します。外部で保持してください。
\r
178 void NyLPC_cUipService_start(const NyLPC_TcIPv4Config_t* i_ref_config)
\r
180 NyLPC_TcUipService_t* inst=&_service_instance;
\r
181 struct TTaskMsg msg;
\r
182 NyLPC_Assert(NyLPC_TcUipService_isInitService());
\r
183 if(!NyLPC_cUipService_isRun())
\r
185 //はじめて起動するときに1度だけデバイス取得(タスクスイッチが動いてないと動かないからここで。)
\r
186 if(inst->_ethif==NULL){
\r
187 inst->_ethif=getEthernetDevicePnP();
\r
190 msg.msg=TTaskMsg_START;
\r
191 msg.start.ref_config=i_ref_config;
\r
192 _NyLPC_TcUipService_inst->_task_cmd=&msg;
\r
194 while(!NyLPC_cUipService_isRun()){
\r
195 NyLPC_cThread_sleep(10);
\r
199 _NyLPC_TcUipService_inst->_task_cmd=NULL;
\r
204 * この関数はリエントラントではありません。複数のタスクから共有するときには、排他ロックを掛けてください。
\r
205 * いまのところ、ストップシーケンスの実装は良くありません。
\r
208 void NyLPC_cUipService_stop(void)
\r
210 struct TTaskMsg msg;
\r
211 NyLPC_TcUipService_t* inst=&_service_instance;
\r
212 NyLPC_Assert(NyLPC_TcUipService_isInitService());
\r
213 if(NyLPC_cUipService_isRun())
\r
216 msg.msg=TTaskMsg_STOP;
\r
217 _NyLPC_TcUipService_inst->_task_cmd=&msg;
\r
219 while(NyLPC_cUipService_isRun()){
\r
220 NyLPC_cThread_sleep(10);
\r
222 NyLPC_cIPv4_stop(&(inst->_tcpv4));
\r
226 _NyLPC_TcUipService_inst->_task_cmd=NULL;
\r
231 const char* NyLPC_cUipService_refDeviceName(void)
\r
233 NyLPC_TcUipService_t* inst=&_service_instance;
\r
234 return NyLPC_cUipService_isRun()?inst->_ethif->device_name:NULL;
\r
236 const NyLPC_TcIPv4Config_t* NyLPC_cUipService_refCurrentConfig(void)
\r
238 NyLPC_TcUipService_t* inst=&_service_instance;
\r
239 return inst->_ref_config;
\r
241 /**********************************************************************
\r
243 * </HWコールバックに関わる宣言>
\r
245 *********************************************************************/
\r
250 static void emacIsrHandler(unsigned long i_status)
\r
252 NyLPC_TcUipService_t* inst=&_service_instance;
\r
254 if( i_status & INT_RX_DONE )
\r
257 NyLPC_cSemaphore_giveFromISR(&inst->_emac_semapho);
\r
259 if( i_status & INT_TX_DONE )
\r
266 #define PERIODIC_TIMER (1*200)
\r
267 #define ARP_TIMER (60*1000*10)
\r
272 * 操作キューを確認して、タスクのステータスをアップデートします。
\r
273 * 高速化のため、Proc-Callerを使用していません。複雑なタスク操作をするときには、書き換えてください。
275 static void updateTaskStatus()
\r
277 NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
\r
279 struct TTaskMsg* msg=(struct TTaskMsg*)(inst->_task_cmd);
\r
281 //コマンドが設定されていない時は、何もしない。
\r
291 case TTaskMsg_START:
\r
293 if(NyLPC_cUipService_isRun()){
\r
296 inst->_ref_config=msg->start.ref_config;
\r
298 NyLPC_cIPv4_start(&(inst->_tcpv4),inst->_ref_config);
\r
299 NyLPC_cIPv4IComp_initialize(&(inst->_icomp),inst->_ref_config);
\r
300 //uip_arp_init(msg->start.ref_config);
\r
301 NyLPC_cIPv4Arp_initialize(&(inst->_arp),inst->_ref_config);
\r
302 NyLPC_cStopwatch_startExpire(&(inst->_arp_sw),1);//1度ARPを起動するため。
\r
303 NyLPC_cStopwatch_startExpire(&(inst->_periodic_sw),PERIODIC_TIMER);
\r
304 while(!inst->_ethif->start(&(inst->_ref_config->eth_mac)));
\r
305 inst->_status=NyLPC_TcUipService_STATUS_RUN;
\r
308 case TTaskMsg_STOP:
\r
310 if(!NyLPC_cUipService_isRun()){
\r
314 inst->_ethif->stop();
\r
315 NyLPC_cIPv4_stop(&(inst->_tcpv4));
\r
316 NyLPC_cIPv4IComp_finalize(&(inst->_icomp));
\r
317 NyLPC_cIPv4Arp_finalize(&(inst->_arp));
\r
318 inst->_status=NyLPC_TcUipService_STATUS_STOP;
\r
325 inst->_task_cmd=TTaskMsg_NOP;
\r
332 static int uipTask(void *pvParameters)
\r
334 NyLPC_TUInt16 rx_len,tx_len;
\r
335 struct TEthPacket* ethbuf;
\r
336 NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
\r
338 (void)pvParameters;
\r
342 updateTaskStatus();
\r
343 if(inst->_status!=NyLPC_TcUipService_STATUS_RUN)
\r
345 //RUNステータス以外の時は、ここで終了する。
\r
346 NyLPC_cThread_sleep(50);
\r
350 //Ethernet Device Lock(ARPを含む)
\r
351 NyLPC_cMutex_lock(&(inst->_mutex));
\r
352 ethbuf= (struct TEthPacket*)inst->_ethif->getRxEthFrame(&rx_len);
\r
354 while(ethbuf != NULL){
\r
358 rx_len-=sizeof(struct NyLPC_TEthernetIIHeader);
\r
359 switch(ethbuf->header.type)
\r
361 case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_IP):
\r
363 //uip_arp_ipin(&(ethbuf->header),ethbuf->data.ipv4.srcipaddr);
\r
364 NyLPC_cIPv4Arp_incomingIp(&inst->_arp,&(ethbuf->header),ethbuf->data.ipv4.srcipaddr);
\r
365 //Ethernet Device UnLock(パケット解析の為に一時的な解除)
\r
366 NyLPC_cMutex_unlock(&(inst->_mutex));
\r
368 r=NyLPC_cIPv4_rx(&(inst->_tcpv4),&(ethbuf->data.ipv4),rx_len);
\r
370 NyLPC_cMutex_lock(&(inst->_mutex));
\r
375 //IPパケットをTxバッファに転写して送信
\r
376 copyAndSendIPv4Tx(ethbuf);
\r
379 case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_ARP):
\r
380 //if(uip_arp_arpin(&(ethbuf->data.arp),rx_len)){
\r
381 if(NyLPC_cIPv4Arp_incomingArp(&inst->_arp,&(ethbuf->data.arp),rx_len)){
\r
382 tx_len=NyLPC_TEthernetIIHeader_setArpTx(&(ethbuf->header),&(inst->_ref_config->eth_mac));
\r
385 sendRawEthFrame(ethbuf,tx_len);
\r
388 case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_IPV6):
\r
389 //uip_process_ipv6();
\r
396 inst->_ethif->nextRxEthFrame();
\r
398 ethbuf= (struct TEthPacket*)inst->_ethif->getRxEthFrame(&rx_len);
\r
401 if(NyLPC_cStopwatch_isExpired(&(inst->_arp_sw))){
\r
403 NyLPC_cIPv4Arp_periodic(&inst->_arp);
\r
404 NyLPC_cStopwatch_startExpire(&(inst->_arp_sw),ARP_TIMER);
\r
406 if(NyLPC_cStopwatch_isExpired(&(inst->_periodic_sw))){
\r
407 NyLPC_cIPv4_periodec(&(inst->_tcpv4));
\r
408 NyLPC_cStopwatch_startExpire(&(inst->_periodic_sw),PERIODIC_TIMER);
\r
411 NyLPC_cMutex_unlock(&(inst->_mutex));
\r
412 //割込によるセマフォの解除か、タイムアウトで再開する。(タイムアウト値は周期関数の実行レート以下にすること。)
\r
413 NyLPC_cSemaphore_take(&(_NyLPC_TcUipService_inst->_emac_semapho),PERIODIC_TIMER);
\r
422 * allocTxBufで取得したメモリを"IPパケットとして"送信します。
\r
423 * @param i_eth_payload
\r
424 * [NyLPC_TTxBufferHeader][NyLPC_TEthernetIIHeader][payload]メモリの、[payload]のアドレスを指定します。
\r
425 * 通常は、NyLPC_cUipService_allocTxBufの返却したメモリを指定します。
\r
428 void NyLPC_cUipService_sendIPv4Tx(void* i_eth_payload)
\r
430 NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
\r
431 NyLPC_cMutex_lock(&(inst->_mutex));
\r
433 if(!sendIPv4Tx(((struct NyLPC_TTxBufferHeader*)(((struct NyLPC_TEthernetIIHeader*)i_eth_payload)-1))-1)){
\r
435 sendArpReqest(((struct TEthPacket*)i_eth_payload)-1);
\r
437 NyLPC_cMutex_unlock(&(inst->_mutex));
\r
441 * 指定したIPアドレスに対してARPRequestを送信します。
\r
443 void NyLPC_cUipService_sendArpRequest(const struct NyLPC_TIPv4Addr* i_addr)
\r
446 struct TEthPacket* ethbuf;
\r
448 NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
\r
449 NyLPC_TUInt16 tx_len;
\r
451 buf=NyLPC_cUipService_allocTxBuf(64,&s);
\r
452 NyLPC_cThread_sleep(10);
\r
454 //IPパケットのアドレスをイーサネットパケットアドレスまで後退させる。
\r
455 ethbuf=(struct TEthPacket*)(((struct NyLPC_TEthernetIIHeader*)buf)-1);
\r
457 NyLPC_TArpHeader_setArpRequest(&(ethbuf->data.arp),inst->_ref_config->ip_addr,&(inst->_ref_config->eth_mac),*i_addr);
\r
458 tx_len=NyLPC_TEthernetIIHeader_setArpTx(&(ethbuf->header),&(inst->_ref_config->eth_mac));
\r
460 NyLPC_cMutex_lock(&(inst->_mutex));
\r
461 inst->_ethif->sendTxEthFrame(((struct NyLPC_TTxBufferHeader*)ethbuf)-1,tx_len);
\r
462 NyLPC_cMutex_unlock(&(inst->_mutex));
\r
467 * ARPテーブルに指定したIPがあるかを返します。
\r
469 NyLPC_TBool NyLPC_cUipService_hasArpInfo(const struct NyLPC_TIPv4Addr* i_addr)
\r
471 NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
\r
472 return NyLPC_cIPv4Arp_IPv4toEthAddr(&inst->_arp,*i_addr)!=NULL;
\r
478 * この関数は、リエントラントを許容します。
\r
480 * 取得したいメモリサイズを指定します。(このサイズは、イーサネットヘッダのサイズを含みません。)
\r
481 * このサイズよりも小さなサイズが割り当てられることがあります。
\r
483 * イーサネットヘッダを除いたペイロード部分の長さ
\r
485 * 成功:IPペイロードのためのメモリブロックを返します。/失敗:NULL
\r
486 * 返されるメモリはブロックの[TEthPacket][payload]の構造で、[payload]のアドレスが返されます。
488 void* NyLPC_cUipService_allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size)
\r
490 NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
\r
491 struct NyLPC_TTxBufferHeader* ethbuf;
\r
492 //排他処理をして、メモリを取得する。
\r
493 NyLPC_cMutex_lock(&(inst->_mutex));
\r
494 ethbuf=(struct NyLPC_TTxBufferHeader*)inst->_ethif->allocTxBuf(i_hint+sizeof(struct NyLPC_TEthernetIIHeader),o_size);
\r
495 NyLPC_cMutex_unlock(&(inst->_mutex));
\r
499 //イーサネットバッファのサイズを計算
\r
500 *o_size-=sizeof(struct NyLPC_TEthernetIIHeader);
\r
501 //イーサネットバッファのアドレスを計算
\r
502 return &(((struct TEthPacket*)(ethbuf+1))->data);
\r
506 void* NyLPC_cUipService_releaseTxBuf(void* i_buf)
\r
508 //排他処理をして、メモリを開放する。
\r
509 NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
\r
510 NyLPC_cMutex_lock(&(inst->_mutex));
\r
511 //ペイロードの位置から、メモリブロックを再生。
\r
512 inst->_ethif->releaseTxBuf(((struct NyLPC_TTxBufferHeader*)(((struct NyLPC_TEthernetIIHeader*)i_buf)-1))-1);
\r
513 NyLPC_cMutex_unlock(&(inst->_mutex));
\r
525 * イーサネットHWのコントロール関数
\r
529 * 新たにメモリを確保して、"IPv4パケットを格納した"イーサフレームを送信します。
\r
530 * コール前に、必ずロックしてから呼び出してください。
\r
532 static void copyAndSendIPv4Tx(const struct TEthPacket* i_buf)
\r
534 NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
\r
536 //ACK送信用の自己バッファが空くまで待つ
\r
537 while(inst->stx.h.is_lock){
\r
538 inst->_ethif->processTx();
\r
541 s=NyLPC_htons(i_buf->data.ipv4.len16)+sizeof(struct NyLPC_TEthernetIIHeader);
\r
542 memcpy(inst->stx.buf,i_buf,s);
\r
543 if(!sendIPv4Tx(&(inst->stx.h))){
\r
544 //失敗した場合はARPリクエストに変換して再送
\r
545 sendArpReqest(i_buf);
\r
550 * IPv4パケットのpeerIPを問い合わせるARPパケットを送信します。
\r
552 static void sendArpReqest(const struct TEthPacket* i_eth_packet)
\r
554 NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
\r
555 NyLPC_TUInt16 tx_len;
\r
556 struct TEthPacket* ethbuf;
\r
557 //ACK送信用の自己バッファが空くまで待つ
\r
558 while(inst->stx.h.is_lock){
\r
559 inst->_ethif->processTx();
\r
562 ethbuf=(struct TEthPacket*)(inst->stx.buf);
\r
563 NyLPC_TArpHeader_setArpRequest(&(ethbuf->data.arp),inst->_ref_config->ip_addr,&(inst->_ref_config->eth_mac),i_eth_packet->data.ipv4.destipaddr);
\r
564 tx_len=NyLPC_TEthernetIIHeader_setArpTx(&(ethbuf->header),&(inst->_ref_config->eth_mac));
\r
566 inst->_ethif->sendTxEthFrame(&(inst->stx.h),tx_len);
\r
570 * uipタスクが所有するTXバッファを使用してデータを送信します。
\r
571 * この関数は、i_bufをコピーします。
\r
573 * イーサネットフレームを格納したメモリです。
\r
575 * イーサネットペイロードのサイズです。
\r
577 static void sendRawEthFrame(void* i_buf,NyLPC_TUInt16 i_len)
\r
579 NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
\r
581 //ACK送信用の自己バッファが空くまで待つ
\r
582 while(inst->stx.h.is_lock){
\r
583 inst->_ethif->processTx();
\r
585 //64バイトを超えるとかありえない。
\r
586 if(i_len+sizeof(struct NyLPC_TEthernetIIHeader)>NyLPC_TcUipService_SIZE_OF_REPLY_BUF){
\r
590 memcpy(inst->stx.buf,i_buf,i_len);
\r
591 inst->_ethif->sendTxEthFrame(&(inst->stx.h),i_len);
\r
596 * マルチキャスとアドレスへ変換する。
\r
598 static void ip2MulticastEmacAddr(const struct NyLPC_TIPv4Addr* i_addr,struct NyLPC_TEthAddr* o_emac)
\r
600 NyLPC_TUInt32 n=NyLPC_htonl(i_addr->v);
\r
601 o_emac->addr[0]=0x01;
\r
602 o_emac->addr[1]=0x00;
\r
603 o_emac->addr[2]=0x5E;
\r
604 o_emac->addr[3]=((n>>16) & 0x7f);
\r
605 o_emac->addr[4]=((n>> 8) & 0xff);
\r
606 o_emac->addr[5]=(n & 0xff);
\r
611 * ペイロードをIPパケットとしてネットワークへ送出します。
\r
612 * コール前に、必ずロックしてから呼び出してください。
\r
613 * @param i_eth_payload
\r
614 * allocTxBufで確保したメモリを指定してください。
\r
615 * ペイロードには、TCP/IPパケットを格納します。
\r
617 static NyLPC_TBool sendIPv4Tx(struct NyLPC_TTxBufferHeader* i_eth_buf)
\r
619 NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
\r
620 struct NyLPC_TEthAddr emac;
\r
621 NyLPC_TUInt16 tx_len;
\r
622 const struct NyLPC_TEthAddr* eth_dest;
\r
623 struct TEthPacket* ethbuf=(struct TEthPacket*)(i_eth_buf+1);
\r
624 //ペイロードのアドレスから、イーサネットフレームバッファのアドレスを復元
\r
626 if(NyLPC_TIPv4Addr_isEqual(&(ethbuf->data.ipv4.destipaddr),&NyLPC_TIPv4Addr_BROADCAST)) {
\r
628 eth_dest=&NyLPC_TEthAddr_BROADCAST;
\r
629 }else if(NyLPC_TIPv4Addr_isEqualWithMask(&(ethbuf->data.ipv4.destipaddr),&NyLPC_TIPv4Addr_MULTICAST,&NyLPC_TIPv4Addr_MULTICAST_MASK)){
\r
631 ip2MulticastEmacAddr(&(ethbuf->data.ipv4.destipaddr),&emac);
\r
634 //LocalIP以外ならdefaultRootへ変換
\r
635 eth_dest=NyLPC_cIPv4Arp_IPv4toEthAddr(
\r
637 NyLPC_cIPv4Config_isLocalIP(inst->_ref_config, &(ethbuf->data.ipv4.destipaddr))?(ethbuf->data.ipv4.destipaddr):(inst->_ref_config->dr_addr));
\r
639 if(eth_dest==NULL){
\r
640 return NyLPC_TBool_FALSE;
\r
643 //変換可能なら、イーサネットヘッダを更新して、送信処理へ。
\r
644 tx_len=NyLPC_TEthernetIIHeader_setIPv4Tx(&(ethbuf->header),&(inst->_ref_config->eth_mac),eth_dest);
\r
645 inst->_ethif->sendTxEthFrame(i_eth_buf,tx_len);
\r
646 return NyLPC_TBool_TRUE;
\r
651 //static void startEther()
\r
653 // NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
\r
656 // while(lEMACInit(_NyLPC_TcUipService_inst->_emac_semapho,&(inst->_ref_config->eth_mac))!= pdPASS )
\r
658 // vTaskDelay( 100 / portTICK_RATE_MS );
\r
660 // //Ethernetの割込み開始設定
\r
661 // portENTER_CRITICAL();
\r
663 // LPC_EMAC->IntEnable = ( INT_RX_DONE | INT_TX_DONE );
\r
664 // /* Set the interrupt priority to the max permissible to cause some
\r
665 // interrupt nesting. */
\r
666 // NVIC_SetPriority( ENET_IRQn, configEMAC_INTERRUPT_PRIORITY );
\r
668 // /* Enable the interrupt. */
\r
669 // NVIC_EnableIRQ( ENET_IRQn );
\r
671 // portEXIT_CRITICAL();
\r
674 //static void stopEther()
\r
676 // portENTER_CRITICAL();
\r
678 // LPC_EMAC->IntEnable = (~(INT_RX_DONE|INT_TX_DONE))&LPC_EMAC->IntEnable;
\r
679 // NVIC_DisableIRQ( ENET_IRQn );
\r
681 // portEXIT_CRITICAL();
\r