+++ /dev/null
-/*********************************************************************************\r
- * PROJECT: MiMic\r
- * --------------------------------------------------------------------------------\r
- *\r
- * This file is part of MiMic\r
- * Copyright (C)2011 Ryo Iizuka\r
- *\r
- * MiMic is free software: you can redistribute it and/or modify\r
- * it under the terms of the GNU Lesser General Public License as published\r
- * by the Free Software Foundation, either version 3 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public License\r
- * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- * For further information please contact.\r
- * http://nyatla.jp/\r
- * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>\r
- *\r
- *\r
- * Parts of this file were leveraged from uIP:\r
- *\r
- * Copyright (c) 2001-2003, Adam Dunkels.\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- * 1. Redistributions of source code must retain the above copyright\r
- * notice, this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the\r
- * documentation and/or other materials provided with the distribution.\r
- * 3. The name of the author may not be used to endorse or promote\r
- * products derived from this software without specific prior\r
- * written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS\r
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY\r
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\r
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-#include "NyLPC_cUipService_protected.h"\r
-#include "NyLPC_cIPv4IComp_protected.h"\r
-#include "NyLPC_cTcpListener_protected.h"\r
-#include "NyLPC_stdlib.h"\r
-#include "NyLPC_uip.h"\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-/****************************************************\r
- * UipServiceに関する宣言:その他\r
- ***************************************************/\r
-/**\r
- * イーサネットフレームの読み出し構造体\r
- */\r
-struct TEthPacket\r
-{\r
- struct NyLPC_TEthernetIIHeader header;\r
- union{\r
- struct NyLPC_TArpHeader arp;\r
- struct NyLPC_TIPv4Header ipv4;\r
- }data;\r
-}PACK_STRUCT_END;\r
-\r
-\r
-\r
-/**\r
- * サービスインスタンスのポインタ。サービスが稼働中はインスタンスのポインタが有効です。
- */\r
-NyLPC_TcUipService_t* _NyLPC_TcUipService_inst=NULL;\r
-\r
-/**\r
- * 唯一のインスタンス
- */\r
-static NyLPC_TcUipService_t _service_instance;\r
-\r
-\r
-\r
-\r
-/**\r
- * uipタスク
- */\r
-static int uipTask(void *pvParameters);\r
-\r
-/** イーサネットドライバからのハンドラ*/\r
-static void ethernet_handler(void* i_param,NyLPC_TiEthernetDevice_EVENT i_type);\r
-\r
-//--------------------------------------------------------------\r
-\r
-\r
-static NyLPC_TBool sendIPv4Tx(struct NyLPC_TTxBufferHeader* i_eth_buf);\r
-\r
-//static void sendArpReqest(const struct TEthPacket* i_eth_packet);\r
-static void sendRawEthFrameNL(void* i_buf,NyLPC_TUInt16 i_len);\r
-static void releaseTxBufNL(void* i_buf);\r
-\r
-/**メッセージなし*/\r
-#define TTaskMessage_MSG_NULL 0x0000\r
-/**uipコアタスクに、開始要求する*/\r
-#define TTaskMessage_MSG_RUN 0x0001\r
-/**uipコアタスクに、停止要求する*/\r
-#define TTaskMessage_MSG_STOP 0x0002\r
-\r
-\r
-NyLPC_TcThread_t th;\r
-\r
-NyLPC_TBool NyLPC_cUipService_initialize(void)\r
-{\r
- NyLPC_TcUipService_t* inst=&_service_instance;\r
- //サービスは停止している事。 - Service must be uninitialized.\r
- NyLPC_Assert(!NyLPC_TcUipService_isInitService());\r
- //IP処理部分の初期化\r
- NyLPC_cIPv4_initialize(&(inst->_tcpv4));\r
- //EMAC割込セマフォ\r
- NyLPC_cSemaphore_initialize(&inst->_emac_semapho);\r
-\r
- inst->_status=0x00;\r
- NyLPC_cStopwatch_initialize(&(inst->_arp_sw));\r
- NyLPC_cStopwatch_initialize(&(inst->_periodic_sw));\r
- NyLPC_cIPv4_initialize(&(inst->_tcpv4));\r
- NyLPC_AbortIfNot(NyLPC_cMutex_initialize(&(inst->_mutex)));\r
-\r
- _NyLPC_TcUipService_inst=inst;\r
- //タスク起動\r
- NyLPC_cThread_initialize(&th,NyLPC_cUipService_config_STACK_SIZE,NyLPC_TcThread_PRIORITY_SERVICE);\r
- NyLPC_cThread_start(&th,uipTask,NULL);\r
- return NyLPC_TBool_TRUE;\r
-}\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-/**\r
- * UIP処理を開始します。\r
- * この関数はリエントラントではありません。複数のタスクから共有するときには、排他ロックを掛けてください。\r
- * @param i_ref_config\r
- * このコンフィギュレーションは、stopを実行するまでの間、インスタンスから参照します。外部で保持してください。\r
- */\r
-void NyLPC_cUipService_start(const NyLPC_TcIPv4Config_t* i_ref_config)\r
-{\r
- NyLPC_TcUipService_t* inst=&_service_instance;\r
- NyLPC_Assert(NyLPC_TcUipService_isInitService());\r
- if(!NyLPC_cUipService_isRun())\r
- {\r
- //はじめて起動するときに1度だけデバイス取得(タスクスイッチが動いてないと動かないからここで。)\r
- if(inst->_ethif==NULL){\r
- inst->_ethif=getEthernetDevicePnP();\r
- }\r
- //コンフィグレーションセット\r
- inst->_ref_config=i_ref_config;\r
- //開始要求セット\r
- NyLPC_TUInt16_setBit(inst->_status,NyLPC_TcUipService_ORDER_START);\r
- //Order実行待ち\r
- while(NyLPC_TUInt16_isBitOn(inst->_status,NyLPC_TcUipService_ORDER_START)){\r
- NyLPC_cThread_sleep(10);\r
- }\r
- }\r
- return;\r
-}\r
-/**\r
- * UIP処理を停止します。\r
- * この関数はリエントラントではありません。複数のタスクから共有するときには、排他ロックを掛けてください。\r
- * いまのところ、ストップシーケンスの実装は良くありません。\r
- * 再設計が必要。
- */\r
-void NyLPC_cUipService_stop(void)\r
-{\r
- NyLPC_TcUipService_t* inst=&_service_instance;\r
- NyLPC_Assert(NyLPC_TcUipService_isInitService());\r
- if(NyLPC_cUipService_isRun())\r
- {\r
- NyLPC_TUInt16_setBit(inst->_status,NyLPC_TcUipService_ORDER_STOP);\r
- //Order実行待ち\r
- while(NyLPC_TUInt16_isBitOn(inst->_status,NyLPC_TcUipService_ORDER_STOP)){\r
- NyLPC_cThread_sleep(10);\r
- }\r
- }\r
- return;\r
-}\r
-\r
-\r
-const char* NyLPC_cUipService_refDeviceName(void)\r
-{\r
- NyLPC_TcUipService_t* inst=&_service_instance;\r
- return NyLPC_cUipService_isRun()?NyLPC_iEthernetDevice_getDevicName(inst->_ethif):NULL;\r
-}\r
-const NyLPC_TcIPv4Config_t* NyLPC_cUipService_refCurrentConfig(void)\r
-{\r
- NyLPC_TcUipService_t* inst=&_service_instance;\r
- return inst->_ref_config;\r
-}\r
-/**********************************************************************\r
- *\r
- * </HWコールバックに関わる宣言>\r
- *\r
- *********************************************************************/\r
-\r
-\r
-//PERIODIC rate\r
-#define PERIODIC_TIMER (1*200)\r
-#define ARP_TIMER (60*1000*10)\r
-\r
-\r
-\r
-/**\r
- * 操作キューを確認して、タスクのステータスをアップデートします。\r
- * 高速化のため、Proc-Callerを使用していません。複雑なタスク操作をするときには、書き換えてください。\r
- * @return\r
- * UIPタスクの実行状態
- */\r
-static NyLPC_TBool updateTaskStatus()\r
-{\r
- NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;\r
- if(NyLPC_cUipService_isRun()){\r
- //開始状態\r
- if(NyLPC_TUInt16_isBitOn(inst->_status,NyLPC_TcUipService_ORDER_STOP))\r
- {\r
- //停止操作\r
- NyLPC_iEthernetDevice_stop(inst->_ethif);\r
- NyLPC_cIPv4_stop(&(inst->_tcpv4));\r
- NyLPC_cIPv4IComp_finalize(&(inst->_icomp));\r
- NyLPC_cIPv4Arp_finalize(&(inst->_arp));\r
- inst->_ref_config=NULL;\r
- NyLPC_TUInt16_unsetBit(inst->_status,NyLPC_TcUipService_STATUSBIT_IS_RUNNING);\r
- NyLPC_TUInt16_unsetBit(inst->_status,NyLPC_TcUipService_ORDER_STOP);\r
- return NyLPC_TBool_FALSE;\r
- }\r
- return NyLPC_TBool_TRUE;\r
- }else{\r
- //停止状態\r
- if(NyLPC_TUInt16_isBitOn(inst->_status,NyLPC_TcUipService_ORDER_START))\r
- {\r
- //TCP,ICOMPの初期化\r
- NyLPC_cIPv4_start(&(inst->_tcpv4),inst->_ref_config);\r
- NyLPC_cIPv4IComp_initialize(&(inst->_icomp),inst->_ref_config);\r
- //uip_arp_init(msg->start.ref_config);\r
- NyLPC_cIPv4Arp_initialize(&(inst->_arp),inst->_ref_config);\r
- NyLPC_cStopwatch_startExpire(&(inst->_arp_sw),1);//1度ARPを起動するため。\r
- NyLPC_cStopwatch_startExpire(&(inst->_periodic_sw),PERIODIC_TIMER);\r
- //EtherNETデバイス初期化\r
- while(!NyLPC_iEthernetDevice_start(inst->_ethif,&(inst->_ref_config->eth_mac),ethernet_handler,inst));\r
- NyLPC_TUInt16_setBit(inst->_status,NyLPC_TcUipService_STATUSBIT_IS_RUNNING);\r
- NyLPC_TUInt16_unsetBit(inst->_status,NyLPC_TcUipService_ORDER_START);\r
- return NyLPC_TBool_TRUE;\r
- }\r
- return NyLPC_TBool_FALSE;\r
- }\r
-}\r
-\r
-/**\r
- * uipタスクのメインループ
- */\r
-static int uipTask(void *pvParameters)\r
-{\r
- NyLPC_TUInt16 rx_len,tx_len;\r
- struct TEthPacket* ethbuf;\r
- NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;\r
- void* r;\r
- (void)pvParameters;\r
- for( ;; )\r
- {\r
- //タスク状態の更新\r
- if(!updateTaskStatus())\r
- {\r
- //RUNステータス以外の時は、ここで終了する。\r
- NyLPC_cThread_sleep(50);\r
- continue;\r
- }\r
- //イーサネットフレームの取得\r
- //Ethernet Device Lock(ARPを含む)\r
- NyLPC_cMutex_lock(&(inst->_mutex));\r
- ethbuf= (struct TEthPacket*)NyLPC_iEthernetDevice_getRxEthFrame(inst->_ethif,&rx_len);\r
- tx_len=0;\r
- while(ethbuf != NULL){\r
- if(rx_len>0)\r
- {\r
- //ペイロードサイズを計算\r
- rx_len-=sizeof(struct NyLPC_TEthernetIIHeader);\r
- switch(ethbuf->header.type)\r
- {\r
- case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_IP):\r
- //ARPテーブルの更新\r
- //uip_arp_ipin(&(ethbuf->header),ethbuf->data.ipv4.srcipaddr);\r
- NyLPC_cIPv4Arp_incomingIp(&inst->_arp,&(ethbuf->header),ethbuf->data.ipv4.srcipaddr);\r
- //Ethernet Device UnLock(NyLPC_cIPv4_rxがallocをコールする可能性があるので一時的にロック解除)\r
- NyLPC_cMutex_unlock(&(inst->_mutex));\r
- //IPパケットの処理\r
- r=NyLPC_cIPv4_rx(&(inst->_tcpv4),&(ethbuf->data.ipv4),rx_len);\r
- if(r!=NULL){\r
- //IPパケットとして送信\r
- NyLPC_cUipService_sendIPv4Tx(r);\r
- }\r
- //ロックの復帰\r
- NyLPC_cMutex_lock(&(inst->_mutex));\r
- if(r!=NULL){\r
- releaseTxBufNL(r);\r
- }\r
- break;\r
- case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_ARP):\r
- //Ethernet Device UnLock(NyLPC_cIPv4_rxがallocをコールする可能性があるので一時的にロック解除)\r
- NyLPC_cMutex_unlock(&(inst->_mutex));\r
- r=NyLPC_cIPv4Arp_rx(&inst->_arp,&(ethbuf->data.arp),rx_len,&tx_len);\r
- NyLPC_cMutex_lock(&(inst->_mutex));\r
- if(r!=NULL){\r
- sendRawEthFrameNL(r,tx_len);\r
- releaseTxBufNL(r);\r
- }\r
- break;\r
- case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_IPV6):\r
- //uip_process_ipv6();\r
- break;\r
- default:\r
- break;\r
- }\r
- }\r
- //受信キューを進行。\r
- NyLPC_iEthernetDevice_nextRxEthFrame(inst->_ethif);\r
- //受信処理\r
- ethbuf= (struct TEthPacket*)NyLPC_iEthernetDevice_getRxEthFrame(inst->_ethif,&rx_len);\r
- }\r
- //データが無い。\r
- if(NyLPC_cStopwatch_isExpired(&(inst->_arp_sw))){\r
- //uip_arp_timer();\r
- NyLPC_cIPv4Arp_periodic(&inst->_arp);\r
- NyLPC_cStopwatch_startExpire(&(inst->_arp_sw),ARP_TIMER);\r
- }\r
- if(NyLPC_cStopwatch_isExpired(&(inst->_periodic_sw))){\r
- NyLPC_cMutex_unlock(&(inst->_mutex));\r
- NyLPC_cIPv4_periodec(&(inst->_tcpv4));\r
- NyLPC_cMutex_lock(&(inst->_mutex));\r
- NyLPC_cStopwatch_startExpire(&(inst->_periodic_sw),PERIODIC_TIMER);\r
- }\r
- //リソースロックの解除\r
- NyLPC_cMutex_unlock(&(inst->_mutex));\r
- //割込によるセマフォの解除か、タイムアウトで再開する。(タイムアウト値は周期関数の実行レート以下にすること。)\r
- NyLPC_cSemaphore_take(&(_NyLPC_TcUipService_inst->_emac_semapho),PERIODIC_TIMER);\r
- }\r
- return 0;\r
-}\r
-\r
-\r
-/**\r
- * イーサネットドライバからのハンドラ\r
- */\r
-static void ethernet_handler(void* i_param,NyLPC_TiEthernetDevice_EVENT i_type)\r
-{\r
- switch(i_type){\r
- case NyLPC_TiEthernetDevice_EVENT_ON_RX:\r
- //受信系のセマフォブロックの解除\r
- NyLPC_cSemaphore_giveFromISR(&(((NyLPC_TcUipService_t*)i_param)->_emac_semapho));\r
- break;\r
- default:\r
- break;\r
- }\r
-}\r
-\r
-/**\r
- * IPv4パケットのpeerIPを問い合わせるARPパケットを送信します。\r
- * allocを中でコールするから要UNLOCK状態\r
- */\r
-void NyLPC_cUipService_sendArpRequest(const struct NyLPC_TIPv4Addr* i_addr)\r
-{\r
- NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;\r
- struct NyLPC_TTxBufferHeader* p;\r
- NyLPC_TUInt16 tx_len;\r
- struct TEthPacket* ethbuf;\r
- //システムTxBufを得る\r
- ethbuf=(struct TEthPacket*)NyLPC_cUipService_allocSysTxBuf();\r
- //ARPパケットを作る。\r
- NyLPC_TArpHeader_setArpRequest(&(ethbuf->data.arp),inst->_ref_config->ip_addr,&(inst->_ref_config->eth_mac),i_addr);\r
- tx_len=NyLPC_TEthernetIIHeader_setArpTx(&(ethbuf->header),&(inst->_ref_config->eth_mac));\r
- //送信\r
- p=((struct NyLPC_TTxBufferHeader*)(((struct NyLPC_TEthernetIIHeader*)ethbuf)-1))-1;\r
-\r
- NyLPC_cMutex_lock(&(inst->_mutex));\r
- NyLPC_iEthernetDevice_sendTxEthFrame(inst->_ethif,p,tx_len);\r
- NyLPC_iEthernetDevice_releaseTxBuf(inst->_ethif,p);\r
- NyLPC_cMutex_unlock(&(inst->_mutex));\r
-}\r
-\r
-\r
-\r
-\r
-/**\r
- * allocTxBufで取得したペイロードメモリを"IPパケットとして"送信します。\r
- * @param i_eth_payload\r
- * [NyLPC_TTxBufferHeader][NyLPC_TEthernetIIHeader][payload]メモリの、[payload]のアドレスを指定します。\r
- * 通常は、NyLPC_cUipService_allocTxBufの返却したメモリを指定します。\r
- */\r
-\r
-void NyLPC_cUipService_sendIPv4Tx(void* i_eth_payload)\r
-{\r
- NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;\r
- struct NyLPC_TTxBufferHeader* p=((struct NyLPC_TTxBufferHeader*)(((struct NyLPC_TEthernetIIHeader*)i_eth_payload)-1))-1;\r
- NyLPC_cMutex_lock(&(inst->_mutex));\r
- //IPパケットの送信を試行\r
- if(sendIPv4Tx(p)){\r
- NyLPC_cMutex_unlock(&(inst->_mutex));\r
- return;\r
- }\r
- NyLPC_cMutex_unlock(&(inst->_mutex));\r
- //ARPリクエストを代わりに送信\r
- NyLPC_cUipService_sendArpRequest(&((struct NyLPC_TIPv4Header*)i_eth_payload)->destipaddr);\r
- return;\r
-}\r
-\r
-\r
-/**\r
- * ARPテーブルに指定したIPがあるかを返します。\r
- */\r
-NyLPC_TBool NyLPC_cUipService_hasArpInfo(const struct NyLPC_TIPv4Addr* i_addr)\r
-{\r
- NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;\r
- return NyLPC_cIPv4Arp_IPv4toEthAddr(&inst->_arp,*i_addr)!=NULL;\r
-}\r
-\r
-/**\r
- * システム用の送信ペイロードを返します。\r
- * 関数は必ず成功します。\r
- */\r
-void* NyLPC_cUipService_allocSysTxBuf(void)\r
-{\r
- NyLPC_TUInt16 s;\r
- NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;\r
- struct NyLPC_TTxBufferHeader* ethbuf;\r
- //排他処理をして、メモリを取得する。SYSTEMメモリはEthernetドライバの解放待ちのみなのでまとめてLOCKしておk\r
- NyLPC_cMutex_lock(&(inst->_mutex));\r
- for(;;){\r
- ethbuf=(struct NyLPC_TTxBufferHeader*)NyLPC_iEthernetDevice_allocTxBuf(inst->_ethif,NyLPC_TcEthernetMM_HINT_CTRL_PACKET,&s);\r
- if(ethbuf==NULL){\r
- NyLPC_cThread_yield();\r
- continue;\r
- }\r
- break;\r
- }\r
- NyLPC_cMutex_unlock(&(inst->_mutex));\r
- //イーサネットバッファのアドレスを計算\r
- return &(((struct TEthPacket*)(ethbuf+1))->data);\r
-}\r
-\r
-\r
-\r
-void* NyLPC_cUipService_allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size)\r
-{\r
- NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;\r
- struct NyLPC_TTxBufferHeader* ethbuf;\r
- //排他処理をして、メモリを取得する。\r
- NyLPC_cMutex_lock(&(inst->_mutex));\r
- ethbuf=(struct NyLPC_TTxBufferHeader*)NyLPC_iEthernetDevice_allocTxBuf(inst->_ethif,i_hint+sizeof(struct NyLPC_TEthernetIIHeader),o_size);\r
- NyLPC_cMutex_unlock(&(inst->_mutex));\r
- if(ethbuf==NULL){\r
- return NULL;\r
- }\r
- //イーサネットバッファのサイズを計算\r
- *o_size-=sizeof(struct NyLPC_TEthernetIIHeader);\r
- //イーサネットバッファのアドレスを計算\r
- return &(((struct TEthPacket*)(ethbuf+1))->data);\r
-}\r
-\r
-\r
-void* NyLPC_cUipService_releaseTxBuf(void* i_buf)\r
-{\r
- //排他処理をして、メモリを開放する。\r
- NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;\r
- NyLPC_cMutex_lock(&(inst->_mutex));\r
- //ペイロードの位置から、メモリブロックを再生。\r
- NyLPC_iEthernetDevice_releaseTxBuf(inst->_ethif,((struct NyLPC_TTxBufferHeader*)(((struct NyLPC_TEthernetIIHeader*)i_buf)-1))-1);\r
- NyLPC_cMutex_unlock(&(inst->_mutex));\r
- return NULL;\r
-}\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-/**********\r
- * イーサネットHWのコントロール関数\r
- */\r
-/**\r
- * "IPv4パケットを格納した"イーサフレームを送信します。\r
- * コール前に、必ずロックしてから呼び出してください。\r
- *//*\r
-static void copyAndSendIPv4Tx(const struct TEthPacket* i_buf)\r
-{\r
- NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;\r
- NyLPC_TUInt16 s;\r
- //送信する。\r
- s=NyLPC_htons(i_buf->data.ipv4.len16)+sizeof(struct NyLPC_TEthernetIIHeader);\r
- memcpy(inst->stx.buf,i_buf,s);\r
- if(!sendIPv4Tx(&(inst->stx.h))){\r
- //失敗した場合はARPリクエストに変換して再送\r
-//@todo unchecked PASS!\r
- sendArpReqest(&i_buf->data.ipv4.destipaddr);\r
- }\r
- return;\r
-}*/\r
-/**\r
- * "IPv4パケットを格納した"イーサフレームを送信します。\r
- * コール前に、必ずロックしてから呼び出してください。\r
- */\r
-/*\r
-static void copyAndSendIPv4Tx(const struct TEthPacket* i_buf)\r
-{\r
- NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;\r
- NyLPC_TUInt16 s;\r
- //ACK送信用の自己バッファが空くまで待つ\r
- while(inst->stx.h.is_lock){\r
- NyLPC_iEthernetDevice_processTx(inst->_ethif);\r
- }\r
- //送信する。\r
- s=NyLPC_htons(i_buf->data.ipv4.len16)+sizeof(struct NyLPC_TEthernetIIHeader);\r
- memcpy(inst->stx.buf,i_buf,s);\r
- if(!sendIPv4Tx(&(inst->stx.h))){\r
- //失敗した場合はARPリクエストに変換して再送\r
-//@todo unchecked PASS!\r
- sendArpReqest(&i_buf->data.ipv4.destipaddr);\r
- }\r
- return;\r
-}\r
-*/\r
-\r
-\r
-/**\r
- * イーサネットフレームを送信します。\r
- * この関数はiptaskで実行される関数からのみ使用てください。\r
- * @i_buf\r
- * イーサネットフレームを格納したメモリです。\r
- * @i_len\r
- * イーサネットペイロードのサイズです。\r
- */\r
-static void sendRawEthFrameNL(void* i_buf,NyLPC_TUInt16 i_len)\r
-{\r
- NyLPC_iEthernetDevice_sendTxEthFrame(\r
- _NyLPC_TcUipService_inst->_ethif,\r
- ((struct NyLPC_TTxBufferHeader*)(((struct NyLPC_TEthernetIIHeader*)i_buf)-1))-1,\r
- i_len);\r
- return;\r
-}\r
-/**\r
- * ロック状態で使用できるreleaseTxBuf。\r
- * この関数はiptaskで実行される関数からのみ使用してください。\r
- */\r
-static void releaseTxBufNL(void* i_buf)\r
-{\r
- //ペイロードの位置から、メモリブロックを再生。\r
- NyLPC_iEthernetDevice_releaseTxBuf(\r
- _NyLPC_TcUipService_inst->_ethif,\r
- ((struct NyLPC_TTxBufferHeader*)(((struct NyLPC_TEthernetIIHeader*)i_buf)-1))-1);\r
- return;\r
-}\r
-/**\r
- * マルチキャスとアドレスへ変換する。\r
- */\r
-static void ip2MulticastEmacAddr(const struct NyLPC_TIPv4Addr* i_addr,struct NyLPC_TEthAddr* o_emac)\r
-{\r
- NyLPC_TUInt32 n=NyLPC_htonl(i_addr->v);\r
- o_emac->addr[0]=0x01;\r
- o_emac->addr[1]=0x00;\r
- o_emac->addr[2]=0x5E;\r
- o_emac->addr[3]=((n>>16) & 0x7f);\r
- o_emac->addr[4]=((n>> 8) & 0xff);\r
- o_emac->addr[5]=(n & 0xff);\r
- return;\r
-};\r
-\r
-/**\r
- * ペイロードをIPパケットとしてネットワークへ送出します。\r
- * コール前に、必ずロックしてから呼び出してください。\r
- * @param i_eth_payload\r
- * allocTxBufで確保したメモリを指定してください。\r
- * ペイロードには、TCP/IPパケットを格納します。\r
- */\r
-static NyLPC_TBool sendIPv4Tx(struct NyLPC_TTxBufferHeader* i_eth_buf)\r
-{\r
- NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;\r
- struct NyLPC_TEthAddr emac;\r
- NyLPC_TUInt16 tx_len;\r
- const struct NyLPC_TEthAddr* eth_dest;\r
- struct TEthPacket* ethbuf=(struct TEthPacket*)(i_eth_buf+1);\r
- //ペイロードのアドレスから、イーサネットフレームバッファのアドレスを復元\r
-\r
- if(NyLPC_TIPv4Addr_isEqual(&(ethbuf->data.ipv4.destipaddr),&NyLPC_TIPv4Addr_BROADCAST)) {\r
- //ブロードキャストならそのまま\r
- eth_dest=&NyLPC_TEthAddr_BROADCAST;\r
- }else if(NyLPC_TIPv4Addr_isEqualWithMask(&(ethbuf->data.ipv4.destipaddr),&NyLPC_TIPv4Addr_MULTICAST,&NyLPC_TIPv4Addr_MULTICAST_MASK)){\r
- //マルチキャスト\r
- ip2MulticastEmacAddr(&(ethbuf->data.ipv4.destipaddr),&emac);\r
- eth_dest=&emac;\r
- }else{\r
- //LocalIP以外ならdefaultRootへ変換\r
- eth_dest=NyLPC_cIPv4Arp_IPv4toEthAddr(\r
- &inst->_arp,\r
- NyLPC_cIPv4Config_isLocalIP(inst->_ref_config, &(ethbuf->data.ipv4.destipaddr))?(ethbuf->data.ipv4.destipaddr):(inst->_ref_config->dr_addr));\r
- //IP->MAC変換をテスト。\r
- if(eth_dest==NULL){\r
- return NyLPC_TBool_FALSE;\r
- }\r
- }\r
- //変換可能なら、イーサネットヘッダを更新して、送信処理へ。\r
- tx_len=NyLPC_TEthernetIIHeader_setIPv4Tx(&(ethbuf->header),&(inst->_ref_config->eth_mac),eth_dest);\r
- NyLPC_iEthernetDevice_sendTxEthFrame(inst->_ethif,i_eth_buf,tx_len);\r
- return NyLPC_TBool_TRUE;\r
-}\r
-\r
-\r
-\r
-\r