Ryo Iizuka / libMiMic

Dependents:   MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more

Committer:
nyatla
Date:
Wed Jun 19 09:33:01 2013 +0000
Revision:
37:fc4b4fd6a649
Parent:
21:f2a70f15301f
Child:
48:00d211aac2ec
update; MiMic Core r263; add mDNS service,DHCP client,APIPA client

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nyatla 0:142ee8b12fef 1 /*********************************************************************************
nyatla 0:142ee8b12fef 2 * PROJECT: MiMic
nyatla 0:142ee8b12fef 3 * --------------------------------------------------------------------------------
nyatla 0:142ee8b12fef 4 *
nyatla 0:142ee8b12fef 5 * This file is part of MiMic
nyatla 0:142ee8b12fef 6 * Copyright (C)2011 Ryo Iizuka
nyatla 0:142ee8b12fef 7 *
nyatla 0:142ee8b12fef 8 * MiMic is free software: you can redistribute it and/or modify
nyatla 0:142ee8b12fef 9 * it under the terms of the GNU Lesser General Public License as published
nyatla 0:142ee8b12fef 10 * by the Free Software Foundation, either version 3 of the License, or
nyatla 0:142ee8b12fef 11 * (at your option) any later version.
nyatla 0:142ee8b12fef 12 *
nyatla 0:142ee8b12fef 13 * This program is distributed in the hope that it will be useful,
nyatla 0:142ee8b12fef 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nyatla 0:142ee8b12fef 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
nyatla 0:142ee8b12fef 16 * GNU General Public License for more details.
nyatla 0:142ee8b12fef 17 *
nyatla 0:142ee8b12fef 18 * You should have received a copy of the GNU Lesser General Public License
nyatla 0:142ee8b12fef 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
nyatla 0:142ee8b12fef 20 *
nyatla 0:142ee8b12fef 21 * For further information please contact.
nyatla 0:142ee8b12fef 22 * http://nyatla.jp/
nyatla 0:142ee8b12fef 23 * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
nyatla 0:142ee8b12fef 24 *
nyatla 0:142ee8b12fef 25 *
nyatla 0:142ee8b12fef 26 * Parts of this file were leveraged from uIP:
nyatla 0:142ee8b12fef 27 *
nyatla 0:142ee8b12fef 28 * Copyright (c) 2001-2003, Adam Dunkels.
nyatla 0:142ee8b12fef 29 * All rights reserved.
nyatla 0:142ee8b12fef 30 *
nyatla 0:142ee8b12fef 31 * Redistribution and use in source and binary forms, with or without
nyatla 0:142ee8b12fef 32 * modification, are permitted provided that the following conditions
nyatla 0:142ee8b12fef 33 * are met:
nyatla 0:142ee8b12fef 34 * 1. Redistributions of source code must retain the above copyright
nyatla 0:142ee8b12fef 35 * notice, this list of conditions and the following disclaimer.
nyatla 0:142ee8b12fef 36 * 2. Redistributions in binary form must reproduce the above copyright
nyatla 0:142ee8b12fef 37 * notice, this list of conditions and the following disclaimer in the
nyatla 0:142ee8b12fef 38 * documentation and/or other materials provided with the distribution.
nyatla 0:142ee8b12fef 39 * 3. The name of the author may not be used to endorse or promote
nyatla 0:142ee8b12fef 40 * products derived from this software without specific prior
nyatla 0:142ee8b12fef 41 * written permission.
nyatla 0:142ee8b12fef 42 *
nyatla 0:142ee8b12fef 43 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
nyatla 0:142ee8b12fef 44 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
nyatla 0:142ee8b12fef 45 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
nyatla 0:142ee8b12fef 46 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
nyatla 0:142ee8b12fef 47 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
nyatla 0:142ee8b12fef 48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
nyatla 0:142ee8b12fef 49 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
nyatla 0:142ee8b12fef 50 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
nyatla 0:142ee8b12fef 51 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
nyatla 0:142ee8b12fef 52 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
nyatla 0:142ee8b12fef 53 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
nyatla 0:142ee8b12fef 54 */
nyatla 37:fc4b4fd6a649 55 #include "NyLPC_cUipService_protected.h"
nyatla 2:b96c1e90d120 56 #include "NyLPC_cIPv4IComp_protected.h"
nyatla 0:142ee8b12fef 57 #include "NyLPC_cTcpListener_protected.h"
nyatla 0:142ee8b12fef 58 #include "NyLPC_stdlib.h"
nyatla 0:142ee8b12fef 59 #include "NyLPC_uip.h"
nyatla 0:142ee8b12fef 60
nyatla 2:b96c1e90d120 61
nyatla 2:b96c1e90d120 62
nyatla 2:b96c1e90d120 63
nyatla 0:142ee8b12fef 64
nyatla 0:142ee8b12fef 65 /****************************************************
nyatla 0:142ee8b12fef 66 * UipServiceに関する宣言:タスクメッセージ
nyatla 0:142ee8b12fef 67 ***************************************************/
nyatla 0:142ee8b12fef 68
nyatla 0:142ee8b12fef 69 #define TTaskMsg_NOP 0
nyatla 0:142ee8b12fef 70 #define TTaskMsg_START 1
nyatla 0:142ee8b12fef 71 #define TTaskMsg_STOP 2
nyatla 0:142ee8b12fef 72
nyatla 0:142ee8b12fef 73 /**
nyatla 0:142ee8b12fef 74 * サービスの起動メッセージです。
nyatla 0:142ee8b12fef 75 */
nyatla 0:142ee8b12fef 76 struct TTaskMsg{
nyatla 0:142ee8b12fef 77 NyLPC_TUInt16 msg;
nyatla 0:142ee8b12fef 78 union{
nyatla 0:142ee8b12fef 79 struct{
nyatla 0:142ee8b12fef 80 const NyLPC_TcIPv4Config_t* ref_config;
nyatla 0:142ee8b12fef 81 }start;
nyatla 0:142ee8b12fef 82 };
nyatla 0:142ee8b12fef 83 };
nyatla 0:142ee8b12fef 84
nyatla 0:142ee8b12fef 85 /****************************************************
nyatla 0:142ee8b12fef 86 * UipServiceに関する宣言:その他
nyatla 0:142ee8b12fef 87 ***************************************************/
nyatla 0:142ee8b12fef 88 /**
nyatla 0:142ee8b12fef 89 * イーサネットフレームの読み出し構造体
nyatla 0:142ee8b12fef 90 */
nyatla 0:142ee8b12fef 91 struct TEthPacket
nyatla 0:142ee8b12fef 92 {
nyatla 0:142ee8b12fef 93 struct NyLPC_TEthernetIIHeader header;
nyatla 0:142ee8b12fef 94 union{
nyatla 0:142ee8b12fef 95 struct NyLPC_TArpHeader arp;
nyatla 0:142ee8b12fef 96 struct NyLPC_TIPv4Header ipv4;
nyatla 0:142ee8b12fef 97 }data;
nyatla 0:142ee8b12fef 98 };
nyatla 0:142ee8b12fef 99
nyatla 0:142ee8b12fef 100
nyatla 0:142ee8b12fef 101
nyatla 0:142ee8b12fef 102 /**
nyatla 0:142ee8b12fef 103 * サービスインスタンスのポインタ。サービスが稼働中はインスタンスのポインタが有効です。
nyatla 0:142ee8b12fef 104 */
nyatla 0:142ee8b12fef 105 NyLPC_TcUipService_t* _NyLPC_TcUipService_inst=NULL;
nyatla 0:142ee8b12fef 106
nyatla 0:142ee8b12fef 107 /**
nyatla 0:142ee8b12fef 108 * 唯一のインスタンス
nyatla 0:142ee8b12fef 109 */
nyatla 0:142ee8b12fef 110 static NyLPC_TcUipService_t _service_instance;
nyatla 0:142ee8b12fef 111
nyatla 0:142ee8b12fef 112
nyatla 0:142ee8b12fef 113
nyatla 0:142ee8b12fef 114
nyatla 0:142ee8b12fef 115 /**
nyatla 0:142ee8b12fef 116 * uipタスク
nyatla 0:142ee8b12fef 117 */
nyatla 0:142ee8b12fef 118 static int uipTask(void *pvParameters);
nyatla 0:142ee8b12fef 119
nyatla 0:142ee8b12fef 120 //--------------------------------------------------------------
nyatla 0:142ee8b12fef 121
nyatla 0:142ee8b12fef 122
nyatla 0:142ee8b12fef 123 static NyLPC_TBool sendIPv4Tx(struct NyLPC_TTxBufferHeader* i_eth_buf);
nyatla 0:142ee8b12fef 124 static void copyAndSendIPv4Tx(const struct TEthPacket* i_buf);
nyatla 0:142ee8b12fef 125 static void sendArpReqest(const struct TEthPacket* i_eth_packet);
nyatla 0:142ee8b12fef 126 static void sendRawEthFrame(void* i_buf,NyLPC_TUInt16 i_len);
nyatla 0:142ee8b12fef 127 static void emacIsrHandler(unsigned long i_status);
nyatla 0:142ee8b12fef 128
nyatla 0:142ee8b12fef 129 /**メッセージなし*/
nyatla 0:142ee8b12fef 130 #define TTaskMessage_MSG_NULL 0x0000
nyatla 0:142ee8b12fef 131 /**uipコアタスクに、開始要求する*/
nyatla 0:142ee8b12fef 132 #define TTaskMessage_MSG_RUN 0x0001
nyatla 0:142ee8b12fef 133 /**uipコアタスクに、停止要求する*/
nyatla 0:142ee8b12fef 134 #define TTaskMessage_MSG_STOP 0x0002
nyatla 0:142ee8b12fef 135
nyatla 0:142ee8b12fef 136
nyatla 0:142ee8b12fef 137 NyLPC_TcThread_t th;
nyatla 0:142ee8b12fef 138
nyatla 0:142ee8b12fef 139 NyLPC_TBool NyLPC_cUipService_initialize(void)
nyatla 0:142ee8b12fef 140 {
nyatla 0:142ee8b12fef 141 NyLPC_TcUipService_t* inst=&_service_instance;
nyatla 0:142ee8b12fef 142 //サービスは停止している事。 - Service must be uninitialized.
nyatla 0:142ee8b12fef 143 NyLPC_Assert(!NyLPC_TcUipService_isInitService());
nyatla 0:142ee8b12fef 144 //IP処理部分の初期化
nyatla 0:142ee8b12fef 145 NyLPC_cIPv4_initialize(&(inst->_tcpv4));
nyatla 0:142ee8b12fef 146 //EMACからの割込処理
nyatla 1:9f6a78395432 147 NyLPC_cIsr_setEnetISR(emacIsrHandler);
nyatla 0:142ee8b12fef 148 //EMAC割込セマフォ
nyatla 0:142ee8b12fef 149 NyLPC_cSemaphore_initialize(&inst->_emac_semapho);
nyatla 0:142ee8b12fef 150
nyatla 0:142ee8b12fef 151 inst->_task_cmd=NULL;
nyatla 0:142ee8b12fef 152 inst->_status=NyLPC_TcUipService_STATUS_STOP;
nyatla 0:142ee8b12fef 153 NyLPC_cStopwatch_initialize(&(inst->_arp_sw));
nyatla 0:142ee8b12fef 154 NyLPC_cStopwatch_initialize(&(inst->_periodic_sw));
nyatla 0:142ee8b12fef 155 NyLPC_cIPv4_initialize(&(inst->_tcpv4));
nyatla 0:142ee8b12fef 156 NyLPC_AbortIfNot(NyLPC_cMutex_initialize(&(inst->_mutex)));
nyatla 0:142ee8b12fef 157
nyatla 0:142ee8b12fef 158 _NyLPC_TcUipService_inst=inst;
nyatla 0:142ee8b12fef 159 //タスク起動
nyatla 0:142ee8b12fef 160 NyLPC_cThread_initialize(&th,NyLPC_TcUipService_config_STACK_SIZE,NyLPC_TcThread_PRIORITY_SERVICE);
nyatla 0:142ee8b12fef 161 NyLPC_cThread_start(&th,uipTask,NULL);
nyatla 0:142ee8b12fef 162 return NyLPC_TBool_TRUE;
nyatla 0:142ee8b12fef 163 }
nyatla 0:142ee8b12fef 164
nyatla 0:142ee8b12fef 165
nyatla 0:142ee8b12fef 166
nyatla 0:142ee8b12fef 167
nyatla 0:142ee8b12fef 168
nyatla 0:142ee8b12fef 169
nyatla 0:142ee8b12fef 170
nyatla 0:142ee8b12fef 171 /**
nyatla 0:142ee8b12fef 172 * UIP処理を開始します。
nyatla 0:142ee8b12fef 173 * この関数はリエントラントではありません。複数のタスクから共有するときには、排他ロックを掛けてください。
nyatla 0:142ee8b12fef 174 * @param i_ref_config
nyatla 0:142ee8b12fef 175 * このコンフィギュレーションは、stopを実行するまでの間、インスタンスから参照します。外部で保持してください。
nyatla 0:142ee8b12fef 176 */
nyatla 0:142ee8b12fef 177 void NyLPC_cUipService_start(const NyLPC_TcIPv4Config_t* i_ref_config)
nyatla 0:142ee8b12fef 178 {
nyatla 0:142ee8b12fef 179 NyLPC_TcUipService_t* inst=&_service_instance;
nyatla 0:142ee8b12fef 180 struct TTaskMsg msg;
nyatla 0:142ee8b12fef 181 NyLPC_Assert(NyLPC_TcUipService_isInitService());
nyatla 0:142ee8b12fef 182 if(!NyLPC_cUipService_isRun())
nyatla 0:142ee8b12fef 183 {
nyatla 0:142ee8b12fef 184 //はじめて起動するときに1度だけデバイス取得(タスクスイッチが動いてないと動かないからここで。)
nyatla 0:142ee8b12fef 185 if(inst->_ethif==NULL){
nyatla 0:142ee8b12fef 186 inst->_ethif=getEthernetDevicePnP();
nyatla 0:142ee8b12fef 187 }
nyatla 0:142ee8b12fef 188 //コマンドセット
nyatla 0:142ee8b12fef 189 msg.msg=TTaskMsg_START;
nyatla 0:142ee8b12fef 190 msg.start.ref_config=i_ref_config;
nyatla 0:142ee8b12fef 191 _NyLPC_TcUipService_inst->_task_cmd=&msg;
nyatla 0:142ee8b12fef 192 //状態が変わるまでループ
nyatla 0:142ee8b12fef 193 while(!NyLPC_cUipService_isRun()){
nyatla 0:142ee8b12fef 194 NyLPC_cThread_sleep(10);
nyatla 0:142ee8b12fef 195 }
nyatla 0:142ee8b12fef 196 }
nyatla 0:142ee8b12fef 197 //コマンドクリア
nyatla 0:142ee8b12fef 198 _NyLPC_TcUipService_inst->_task_cmd=NULL;
nyatla 0:142ee8b12fef 199 return;
nyatla 0:142ee8b12fef 200 }
nyatla 0:142ee8b12fef 201 /**
nyatla 0:142ee8b12fef 202 * UIP処理を停止します。
nyatla 0:142ee8b12fef 203 * この関数はリエントラントではありません。複数のタスクから共有するときには、排他ロックを掛けてください。
nyatla 0:142ee8b12fef 204 * いまのところ、ストップシーケンスの実装は良くありません。
nyatla 0:142ee8b12fef 205 * 再設計が必要。
nyatla 0:142ee8b12fef 206 */
nyatla 0:142ee8b12fef 207 void NyLPC_cUipService_stop(void)
nyatla 0:142ee8b12fef 208 {
nyatla 0:142ee8b12fef 209 struct TTaskMsg msg;
nyatla 0:142ee8b12fef 210 NyLPC_TcUipService_t* inst=&_service_instance;
nyatla 0:142ee8b12fef 211 NyLPC_Assert(NyLPC_TcUipService_isInitService());
nyatla 0:142ee8b12fef 212 if(NyLPC_cUipService_isRun())
nyatla 0:142ee8b12fef 213 {
nyatla 0:142ee8b12fef 214 //コマンドセット
nyatla 0:142ee8b12fef 215 msg.msg=TTaskMsg_STOP;
nyatla 0:142ee8b12fef 216 _NyLPC_TcUipService_inst->_task_cmd=&msg;
nyatla 0:142ee8b12fef 217 //状態が変わるまでループ
nyatla 0:142ee8b12fef 218 while(NyLPC_cUipService_isRun()){
nyatla 0:142ee8b12fef 219 NyLPC_cThread_sleep(10);
nyatla 0:142ee8b12fef 220 }
nyatla 0:142ee8b12fef 221 NyLPC_cIPv4_stop(&(inst->_tcpv4));
nyatla 0:142ee8b12fef 222
nyatla 0:142ee8b12fef 223 }
nyatla 0:142ee8b12fef 224 //コマンドクリア
nyatla 0:142ee8b12fef 225 _NyLPC_TcUipService_inst->_task_cmd=NULL;
nyatla 0:142ee8b12fef 226 return;
nyatla 0:142ee8b12fef 227 }
nyatla 0:142ee8b12fef 228
nyatla 0:142ee8b12fef 229
nyatla 0:142ee8b12fef 230 const char* NyLPC_cUipService_refDeviceName(void)
nyatla 0:142ee8b12fef 231 {
nyatla 0:142ee8b12fef 232 NyLPC_TcUipService_t* inst=&_service_instance;
nyatla 0:142ee8b12fef 233 return NyLPC_cUipService_isRun()?inst->_ethif->device_name:NULL;
nyatla 0:142ee8b12fef 234 }
nyatla 21:f2a70f15301f 235 const NyLPC_TcIPv4Config_t* NyLPC_cUipService_refCurrentConfig(void)
nyatla 21:f2a70f15301f 236 {
nyatla 21:f2a70f15301f 237 NyLPC_TcUipService_t* inst=&_service_instance;
nyatla 21:f2a70f15301f 238 return inst->_ref_config;
nyatla 21:f2a70f15301f 239 }
nyatla 0:142ee8b12fef 240 /**********************************************************************
nyatla 0:142ee8b12fef 241 *
nyatla 0:142ee8b12fef 242 * </HWコールバックに関わる宣言>
nyatla 0:142ee8b12fef 243 *
nyatla 0:142ee8b12fef 244 *********************************************************************/
nyatla 0:142ee8b12fef 245
nyatla 0:142ee8b12fef 246 /**
nyatla 0:142ee8b12fef 247 * EMACからのハンドラ
nyatla 0:142ee8b12fef 248 */
nyatla 0:142ee8b12fef 249 static void emacIsrHandler(unsigned long i_status)
nyatla 0:142ee8b12fef 250 {
nyatla 0:142ee8b12fef 251 NyLPC_TcUipService_t* inst=&_service_instance;
nyatla 0:142ee8b12fef 252
nyatla 0:142ee8b12fef 253 if( i_status & INT_RX_DONE )
nyatla 0:142ee8b12fef 254 {
nyatla 0:142ee8b12fef 255 //受信系のセマフォブロックの解除
nyatla 0:142ee8b12fef 256 NyLPC_cSemaphore_giveFromISR(&inst->_emac_semapho);
nyatla 0:142ee8b12fef 257 }
nyatla 0:142ee8b12fef 258 if( i_status & INT_TX_DONE )
nyatla 0:142ee8b12fef 259 {
nyatla 0:142ee8b12fef 260 }
nyatla 0:142ee8b12fef 261 }
nyatla 0:142ee8b12fef 262
nyatla 0:142ee8b12fef 263
nyatla 0:142ee8b12fef 264 //PERIODIC rate
nyatla 0:142ee8b12fef 265 #define PERIODIC_TIMER (1*200)
nyatla 0:142ee8b12fef 266 #define ARP_TIMER (60*1000*10)
nyatla 0:142ee8b12fef 267
nyatla 37:fc4b4fd6a649 268
nyatla 37:fc4b4fd6a649 269
nyatla 0:142ee8b12fef 270 /**
nyatla 0:142ee8b12fef 271 * 操作キューを確認して、タスクのステータスをアップデートします。
nyatla 0:142ee8b12fef 272 * 高速化のため、Proc-Callerを使用していません。複雑なタスク操作をするときには、書き換えてください。
nyatla 0:142ee8b12fef 273 */
nyatla 0:142ee8b12fef 274 static void updateTaskStatus()
nyatla 0:142ee8b12fef 275 {
nyatla 0:142ee8b12fef 276 NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
nyatla 0:142ee8b12fef 277
nyatla 0:142ee8b12fef 278 struct TTaskMsg* msg=(struct TTaskMsg*)(inst->_task_cmd);
nyatla 0:142ee8b12fef 279
nyatla 0:142ee8b12fef 280 //コマンドが設定されていない時は、何もしない。
nyatla 0:142ee8b12fef 281 if(msg==NULL){
nyatla 0:142ee8b12fef 282 return;
nyatla 0:142ee8b12fef 283 }
nyatla 0:142ee8b12fef 284 switch(msg->msg)
nyatla 0:142ee8b12fef 285 {
nyatla 0:142ee8b12fef 286 //何もしない。
nyatla 0:142ee8b12fef 287 case TTaskMsg_NOP:
nyatla 0:142ee8b12fef 288 break;
nyatla 0:142ee8b12fef 289 //開始操作
nyatla 0:142ee8b12fef 290 case TTaskMsg_START:
nyatla 0:142ee8b12fef 291 //状態チェック
nyatla 0:142ee8b12fef 292 if(NyLPC_cUipService_isRun()){
nyatla 0:142ee8b12fef 293 break;
nyatla 0:142ee8b12fef 294 }
nyatla 0:142ee8b12fef 295 inst->_ref_config=msg->start.ref_config;
nyatla 0:142ee8b12fef 296 //TCP,ICOMPの初期化
nyatla 0:142ee8b12fef 297 NyLPC_cIPv4_start(&(inst->_tcpv4),inst->_ref_config);
nyatla 0:142ee8b12fef 298 NyLPC_cIPv4IComp_initialize(&(inst->_icomp),inst->_ref_config);
nyatla 0:142ee8b12fef 299 //uip_arp_init(msg->start.ref_config);
nyatla 0:142ee8b12fef 300 NyLPC_cIPv4Arp_initialize(&(inst->_arp),inst->_ref_config);
nyatla 0:142ee8b12fef 301 NyLPC_cStopwatch_startExpire(&(inst->_arp_sw),1);//1度ARPを起動するため。
nyatla 0:142ee8b12fef 302 NyLPC_cStopwatch_startExpire(&(inst->_periodic_sw),PERIODIC_TIMER);
nyatla 37:fc4b4fd6a649 303 //InBuffer初期化
nyatla 37:fc4b4fd6a649 304 inst->stx.h.is_lock=NyLPC_TUInt8_FALSE;
nyatla 37:fc4b4fd6a649 305 inst->stx.h.ref=0;
nyatla 37:fc4b4fd6a649 306 //EtherNETデバイス初期化
nyatla 0:142ee8b12fef 307 while(!inst->_ethif->start(&(inst->_ref_config->eth_mac)));
nyatla 0:142ee8b12fef 308 inst->_status=NyLPC_TcUipService_STATUS_RUN;
nyatla 0:142ee8b12fef 309 break;
nyatla 0:142ee8b12fef 310 //終了操作
nyatla 0:142ee8b12fef 311 case TTaskMsg_STOP:
nyatla 0:142ee8b12fef 312 //状態チェック
nyatla 0:142ee8b12fef 313 if(!NyLPC_cUipService_isRun()){
nyatla 0:142ee8b12fef 314 break;
nyatla 0:142ee8b12fef 315 }
nyatla 0:142ee8b12fef 316 //停止操作
nyatla 0:142ee8b12fef 317 inst->_ethif->stop();
nyatla 0:142ee8b12fef 318 NyLPC_cIPv4_stop(&(inst->_tcpv4));
nyatla 0:142ee8b12fef 319 NyLPC_cIPv4IComp_finalize(&(inst->_icomp));
nyatla 37:fc4b4fd6a649 320 NyLPC_cIPv4Arp_finalize(&(inst->_arp));
nyatla 0:142ee8b12fef 321 inst->_status=NyLPC_TcUipService_STATUS_STOP;
nyatla 0:142ee8b12fef 322 break;
nyatla 0:142ee8b12fef 323 default:
nyatla 0:142ee8b12fef 324 //実行してはいけない。
nyatla 0:142ee8b12fef 325 NyLPC_Abort();
nyatla 0:142ee8b12fef 326 }
nyatla 0:142ee8b12fef 327 //コマンドを無効化
nyatla 0:142ee8b12fef 328 inst->_task_cmd=TTaskMsg_NOP;
nyatla 0:142ee8b12fef 329 return;
nyatla 0:142ee8b12fef 330 }
nyatla 0:142ee8b12fef 331
nyatla 0:142ee8b12fef 332 /**
nyatla 0:142ee8b12fef 333 * uipタスクのメインループ
nyatla 0:142ee8b12fef 334 */
nyatla 0:142ee8b12fef 335 static int uipTask(void *pvParameters)
nyatla 0:142ee8b12fef 336 {
nyatla 0:142ee8b12fef 337 NyLPC_TUInt16 rx_len,tx_len;
nyatla 0:142ee8b12fef 338 struct TEthPacket* ethbuf;
nyatla 0:142ee8b12fef 339 NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
nyatla 0:142ee8b12fef 340 NyLPC_TBool r;
nyatla 0:142ee8b12fef 341 (void)pvParameters;
nyatla 0:142ee8b12fef 342 for( ;; )
nyatla 0:142ee8b12fef 343 {
nyatla 0:142ee8b12fef 344 //タスク状態の更新
nyatla 0:142ee8b12fef 345 updateTaskStatus();
nyatla 0:142ee8b12fef 346 if(inst->_status!=NyLPC_TcUipService_STATUS_RUN)
nyatla 0:142ee8b12fef 347 {
nyatla 0:142ee8b12fef 348 //RUNステータス以外の時は、ここで終了する。
nyatla 0:142ee8b12fef 349 NyLPC_cThread_sleep(50);
nyatla 0:142ee8b12fef 350 continue;
nyatla 0:142ee8b12fef 351 }
nyatla 0:142ee8b12fef 352 //イーサネットフレームの取得
nyatla 0:142ee8b12fef 353 //Ethernet Device Lock(ARPを含む)
nyatla 2:b96c1e90d120 354 NyLPC_cMutex_lock(&(inst->_mutex));
nyatla 0:142ee8b12fef 355 ethbuf= (struct TEthPacket*)inst->_ethif->getRxEthFrame(&rx_len);
nyatla 0:142ee8b12fef 356 tx_len=0;
nyatla 0:142ee8b12fef 357 while(ethbuf != NULL){
nyatla 0:142ee8b12fef 358 if(rx_len>0)
nyatla 0:142ee8b12fef 359 {
nyatla 0:142ee8b12fef 360 //ペイロードサイズを計算
nyatla 0:142ee8b12fef 361 rx_len-=sizeof(struct NyLPC_TEthernetIIHeader);
nyatla 0:142ee8b12fef 362 switch(ethbuf->header.type)
nyatla 0:142ee8b12fef 363 {
nyatla 0:142ee8b12fef 364 case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_IP):
nyatla 0:142ee8b12fef 365 //ARPテーブルの更新
nyatla 0:142ee8b12fef 366 //uip_arp_ipin(&(ethbuf->header),ethbuf->data.ipv4.srcipaddr);
nyatla 0:142ee8b12fef 367 NyLPC_cIPv4Arp_incomingIp(&inst->_arp,&(ethbuf->header),ethbuf->data.ipv4.srcipaddr);
nyatla 0:142ee8b12fef 368 //Ethernet Device UnLock(パケット解析の為に一時的な解除)
nyatla 0:142ee8b12fef 369 NyLPC_cMutex_unlock(&(inst->_mutex));
nyatla 0:142ee8b12fef 370 //IPパケットの処理
nyatla 0:142ee8b12fef 371 r=NyLPC_cIPv4_rx(&(inst->_tcpv4),&(ethbuf->data.ipv4),rx_len);
nyatla 0:142ee8b12fef 372 //ロックの復帰
nyatla 0:142ee8b12fef 373 NyLPC_cMutex_lock(&(inst->_mutex));
nyatla 0:142ee8b12fef 374 if(!r){
nyatla 0:142ee8b12fef 375 //応答データは存在しない。
nyatla 0:142ee8b12fef 376 break;
nyatla 0:142ee8b12fef 377 }
nyatla 0:142ee8b12fef 378 //IPパケットをTxバッファに転写して送信
nyatla 0:142ee8b12fef 379 copyAndSendIPv4Tx(ethbuf);
nyatla 0:142ee8b12fef 380 ethbuf=NULL;
nyatla 0:142ee8b12fef 381 break;
nyatla 0:142ee8b12fef 382 case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_ARP):
nyatla 0:142ee8b12fef 383 //if(uip_arp_arpin(&(ethbuf->data.arp),rx_len)){
nyatla 0:142ee8b12fef 384 if(NyLPC_cIPv4Arp_incomingArp(&inst->_arp,&(ethbuf->data.arp),rx_len)){
nyatla 0:142ee8b12fef 385 tx_len=NyLPC_TEthernetIIHeader_setArpTx(&(ethbuf->header),&(inst->_ref_config->eth_mac));
nyatla 0:142ee8b12fef 386 }
nyatla 0:142ee8b12fef 387 if(tx_len>0){
nyatla 0:142ee8b12fef 388 sendRawEthFrame(ethbuf,tx_len);
nyatla 0:142ee8b12fef 389 }
nyatla 0:142ee8b12fef 390 break;
nyatla 0:142ee8b12fef 391 case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_IPV6):
nyatla 0:142ee8b12fef 392 //uip_process_ipv6();
nyatla 0:142ee8b12fef 393 break;
nyatla 0:142ee8b12fef 394 default:
nyatla 0:142ee8b12fef 395 break;
nyatla 0:142ee8b12fef 396 }
nyatla 0:142ee8b12fef 397 }
nyatla 2:b96c1e90d120 398 //受信キューを進行。
nyatla 0:142ee8b12fef 399 inst->_ethif->nextRxEthFrame();
nyatla 0:142ee8b12fef 400 //受信処理
nyatla 0:142ee8b12fef 401 ethbuf= (struct TEthPacket*)inst->_ethif->getRxEthFrame(&rx_len);
nyatla 0:142ee8b12fef 402 }
nyatla 0:142ee8b12fef 403 //データが無い。
nyatla 0:142ee8b12fef 404 if(NyLPC_cStopwatch_isExpired(&(inst->_arp_sw))){
nyatla 0:142ee8b12fef 405 //uip_arp_timer();
nyatla 0:142ee8b12fef 406 NyLPC_cIPv4Arp_periodic(&inst->_arp);
nyatla 0:142ee8b12fef 407 NyLPC_cStopwatch_startExpire(&(inst->_arp_sw),ARP_TIMER);
nyatla 2:b96c1e90d120 408 }
nyatla 0:142ee8b12fef 409 if(NyLPC_cStopwatch_isExpired(&(inst->_periodic_sw))){
nyatla 37:fc4b4fd6a649 410 NyLPC_cMutex_unlock(&(inst->_mutex));
nyatla 0:142ee8b12fef 411 NyLPC_cIPv4_periodec(&(inst->_tcpv4));
nyatla 37:fc4b4fd6a649 412 NyLPC_cMutex_lock(&(inst->_mutex));
nyatla 0:142ee8b12fef 413 NyLPC_cStopwatch_startExpire(&(inst->_periodic_sw),PERIODIC_TIMER);
nyatla 0:142ee8b12fef 414 }
nyatla 0:142ee8b12fef 415 //リソースロックの解除
nyatla 0:142ee8b12fef 416 NyLPC_cMutex_unlock(&(inst->_mutex));
nyatla 0:142ee8b12fef 417 //割込によるセマフォの解除か、タイムアウトで再開する。(タイムアウト値は周期関数の実行レート以下にすること。)
nyatla 0:142ee8b12fef 418 NyLPC_cSemaphore_take(&(_NyLPC_TcUipService_inst->_emac_semapho),PERIODIC_TIMER);
nyatla 0:142ee8b12fef 419 }
nyatla 0:142ee8b12fef 420 return 0;
nyatla 0:142ee8b12fef 421 }
nyatla 0:142ee8b12fef 422
nyatla 0:142ee8b12fef 423
nyatla 0:142ee8b12fef 424
nyatla 0:142ee8b12fef 425
nyatla 0:142ee8b12fef 426 /**
nyatla 0:142ee8b12fef 427 * allocTxBufで取得したメモリを"IPパケットとして"送信します。
nyatla 0:142ee8b12fef 428 * @param i_eth_payload
nyatla 0:142ee8b12fef 429 * [NyLPC_TTxBufferHeader][NyLPC_TEthernetIIHeader][payload]メモリの、[payload]のアドレスを指定します。
nyatla 0:142ee8b12fef 430 * 通常は、NyLPC_cUipService_allocTxBufの返却したメモリを指定します。
nyatla 0:142ee8b12fef 431 */
nyatla 0:142ee8b12fef 432
nyatla 0:142ee8b12fef 433 void NyLPC_cUipService_sendIPv4Tx(void* i_eth_payload)
nyatla 0:142ee8b12fef 434 {
nyatla 0:142ee8b12fef 435 NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
nyatla 0:142ee8b12fef 436 NyLPC_cMutex_lock(&(inst->_mutex));
nyatla 0:142ee8b12fef 437 //IPパケットの送信を試行
nyatla 0:142ee8b12fef 438 if(!sendIPv4Tx(((struct NyLPC_TTxBufferHeader*)(((struct NyLPC_TEthernetIIHeader*)i_eth_payload)-1))-1)){
nyatla 0:142ee8b12fef 439 //ARPリクエストを代わりに送信
nyatla 0:142ee8b12fef 440 sendArpReqest(((struct TEthPacket*)i_eth_payload)-1);
nyatla 0:142ee8b12fef 441 }
nyatla 0:142ee8b12fef 442 NyLPC_cMutex_unlock(&(inst->_mutex));
nyatla 0:142ee8b12fef 443 return;
nyatla 0:142ee8b12fef 444 }
nyatla 37:fc4b4fd6a649 445 /**
nyatla 37:fc4b4fd6a649 446 * 指定したIPアドレスに対してARPRequestを送信します。
nyatla 37:fc4b4fd6a649 447 */
nyatla 37:fc4b4fd6a649 448 void NyLPC_cUipService_sendArpRequest(const struct NyLPC_TIPv4Addr* i_addr)
nyatla 37:fc4b4fd6a649 449 {
nyatla 37:fc4b4fd6a649 450 NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
nyatla 37:fc4b4fd6a649 451 NyLPC_TUInt16 tx_len;
nyatla 37:fc4b4fd6a649 452 struct TEthPacket* ethbuf;
nyatla 37:fc4b4fd6a649 453 //ACK送信用の自己バッファが空くまで待つ
nyatla 37:fc4b4fd6a649 454 while(inst->stx.h.is_lock){
nyatla 37:fc4b4fd6a649 455 inst->_ethif->processTx();
nyatla 37:fc4b4fd6a649 456 }
nyatla 37:fc4b4fd6a649 457 //ARPパケットを作る。
nyatla 37:fc4b4fd6a649 458 ethbuf=(struct TEthPacket*)(inst->stx.buf);
nyatla 37:fc4b4fd6a649 459 NyLPC_TArpHeader_setArpRequest(&(ethbuf->data.arp),inst->_ref_config->ip_addr,&(inst->_ref_config->eth_mac),*i_addr);
nyatla 37:fc4b4fd6a649 460 tx_len=NyLPC_TEthernetIIHeader_setArpTx(&(ethbuf->header),&(inst->_ref_config->eth_mac));
nyatla 37:fc4b4fd6a649 461 //送信
nyatla 37:fc4b4fd6a649 462 inst->_ethif->sendTxEthFrame(&(inst->stx.h),tx_len);
nyatla 37:fc4b4fd6a649 463 return;
nyatla 37:fc4b4fd6a649 464 }
nyatla 0:142ee8b12fef 465
nyatla 37:fc4b4fd6a649 466 /**
nyatla 37:fc4b4fd6a649 467 * ARPテーブルに指定したIPがあるかを返します。
nyatla 37:fc4b4fd6a649 468 */
nyatla 37:fc4b4fd6a649 469 NyLPC_TBool NyLPC_cUipService_hasArpInfo(const struct NyLPC_TIPv4Addr* i_addr)
nyatla 37:fc4b4fd6a649 470 {
nyatla 37:fc4b4fd6a649 471 NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
nyatla 37:fc4b4fd6a649 472 return NyLPC_cIPv4Arp_IPv4toEthAddr(&inst->_arp,*i_addr)!=NULL;
nyatla 37:fc4b4fd6a649 473 }
nyatla 0:142ee8b12fef 474
nyatla 0:142ee8b12fef 475
nyatla 0:142ee8b12fef 476 /**
nyatla 0:142ee8b12fef 477 * 送信ペイロードメモリを返します。
nyatla 0:142ee8b12fef 478 * この関数は、リエントラントを許容します。
nyatla 0:142ee8b12fef 479 * @param i_hint
nyatla 0:142ee8b12fef 480 * 取得したいメモリサイズを指定します。(このサイズは、イーサネットヘッダのサイズを含みません。)
nyatla 0:142ee8b12fef 481 * このサイズよりも小さなサイズが割り当てられることがあります。
nyatla 37:fc4b4fd6a649 482 * @param o_size
nyatla 37:fc4b4fd6a649 483 * イーサネットヘッダを除いたペイロード部分の長さ
nyatla 0:142ee8b12fef 484 * @return
nyatla 20:3b0b444b4deb 485 * 成功:IPペイロードのためのメモリブロックを返します。/失敗:NULL
nyatla 37:fc4b4fd6a649 486 * 返されるメモリはブロックの[TEthPacket][payload]の構造で、[payload]のアドレスが返されます。
nyatla 0:142ee8b12fef 487 */
nyatla 0:142ee8b12fef 488 void* NyLPC_cUipService_allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size)
nyatla 0:142ee8b12fef 489 {
nyatla 0:142ee8b12fef 490 NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
nyatla 0:142ee8b12fef 491 struct NyLPC_TTxBufferHeader* ethbuf;
nyatla 37:fc4b4fd6a649 492 //排他処理をして、メモリを取得する。
nyatla 0:142ee8b12fef 493 NyLPC_cMutex_lock(&(inst->_mutex));
nyatla 0:142ee8b12fef 494 ethbuf=(struct NyLPC_TTxBufferHeader*)inst->_ethif->allocTxBuf(i_hint+sizeof(struct NyLPC_TEthernetIIHeader),o_size);
nyatla 0:142ee8b12fef 495 NyLPC_cMutex_unlock(&(inst->_mutex));
nyatla 20:3b0b444b4deb 496 if(ethbuf==NULL){
nyatla 20:3b0b444b4deb 497 return NULL;
nyatla 0:142ee8b12fef 498 }
nyatla 20:3b0b444b4deb 499 //イーサネットバッファのサイズを計算
nyatla 20:3b0b444b4deb 500 *o_size-=sizeof(struct NyLPC_TEthernetIIHeader);
nyatla 20:3b0b444b4deb 501 //イーサネットバッファのアドレスを計算
nyatla 20:3b0b444b4deb 502 return &(((struct TEthPacket*)(ethbuf+1))->data);
nyatla 0:142ee8b12fef 503 }
nyatla 0:142ee8b12fef 504
nyatla 0:142ee8b12fef 505
nyatla 0:142ee8b12fef 506 void* NyLPC_cUipService_releaseTxBuf(void* i_buf)
nyatla 0:142ee8b12fef 507 {
nyatla 0:142ee8b12fef 508 //排他処理をして、メモリを開放する。
nyatla 0:142ee8b12fef 509 NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
nyatla 0:142ee8b12fef 510 NyLPC_cMutex_lock(&(inst->_mutex));
nyatla 0:142ee8b12fef 511 //ペイロードの位置から、メモリブロックを再生。
nyatla 0:142ee8b12fef 512 inst->_ethif->releaseTxBuf(((struct NyLPC_TTxBufferHeader*)(((struct NyLPC_TEthernetIIHeader*)i_buf)-1))-1);
nyatla 0:142ee8b12fef 513 NyLPC_cMutex_unlock(&(inst->_mutex));
nyatla 0:142ee8b12fef 514 return NULL;
nyatla 0:142ee8b12fef 515 }
nyatla 0:142ee8b12fef 516
nyatla 0:142ee8b12fef 517
nyatla 0:142ee8b12fef 518
nyatla 0:142ee8b12fef 519
nyatla 0:142ee8b12fef 520
nyatla 0:142ee8b12fef 521
nyatla 0:142ee8b12fef 522
nyatla 0:142ee8b12fef 523
nyatla 0:142ee8b12fef 524 /**********
nyatla 0:142ee8b12fef 525 * イーサネットHWのコントロール関数
nyatla 0:142ee8b12fef 526 */
nyatla 0:142ee8b12fef 527
nyatla 0:142ee8b12fef 528 /**
nyatla 0:142ee8b12fef 529 * 新たにメモリを確保して、"IPv4パケットを格納した"イーサフレームを送信します。
nyatla 0:142ee8b12fef 530 * コール前に、必ずロックしてから呼び出してください。
nyatla 0:142ee8b12fef 531 */
nyatla 0:142ee8b12fef 532 static void copyAndSendIPv4Tx(const struct TEthPacket* i_buf)
nyatla 0:142ee8b12fef 533 {
nyatla 0:142ee8b12fef 534 NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
nyatla 0:142ee8b12fef 535 NyLPC_TUInt16 s;
nyatla 0:142ee8b12fef 536 //ACK送信用の自己バッファが空くまで待つ
nyatla 0:142ee8b12fef 537 while(inst->stx.h.is_lock){
nyatla 0:142ee8b12fef 538 inst->_ethif->processTx();
nyatla 0:142ee8b12fef 539 }
nyatla 0:142ee8b12fef 540 //送信する。
nyatla 0:142ee8b12fef 541 s=NyLPC_htons(i_buf->data.ipv4.len16)+sizeof(struct NyLPC_TEthernetIIHeader);
nyatla 0:142ee8b12fef 542 memcpy(inst->stx.buf,i_buf,s);
nyatla 0:142ee8b12fef 543 if(!sendIPv4Tx(&(inst->stx.h))){
nyatla 0:142ee8b12fef 544 //失敗した場合はARPリクエストに変換して再送
nyatla 0:142ee8b12fef 545 sendArpReqest(i_buf);
nyatla 0:142ee8b12fef 546 }
nyatla 0:142ee8b12fef 547 return;
nyatla 0:142ee8b12fef 548 }
nyatla 0:142ee8b12fef 549 /**
nyatla 0:142ee8b12fef 550 * IPv4パケットのpeerIPを問い合わせるARPパケットを送信します。
nyatla 0:142ee8b12fef 551 */
nyatla 0:142ee8b12fef 552 static void sendArpReqest(const struct TEthPacket* i_eth_packet)
nyatla 0:142ee8b12fef 553 {
nyatla 0:142ee8b12fef 554 NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
nyatla 0:142ee8b12fef 555 NyLPC_TUInt16 tx_len;
nyatla 0:142ee8b12fef 556 struct TEthPacket* ethbuf;
nyatla 0:142ee8b12fef 557 //ACK送信用の自己バッファが空くまで待つ
nyatla 0:142ee8b12fef 558 while(inst->stx.h.is_lock){
nyatla 0:142ee8b12fef 559 inst->_ethif->processTx();
nyatla 0:142ee8b12fef 560 }
nyatla 0:142ee8b12fef 561 //ARPパケットを作る。
nyatla 0:142ee8b12fef 562 ethbuf=(struct TEthPacket*)(inst->stx.buf);
nyatla 0:142ee8b12fef 563 NyLPC_TArpHeader_setArpRequest(&(ethbuf->data.arp),inst->_ref_config->ip_addr,&(inst->_ref_config->eth_mac),i_eth_packet->data.ipv4.destipaddr);
nyatla 0:142ee8b12fef 564 tx_len=NyLPC_TEthernetIIHeader_setArpTx(&(ethbuf->header),&(inst->_ref_config->eth_mac));
nyatla 0:142ee8b12fef 565 //送信
nyatla 0:142ee8b12fef 566 inst->_ethif->sendTxEthFrame(&(inst->stx.h),tx_len);
nyatla 0:142ee8b12fef 567 }
nyatla 0:142ee8b12fef 568
nyatla 0:142ee8b12fef 569 /**
nyatla 0:142ee8b12fef 570 * uipタスクが所有するTXバッファを使用してデータを送信します。
nyatla 0:142ee8b12fef 571 * この関数は、i_bufをコピーします。
nyatla 0:142ee8b12fef 572 * @i_buf
nyatla 0:142ee8b12fef 573 * イーサネットフレームを格納したメモリです。
nyatla 0:142ee8b12fef 574 * @i_len
nyatla 0:142ee8b12fef 575 * イーサネットペイロードのサイズです。
nyatla 0:142ee8b12fef 576 */
nyatla 0:142ee8b12fef 577 static void sendRawEthFrame(void* i_buf,NyLPC_TUInt16 i_len)
nyatla 0:142ee8b12fef 578 {
nyatla 0:142ee8b12fef 579 NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
nyatla 0:142ee8b12fef 580
nyatla 0:142ee8b12fef 581 //ACK送信用の自己バッファが空くまで待つ
nyatla 0:142ee8b12fef 582 while(inst->stx.h.is_lock){
nyatla 0:142ee8b12fef 583 inst->_ethif->processTx();
nyatla 0:142ee8b12fef 584 }
nyatla 0:142ee8b12fef 585 //64バイトを超えるとかありえない。
nyatla 0:142ee8b12fef 586 if(i_len+sizeof(struct NyLPC_TEthernetIIHeader)>NyLPC_TcUipService_SIZE_OF_REPLY_BUF){
nyatla 0:142ee8b12fef 587 return;
nyatla 0:142ee8b12fef 588 }
nyatla 0:142ee8b12fef 589 //送信する。
nyatla 0:142ee8b12fef 590 memcpy(inst->stx.buf,i_buf,i_len);
nyatla 0:142ee8b12fef 591 inst->_ethif->sendTxEthFrame(&(inst->stx.h),i_len);
nyatla 0:142ee8b12fef 592 return;
nyatla 0:142ee8b12fef 593 }
nyatla 0:142ee8b12fef 594
nyatla 37:fc4b4fd6a649 595 /**
nyatla 37:fc4b4fd6a649 596 * マルチキャスとアドレスへ変換する。
nyatla 37:fc4b4fd6a649 597 */
nyatla 37:fc4b4fd6a649 598 static void ip2MulticastEmacAddr(const struct NyLPC_TIPv4Addr* i_addr,struct NyLPC_TEthAddr* o_emac)
nyatla 37:fc4b4fd6a649 599 {
nyatla 37:fc4b4fd6a649 600 NyLPC_TUInt32 n=NyLPC_htonl(i_addr->v);
nyatla 37:fc4b4fd6a649 601 o_emac->addr[0]=0x01;
nyatla 37:fc4b4fd6a649 602 o_emac->addr[1]=0x00;
nyatla 37:fc4b4fd6a649 603 o_emac->addr[2]=0x5E;
nyatla 37:fc4b4fd6a649 604 o_emac->addr[3]=((n>>16) & 0x7f);
nyatla 37:fc4b4fd6a649 605 o_emac->addr[4]=((n>> 8) & 0xff);
nyatla 37:fc4b4fd6a649 606 o_emac->addr[5]=(n & 0xff);
nyatla 37:fc4b4fd6a649 607 return;
nyatla 37:fc4b4fd6a649 608 };
nyatla 0:142ee8b12fef 609
nyatla 0:142ee8b12fef 610 /**
nyatla 0:142ee8b12fef 611 * ペイロードをIPパケットとしてネットワークへ送出します。
nyatla 0:142ee8b12fef 612 * コール前に、必ずロックしてから呼び出してください。
nyatla 0:142ee8b12fef 613 * @param i_eth_payload
nyatla 0:142ee8b12fef 614 * allocTxBufで確保したメモリを指定してください。
nyatla 0:142ee8b12fef 615 * ペイロードには、TCP/IPパケットを格納します。
nyatla 0:142ee8b12fef 616 */
nyatla 0:142ee8b12fef 617 static NyLPC_TBool sendIPv4Tx(struct NyLPC_TTxBufferHeader* i_eth_buf)
nyatla 0:142ee8b12fef 618 {
nyatla 0:142ee8b12fef 619 NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
nyatla 37:fc4b4fd6a649 620 struct NyLPC_TEthAddr emac;
nyatla 0:142ee8b12fef 621 NyLPC_TUInt16 tx_len;
nyatla 37:fc4b4fd6a649 622 const struct NyLPC_TEthAddr* eth_dest;
nyatla 0:142ee8b12fef 623 struct TEthPacket* ethbuf=(struct TEthPacket*)(i_eth_buf+1);
nyatla 0:142ee8b12fef 624 //ペイロードのアドレスから、イーサネットフレームバッファのアドレスを復元
nyatla 37:fc4b4fd6a649 625
nyatla 37:fc4b4fd6a649 626 if(NyLPC_TIPv4Addr_isEqual(&(ethbuf->data.ipv4.destipaddr),&NyLPC_TIPv4Addr_BROADCAST)) {
nyatla 37:fc4b4fd6a649 627 //ブロードキャストならそのまま
nyatla 37:fc4b4fd6a649 628 eth_dest=&NyLPC_TEthAddr_BROADCAST;
nyatla 37:fc4b4fd6a649 629 }else if(NyLPC_TIPv4Addr_isEqualWithMask(&(ethbuf->data.ipv4.destipaddr),&NyLPC_TIPv4Addr_MULTICAST,&NyLPC_TIPv4Addr_MULTICAST_MASK)){
nyatla 37:fc4b4fd6a649 630 //マルチキャスト
nyatla 37:fc4b4fd6a649 631 ip2MulticastEmacAddr(&(ethbuf->data.ipv4.destipaddr),&emac);
nyatla 37:fc4b4fd6a649 632 eth_dest=&emac;
nyatla 37:fc4b4fd6a649 633 }else{
nyatla 37:fc4b4fd6a649 634 //LocalIP以外ならdefaultRootへ変換
nyatla 37:fc4b4fd6a649 635 eth_dest=NyLPC_cIPv4Arp_IPv4toEthAddr(
nyatla 37:fc4b4fd6a649 636 &inst->_arp,
nyatla 37:fc4b4fd6a649 637 NyLPC_cIPv4Config_isLocalIP(inst->_ref_config, &(ethbuf->data.ipv4.destipaddr))?(ethbuf->data.ipv4.destipaddr):(inst->_ref_config->dr_addr));
nyatla 37:fc4b4fd6a649 638 //IP->MAC変換をテスト。
nyatla 37:fc4b4fd6a649 639 if(eth_dest==NULL){
nyatla 37:fc4b4fd6a649 640 return NyLPC_TBool_FALSE;
nyatla 37:fc4b4fd6a649 641 }
nyatla 0:142ee8b12fef 642 }
nyatla 0:142ee8b12fef 643 //変換可能なら、イーサネットヘッダを更新して、送信処理へ。
nyatla 0:142ee8b12fef 644 tx_len=NyLPC_TEthernetIIHeader_setIPv4Tx(&(ethbuf->header),&(inst->_ref_config->eth_mac),eth_dest);
nyatla 0:142ee8b12fef 645 inst->_ethif->sendTxEthFrame(i_eth_buf,tx_len);
nyatla 0:142ee8b12fef 646 return NyLPC_TBool_TRUE;
nyatla 0:142ee8b12fef 647 }
nyatla 0:142ee8b12fef 648
nyatla 0:142ee8b12fef 649
nyatla 0:142ee8b12fef 650
nyatla 0:142ee8b12fef 651 //static void startEther()
nyatla 0:142ee8b12fef 652 //{
nyatla 0:142ee8b12fef 653 // NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;
nyatla 0:142ee8b12fef 654 //
nyatla 0:142ee8b12fef 655 // //Ethernetの起動待ち
nyatla 0:142ee8b12fef 656 // while(lEMACInit(_NyLPC_TcUipService_inst->_emac_semapho,&(inst->_ref_config->eth_mac))!= pdPASS )
nyatla 0:142ee8b12fef 657 // {
nyatla 0:142ee8b12fef 658 // vTaskDelay( 100 / portTICK_RATE_MS );
nyatla 0:142ee8b12fef 659 // }
nyatla 0:142ee8b12fef 660 // //Ethernetの割込み開始設定
nyatla 0:142ee8b12fef 661 // portENTER_CRITICAL();
nyatla 0:142ee8b12fef 662 // {
nyatla 0:142ee8b12fef 663 // LPC_EMAC->IntEnable = ( INT_RX_DONE | INT_TX_DONE );
nyatla 0:142ee8b12fef 664 // /* Set the interrupt priority to the max permissible to cause some
nyatla 0:142ee8b12fef 665 // interrupt nesting. */
nyatla 0:142ee8b12fef 666 // NVIC_SetPriority( ENET_IRQn, configEMAC_INTERRUPT_PRIORITY );
nyatla 0:142ee8b12fef 667 //
nyatla 0:142ee8b12fef 668 // /* Enable the interrupt. */
nyatla 0:142ee8b12fef 669 // NVIC_EnableIRQ( ENET_IRQn );
nyatla 0:142ee8b12fef 670 // }
nyatla 0:142ee8b12fef 671 // portEXIT_CRITICAL();
nyatla 0:142ee8b12fef 672 //}
nyatla 0:142ee8b12fef 673 //
nyatla 0:142ee8b12fef 674 //static void stopEther()
nyatla 0:142ee8b12fef 675 //{
nyatla 0:142ee8b12fef 676 // portENTER_CRITICAL();
nyatla 0:142ee8b12fef 677 // {
nyatla 0:142ee8b12fef 678 // LPC_EMAC->IntEnable = (~(INT_RX_DONE|INT_TX_DONE))&LPC_EMAC->IntEnable;
nyatla 0:142ee8b12fef 679 // NVIC_DisableIRQ( ENET_IRQn );
nyatla 0:142ee8b12fef 680 // }
nyatla 0:142ee8b12fef 681 // portEXIT_CRITICAL();
nyatla 20:3b0b444b4deb 682 //}
nyatla 20:3b0b444b4deb 683