1 /*********************************************************************************
3 * --------------------------------------------------------------------------------
5 * This file is part of MiMic
6 * Copyright (C)2011 Ryo Iizuka
8 * MiMic is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published
10 * by the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 * For further information please contact.
23 * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
26 * Parts of this file were leveraged from uIP:
28 * Copyright (c) 2001-2003, Adam Dunkels.
29 * All rights reserved.
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
34 * 1. Redistributions of source code must retain the above copyright
35 * notice, this list of conditions and the following disclaimer.
36 * 2. Redistributions in binary form must reproduce the above copyright
37 * notice, this list of conditions and the following disclaimer in the
38 * documentation and/or other materials provided with the distribution.
39 * 3. The name of the author may not be used to endorse or promote
40 * products derived from this software without specific prior
43 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
44 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
45 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
47 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
49 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
50 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
51 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
52 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
53 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55 //#include "NyLPC_cIPv4IComp_protected.h"
56 //#include "NyLPC_cTcpListener_protected.h"
57 #include "NyLPC_cMiMicIpNetIf_protected.h"
58 #include "NyLPC_stdlib.h"
59 #include "../NyLPC_NetIf_ip_types.h"
60 #include "NyLPC_cIPv4IComp_protected.h"
61 #include "NyLPC_cMiMicIpTcpSocket_protected.h"
62 #include "NyLPC_cMiMicIpUdpSocket_protected.h"
63 #include "NyLPC_cMiMicIpTcpListener_protected.h"
69 /****************************************************
70 * UipServiceに関する宣言:その他
71 ***************************************************/
77 struct NyLPC_TEthernetIIHeader header;
79 struct NyLPC_TArpHeader arp;
80 struct NyLPC_TIPv4Header ipv4;
87 * サービスインスタンスのポインタ。サービスが稼働中はインスタンスのポインタが有効です。
89 NyLPC_TcMiMicIpNetIf_t* _NyLPC_TcMiMicIpNetIf_inst=NULL;
96 static int uipTask(void *pvParameters);
98 /** イーサネットドライバからのハンドラ*/
99 static void ethernet_handler(void* i_param,NyLPC_TiEthernetDevice_EVENT i_type);
101 //--------------------------------------------------------------
104 static NyLPC_TBool sendIPv4Tx(struct TEthPacket* i_eth_buf);
106 //static void sendArpReqest(const struct TEthPacket* i_eth_packet);
107 static void sendRawEthFrameNL(void* i_buf,NyLPC_TUInt16 i_len);
108 static void releaseTxBufNL(void* i_buf);
111 #define TTaskMessage_MSG_NULL 0x0000
112 /**uipコアタスクに、開始要求する*/
113 #define TTaskMessage_MSG_RUN 0x0001
114 /**uipコアタスクに、停止要求する*/
115 #define TTaskMessage_MSG_STOP 0x0002
118 static NyLPC_TcThread_t th;
120 NyLPC_TBool NyLPC_cMiMicIpNetIf_initialize(NyLPC_TcMiMicIpNetIf_t* i_inst)
122 //サービスは停止している事。 - Service must be uninitialized.
123 NyLPC_Assert(!NyLPC_cMiMicIpNetIf_isInitService());
125 NyLPC_cIPv4_initialize(&(i_inst->_tcpv4));
127 NyLPC_cSemaphore_initialize(&i_inst->_emac_semapho);
129 i_inst->_status=0x00;
130 NyLPC_cStopwatch_initialize(&(i_inst->_arp_sw));
131 NyLPC_cStopwatch_initialize(&(i_inst->_periodic_sw));
132 NyLPC_AbortIfNot(NyLPC_cMutex_initialize(&(i_inst->_mutex)));
134 _NyLPC_TcMiMicIpNetIf_inst=i_inst;
136 NyLPC_cThread_initialize(&th,NyLPC_cMiMicIpNetIf_config_STACK_SIZE,NyLPC_TcThread_PRIORITY_SERVICE);
137 NyLPC_cThread_start(&th,uipTask,NULL);
138 return NyLPC_TBool_TRUE;
149 * この関数はリエントラントではありません。複数のタスクから共有するときには、排他ロックを掛けてください。
150 * @param i_ref_config
151 * このコンフィギュレーションは、stopを実行するまでの間、インスタンスから参照します。外部で保持してください。
153 void NyLPC_cMiMicIpNetIf_start(const NyLPC_TcIPv4Config_t* i_ref_config)
155 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst;
156 NyLPC_Assert(NyLPC_cMiMicIpNetIf_isInitService());
157 if(!NyLPC_cMiMicIpNetIf_isRun())
159 //はじめて起動するときに1度だけデバイス取得(タスクスイッチが動いてないと動かないからここで。)
160 if(inst->_ethif==NULL){
161 inst->_ethif=getEthernetDevicePnP();
164 inst->_netinfo.current_config=i_ref_config;
166 NyLPC_TUInt16_setBit(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_START);
168 while(NyLPC_TUInt16_isBitOn(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_START)){
169 NyLPC_cThread_sleep(10);
172 inst->_netinfo.device_name=NyLPC_iEthernetDevice_getDevicName(inst->_ethif);
178 * この関数はリエントラントではありません。複数のタスクから共有するときには、排他ロックを掛けてください。
179 * いまのところ、ストップシーケンスの実装は良くありません。
182 void NyLPC_cMiMicIpNetIf_stop(void)
184 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst;
185 NyLPC_Assert(NyLPC_cMiMicIpNetIf_isInitService());
186 if(NyLPC_cMiMicIpNetIf_isRun())
188 NyLPC_TUInt16_setBit(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_STOP);
190 while(NyLPC_TUInt16_isBitOn(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_STOP)){
191 NyLPC_cThread_sleep(10);
197 static const struct NyLPC_TNetInterfaceInfo* NyLPC_cMiMicIpNetIf_getInterfaceInfo(void)
199 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst;
200 return &inst->_netinfo;
203 /**********************************************************************
207 *********************************************************************/
211 #define PERIODIC_TIMER (1*200)
212 #define ARP_TIMER (60*1000*10)
217 * 操作キューを確認して、タスクのステータスをアップデートします。
218 * 高速化のため、Proc-Callerを使用していません。複雑なタスク操作をするときには、書き換えてください。
222 static NyLPC_TBool updateTaskStatus()
224 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst;
225 if(NyLPC_cMiMicIpNetIf_isRun()){
227 if(NyLPC_TUInt16_isBitOn(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_STOP))
230 NyLPC_iEthernetDevice_stop(inst->_ethif);
231 NyLPC_cIPv4_stop(&(inst->_tcpv4));
232 NyLPC_cIPv4IComp_finalize(&(inst->_icomp));
233 NyLPC_cIPv4Arp_finalize(&(inst->_arp));
234 // inst->_ref_config=NULL;
235 NyLPC_TUInt16_unsetBit(inst->_status,NyLPC_TcMiMicIpNetIf_STATUSBIT_IS_RUNNING);
236 NyLPC_TUInt16_unsetBit(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_STOP);
237 return NyLPC_TBool_FALSE;
239 return NyLPC_TBool_TRUE;
242 if(NyLPC_TUInt16_isBitOn(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_START))
245 NyLPC_cIPv4_start(&(inst->_tcpv4),inst->_netinfo.current_config);
246 NyLPC_cIPv4IComp_initialize(&(inst->_icomp),inst->_netinfo.current_config);
247 //uip_arp_init(msg->start.ref_config);
248 NyLPC_cIPv4Arp_initialize(&(inst->_arp),inst->_netinfo.current_config);
249 NyLPC_cStopwatch_startExpire(&(inst->_arp_sw),1);//1度ARPを起動するため。
250 NyLPC_cStopwatch_startExpire(&(inst->_periodic_sw),PERIODIC_TIMER);
252 while(!NyLPC_iEthernetDevice_start(inst->_ethif,&(inst->_netinfo.current_config->eth_mac),ethernet_handler,inst));
253 NyLPC_TUInt16_setBit(inst->_status,NyLPC_TcMiMicIpNetIf_STATUSBIT_IS_RUNNING);
254 NyLPC_TUInt16_unsetBit(inst->_status,NyLPC_TcMiMicIpNetIf_ORDER_START);
255 return NyLPC_TBool_TRUE;
257 return NyLPC_TBool_FALSE;
264 static int uipTask(void *pvParameters)
266 NyLPC_TUInt16 rx_len,tx_len;
267 struct TEthPacket* ethbuf;
268 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst;
274 if(!updateTaskStatus())
276 //RUNステータス以外の時は、ここで終了する。
277 NyLPC_cThread_sleep(50);
281 //Ethernet Device Lock(ARPを含む)
282 NyLPC_cMutex_lock(&(inst->_mutex));
283 ethbuf= (struct TEthPacket*)NyLPC_iEthernetDevice_getRxEthFrame(inst->_ethif,&rx_len);
285 while(ethbuf != NULL){
289 rx_len-=sizeof(struct NyLPC_TEthernetIIHeader);
290 switch(ethbuf->header.type)
292 case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_IP):
294 //uip_arp_ipin(&(ethbuf->header),ethbuf->data.ipv4.srcipaddr);
295 NyLPC_cIPv4Arp_incomingIp(&inst->_arp,&(ethbuf->header),ethbuf->data.ipv4.srcipaddr);
296 //Ethernet Device UnLock(NyLPC_cIPv4_rxがallocをコールする可能性があるので一時的にロック解除)
297 NyLPC_cMutex_unlock(&(inst->_mutex));
299 r=NyLPC_cIPv4_rx(&(inst->_tcpv4),&(ethbuf->data.ipv4),rx_len);
302 NyLPC_cMiMicIpNetIf_sendIPv4Tx(r);
305 NyLPC_cMutex_lock(&(inst->_mutex));
310 case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_ARP):
311 //Ethernet Device UnLock(NyLPC_cIPv4_rxがallocをコールする可能性があるので一時的にロック解除)
312 NyLPC_cMutex_unlock(&(inst->_mutex));
313 r=NyLPC_cIPv4Arp_rx(&inst->_arp,&(ethbuf->data.arp),rx_len,&tx_len);
314 NyLPC_cMutex_lock(&(inst->_mutex));
316 sendRawEthFrameNL(r,tx_len);
320 case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_IPV6):
321 //uip_process_ipv6();
328 NyLPC_iEthernetDevice_nextRxEthFrame(inst->_ethif);
330 ethbuf= (struct TEthPacket*)NyLPC_iEthernetDevice_getRxEthFrame(inst->_ethif,&rx_len);
333 if(NyLPC_cStopwatch_isExpired(&(inst->_arp_sw))){
335 NyLPC_cIPv4Arp_periodic(&inst->_arp);
336 NyLPC_cStopwatch_startExpire(&(inst->_arp_sw),ARP_TIMER);
338 if(NyLPC_cStopwatch_isExpired(&(inst->_periodic_sw))){
339 NyLPC_cMutex_unlock(&(inst->_mutex));
340 NyLPC_cIPv4_periodec(&(inst->_tcpv4));
341 NyLPC_cMutex_lock(&(inst->_mutex));
342 NyLPC_cStopwatch_startExpire(&(inst->_periodic_sw),PERIODIC_TIMER);
345 NyLPC_cMutex_unlock(&(inst->_mutex));
346 //割込によるセマフォの解除か、タイムアウトで再開する。(タイムアウト値は周期関数の実行レート以下にすること。)
347 NyLPC_cSemaphore_take(&(_NyLPC_TcMiMicIpNetIf_inst->_emac_semapho),PERIODIC_TIMER);
356 static void ethernet_handler(void* i_param,NyLPC_TiEthernetDevice_EVENT i_type)
359 case NyLPC_TiEthernetDevice_EVENT_ON_RX:
361 NyLPC_cSemaphore_giveFromISR(&(((NyLPC_TcMiMicIpNetIf_t*)i_param)->_emac_semapho));
369 * IPv4パケットのpeerIPを問い合わせるARPパケットを送信します。
370 * allocを中でコールするから要UNLOCK状態
372 void NyLPC_cMiMicIpNetIf_sendArpRequest(const struct NyLPC_TIPv4Addr* i_addr)
374 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst;
375 NyLPC_TUInt16 tx_len;
376 struct TEthPacket* ethbuf;
377 //システムTXメモリを得てイーサフレームのポインタを復元
378 ethbuf=(struct TEthPacket*)(((struct NyLPC_TEthernetIIHeader*)NyLPC_cMiMicIpNetIf_allocSysTxBuf()-1));
380 NyLPC_TArpHeader_setArpRequest(&(ethbuf->data.arp),inst->_netinfo.current_config->ip_addr,&(inst->_netinfo.current_config->eth_mac),i_addr);
381 tx_len=NyLPC_TEthernetIIHeader_setArpTx(&(ethbuf->header),&(inst->_netinfo.current_config->eth_mac));
383 NyLPC_cMutex_lock(&(inst->_mutex));
384 NyLPC_iEthernetDevice_sendTxEthFrame(inst->_ethif,ethbuf,tx_len);
385 NyLPC_iEthernetDevice_releaseTxBuf(inst->_ethif,ethbuf);//NyLPC_cMiMicIpNetIf_releaseTxBufの代用だから元のイーサフレームメモリの値で開放
386 NyLPC_cMutex_unlock(&(inst->_mutex));
393 * allocTxBufで取得したペイロードメモリを"IPパケットとして"送信します。
394 * @param i_eth_payload
395 * [NyLPC_TEthernetIIHeader][payload]メモリの、[payload]のアドレスを指定します。
396 * 通常は、NyLPC_cUipService_allocTxBufの返却したメモリを指定します。
399 void NyLPC_cMiMicIpNetIf_sendIPv4Tx(void* i_eth_payload)
401 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst;
402 void* p=((struct NyLPC_TEthernetIIHeader*)i_eth_payload)-1;
403 NyLPC_cMutex_lock(&(inst->_mutex));
405 if(sendIPv4Tx((struct TEthPacket*)p)){
406 NyLPC_cMutex_unlock(&(inst->_mutex));
409 NyLPC_cMutex_unlock(&(inst->_mutex));
411 NyLPC_cMiMicIpNetIf_sendArpRequest(&((struct NyLPC_TIPv4Header*)i_eth_payload)->destipaddr);
417 * ARPテーブルに指定したIPがあるかを返します。
419 NyLPC_TBool NyLPC_cMiMicIpNetIf_hasArpInfo(const struct NyLPC_TIPv4Addr* i_addr)
421 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst;
422 return NyLPC_cIPv4Arp_IPv4toEthAddr(&inst->_arp,*i_addr)!=NULL;
426 * システム用の送信ペイロードを返します。
429 void* NyLPC_cMiMicIpNetIf_allocSysTxBuf(void)
432 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst;
433 struct TEthPacket* ethbuf;
434 //排他処理をして、メモリを取得する。SYSTEMメモリはEthernetドライバの解放待ちのみなのでまとめてLOCKしておk
435 NyLPC_cMutex_lock(&(inst->_mutex));
437 ethbuf=(struct TEthPacket*)NyLPC_iEthernetDevice_allocTxBuf(inst->_ethif,NyLPC_TcEthernetMM_HINT_CTRL_PACKET,&s);
439 NyLPC_cThread_yield();
444 NyLPC_cMutex_unlock(&(inst->_mutex));
446 return &(ethbuf->data);
451 void* NyLPC_cMiMicIpNetIf_allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size)
453 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst;
454 struct TEthPacket* ethbuf;
456 NyLPC_cMutex_lock(&(inst->_mutex));
457 ethbuf=(struct TEthPacket*)NyLPC_iEthernetDevice_allocTxBuf(inst->_ethif,i_hint+sizeof(struct NyLPC_TEthernetIIHeader),o_size);
458 NyLPC_cMutex_unlock(&(inst->_mutex));
463 *o_size-=sizeof(struct NyLPC_TEthernetIIHeader);
465 return &(ethbuf->data);
469 void* NyLPC_cMiMicIpNetIf_releaseTxBuf(void* i_buf)
472 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst;
473 NyLPC_cMutex_lock(&(inst->_mutex));
474 //ペイロードの位置から、メモリブロックを再生。
475 NyLPC_iEthernetDevice_releaseTxBuf(inst->_ethif,((struct NyLPC_TEthernetIIHeader*)i_buf)-1);
476 NyLPC_cMutex_unlock(&(inst->_mutex));
490 * この関数はiptaskで実行される関数からのみ使用てください。
492 * イーサネットフレームを格納したメモリです。
496 static void sendRawEthFrameNL(void* i_buf,NyLPC_TUInt16 i_len)
498 NyLPC_iEthernetDevice_sendTxEthFrame(
499 _NyLPC_TcMiMicIpNetIf_inst->_ethif,
500 ((struct NyLPC_TEthernetIIHeader*)i_buf)-1,
505 * ロック状態で使用できるreleaseTxBuf。
506 * この関数はiptaskで実行される関数からのみ使用してください。
508 static void releaseTxBufNL(void* i_buf)
510 //ペイロードの位置から、メモリブロックを再生。
511 NyLPC_iEthernetDevice_releaseTxBuf(
512 _NyLPC_TcMiMicIpNetIf_inst->_ethif,
513 ((struct NyLPC_TEthernetIIHeader*)i_buf)-1);
519 static void ip2MulticastEmacAddr(const struct NyLPC_TIPv4Addr* i_addr,struct NyLPC_TEthAddr* o_emac)
521 NyLPC_TUInt32 n=NyLPC_htonl(i_addr->v);
522 o_emac->addr[0]=0x01;
523 o_emac->addr[1]=0x00;
524 o_emac->addr[2]=0x5E;
525 o_emac->addr[3]=((n>>16) & 0x7f);
526 o_emac->addr[4]=((n>> 8) & 0xff);
527 o_emac->addr[5]=(n & 0xff);
532 * ペイロードをIPパケットとしてネットワークへ送出します。
533 * コール前に、必ずロックしてから呼び出してください。
534 * @param i_eth_payload
535 * allocTxBufで確保したメモリを指定してください。
536 * ペイロードには、TCP/IPパケットを格納します。
538 static NyLPC_TBool sendIPv4Tx(struct TEthPacket* i_eth_buf)
540 NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst;
541 struct NyLPC_TEthAddr emac;
542 NyLPC_TUInt16 tx_len;
543 const struct NyLPC_TEthAddr* eth_dest;
544 //ペイロードのアドレスから、イーサネットフレームバッファのアドレスを復元
546 if(NyLPC_TIPv4Addr_isEqual(&(i_eth_buf->data.ipv4.destipaddr),&NyLPC_TIPv4Addr_BROADCAST)) {
548 eth_dest=&NyLPC_TEthAddr_BROADCAST;
549 }else if(NyLPC_TIPv4Addr_isEqualWithMask(&(i_eth_buf->data.ipv4.destipaddr),&NyLPC_TIPv4Addr_MULTICAST,&NyLPC_TIPv4Addr_MULTICAST_MASK)){
551 ip2MulticastEmacAddr(&(i_eth_buf->data.ipv4.destipaddr),&emac);
554 //LocalIP以外ならdefaultRootへ変換
555 eth_dest=NyLPC_cIPv4Arp_IPv4toEthAddr(
557 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));
560 return NyLPC_TBool_FALSE;
563 //変換可能なら、イーサネットヘッダを更新して、送信処理へ。
564 tx_len=NyLPC_TEthernetIIHeader_setIPv4Tx(&(i_eth_buf->header),&(inst->_netinfo.current_config->eth_mac),eth_dest);
565 NyLPC_iEthernetDevice_sendTxEthFrame(inst->_ethif,i_eth_buf,tx_len);
566 return NyLPC_TBool_TRUE;
569 static NyLPC_TBool isInitService(void)
571 return _NyLPC_TcMiMicIpNetIf_inst!=NULL;
574 //--------------------------------------------------------------------------------
578 //--------------------------------------------------------------------------------
581 //--------------------------------------------------------------------------------
583 //--------------------------------------------------------------------------------
585 #define FLAGS_USED 0x00000001
590 NyLPC_TcMiMicIpTcpSocket_t socket;
591 NyLPC_TUInt8 rxbuf[NyLPC_cMiMicIpNetIf_config_TCPSOCKET_RX_BUFFER_SIZE];
596 NyLPC_TcMiMicIpUdpSocket_t socket;
597 NyLPC_TUInt8 rxbuf[NyLPC_cMiMicIpNetIf_config_UDPSOCKET_RX_BUFFER_SIZE];
602 NyLPC_TcMiMicIpUdpSocket_t socket;
604 struct TTcpListenerTable
607 NyLPC_TcMiMicIpTcpListener_t listener;
612 static struct TTcpTable tcp_socket_table[NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX];
613 static struct TUdpTable udp_socket_table[NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX];
614 static struct TUdpNBTable udp_socket_nb_table[NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX];
615 static struct TTcpListenerTable tcp_listener_table[NyLPC_cMiMicIpNetIf_config_TCPLISTENER_MAX];
617 NyLPC_TcMiMicIpTcpListener_t* NyLPC_cMiMicIpNetIf_getListenerByPeerPort(NyLPC_TUInt16 i_port)
620 //一致するポートを検索して、acceptをコールする。
621 for(i=NyLPC_cMiMicIpNetIf_config_TCPLISTENER_MAX-1;i>=0;i--){
622 if((tcp_listener_table[i].flags&FLAGS_USED)==0){
625 if(tcp_listener_table[i].listener._port!=i_port){
628 return &tcp_listener_table[i].listener;
634 * 指定番号のTCPポートが未使用かを返す。
636 * i_lport番のポートが未使用であればTRUE
638 NyLPC_TBool NyLPC_cMiMicIpNetIf_isClosedTcpPort(NyLPC_TUInt16 i_lport)
642 for(i=NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX-1;i>=0;i--){
643 if( ((tcp_socket_table[i].flags&FLAGS_USED)!=0) &&
644 (NyLPC_cMiMicIpTcpSocket_getLocalPort(&tcp_socket_table[i].socket)==i_lport)&&
645 (!NyLPC_cMiMicIpTcpSocket_isClosed(&tcp_socket_table[i].socket))){
647 return NyLPC_TBool_FALSE;
650 for(i=NyLPC_cMiMicIpNetIf_config_TCPLISTENER_MAX-1;i>=0;i--){
651 if( ((tcp_listener_table[i].flags&FLAGS_USED)!=0) &&
652 (NyLPC_cMiMicIpTcpListener_getLocalPort(&tcp_listener_table[i].listener)==i_lport)){
654 return NyLPC_TBool_FALSE;
657 return NyLPC_TBool_TRUE;
661 * 条件に一致する、アクティブなTCPソケットオブジェクトを取得します。
662 * この関数は、ローカルIPが一致していると仮定して検索をします。
666 NyLPC_TcMiMicIpTcpSocket_t* NyLPC_cMiMicIpNetIf_getMatchTcpSocket(
667 NyLPC_TUInt16 i_lport,struct NyLPC_TIPv4Addr i_rip,NyLPC_TUInt16 i_rport)
669 NyLPC_TcMiMicIpTcpSocket_t* tp;
672 for(i=NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX-1;i>=0;i--){
673 if((tcp_socket_table[i].flags&FLAGS_USED)==0){
676 if(NyLPC_cMiMicIpTcpSocket_isClosed(&tcp_socket_table[i].socket)){
679 tp=&tcp_socket_table[i].socket;
681 if(i_lport!=tp->uip_connr.lport || i_rport!= tp->uip_connr.rport || i_rip.v!=tp->uip_connr.ripaddr.v)
689 NyLPC_TcMiMicIpUdpSocket_t* NyLPC_cMiMicIpNetIf_getMatchUdpSocket(
690 NyLPC_TUInt16 i_lport)
693 for(i=NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX-1;i>=0;i--){
694 if((udp_socket_table[i].flags&FLAGS_USED)==0){
697 if(i_lport!=udp_socket_table[i].socket.uip_udp_conn.lport){
701 return &udp_socket_table[i].socket;
703 for(i=NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX-1;i>=0;i--){
704 if((udp_socket_nb_table[i].flags&FLAGS_USED)==0){
707 if(i_lport!=udp_socket_nb_table[i].socket.uip_udp_conn.lport){
711 return &udp_socket_nb_table[i].socket;
715 NyLPC_TcMiMicIpUdpSocket_t* NyLPC_cMiMicIpNetIf_getMatchMulticastUdpSocket(
716 const struct NyLPC_TIPv4Addr* i_mcast_ip,
717 NyLPC_TUInt16 i_lport)
720 for(i=NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX-1;i>=0;i--){
721 if((udp_socket_table[i].flags&FLAGS_USED)==0){
724 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))))
728 return &udp_socket_table[i].socket;
730 for(i=NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX-1;i>=0;i--){
731 if((udp_socket_nb_table[i].flags&FLAGS_USED)==0){
734 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))))
738 return &udp_socket_nb_table[i].socket;
744 void NyLPC_cMiMicIpNetIf_callPeriodic(void)
747 for(i=NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX-1;i>=0;i--){
748 if((udp_socket_table[i].flags&FLAGS_USED)!=0){
749 NyLPC_cMiMicIpUdpSocket_periodic(&udp_socket_table[i].socket);
752 for(i=NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX-1;i>=0;i--){
753 if((udp_socket_nb_table[i].flags&FLAGS_USED)!=0){
754 NyLPC_cMiMicIpUdpSocket_periodic(&udp_socket_nb_table[i].socket);
757 for(i=NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX-1;i>=0;i--){
758 if((tcp_socket_table[i].flags&FLAGS_USED)!=0){
759 NyLPC_cMiMicIpTcpSocket_periodic(&tcp_socket_table[i].socket);
763 void NyLPC_cMiMicIpNetIf_callSocketStart(
764 const NyLPC_TcIPv4Config_t* i_cfg)
767 for(i=NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX-1;i>=0;i--){
768 if((udp_socket_table[i].flags&FLAGS_USED)!=0){
769 NyLPC_cMiMicIpUdpSocket_startService(&udp_socket_table[i].socket,i_cfg);
772 for(i=NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX-1;i>=0;i--){
773 if((udp_socket_nb_table[i].flags&FLAGS_USED)!=0){
774 NyLPC_cMiMicIpUdpSocket_startService(&udp_socket_nb_table[i].socket,i_cfg);
777 for(i=NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX-1;i>=0;i--){
778 if((tcp_socket_table[i].flags&FLAGS_USED)!=0){
779 NyLPC_cMiMicIpTcpSocket_startService(&tcp_socket_table[i].socket,i_cfg);
783 void NyLPC_cMiMicIpNetIf_callSocketStop(void)
786 for(i=NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX-1;i>=0;i--){
787 if((udp_socket_table[i].flags&FLAGS_USED)!=0){
788 NyLPC_cMiMicIpUdpSocket_stopService(&udp_socket_table[i].socket);
791 for(i=NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX-1;i>=0;i--){
792 if((udp_socket_nb_table[i].flags&FLAGS_USED)!=0){
793 NyLPC_cMiMicIpUdpSocket_stopService(&udp_socket_nb_table[i].socket);
796 for(i=NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX-1;i>=0;i--){
797 if((tcp_socket_table[i].flags&FLAGS_USED)!=0){
798 NyLPC_cMiMicIpTcpSocket_stopService(&tcp_socket_table[i].socket);
805 //--------------------------------------------------------------------------------
808 static NyLPC_TiTcpSocket_t* createTcpSocetEx(NyLPC_TSocketType i_socktype)
812 case NyLPC_TSocketType_TCP_HTTP:
813 case NyLPC_TSocketType_TCP_NORMAL:
815 for(i=0;i<NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX;i++){
817 if((tcp_socket_table[i].flags&FLAGS_USED)==0){
818 if(!NyLPC_cMiMicIpTcpSocket_initialize(&tcp_socket_table[i].socket,tcp_socket_table[i].rxbuf,NyLPC_cMiMicIpNetIf_config_TCPSOCKET_RX_BUFFER_SIZE)){
822 tcp_socket_table[i].flags|=FLAGS_USED;
823 return &(tcp_socket_table[i].socket._super);
833 static NyLPC_TiUdpSocket_t* createUdpSocetEx(NyLPC_TUInt16 i_port,NyLPC_TSocketType i_socktype)
837 case NyLPC_TSocketType_UDP_NORMAL:
839 for(i=0;i<NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX;i++){
841 if((udp_socket_table[i].flags&FLAGS_USED)==0){
842 if(!NyLPC_cMiMicIpUdpSocket_initialize(&udp_socket_table[i].socket,i_port,udp_socket_table[i].rxbuf,NyLPC_cMiMicIpNetIf_config_UDPSOCKET_RX_BUFFER_SIZE)){
845 udp_socket_table[i].flags|=FLAGS_USED;
846 return &(udp_socket_table[i].socket._super);
850 case NyLPC_TSocketType_UDP_NOBUF:
852 for(i=0;i<NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX;i++){
854 if((udp_socket_nb_table[i].flags&FLAGS_USED)==0){
855 if(!NyLPC_cMiMicIpUdpSocket_initialize(&udp_socket_nb_table[i].socket,i_port,NULL,0)){
858 udp_socket_nb_table[i].flags|=FLAGS_USED;
859 return &(udp_socket_nb_table[i].socket._super);
868 static NyLPC_TiTcpListener_t* createTcpListener(NyLPC_TUInt16 i_port)
872 for(i=0;i<NyLPC_cMiMicIpNetIf_config_TCPLISTENER_MAX;i++){
874 if((tcp_listener_table[i].flags&FLAGS_USED)==0){
875 if(!NyLPC_cMiMicIpTcpListener_initialize(&tcp_listener_table[i].listener,i_port)){
879 tcp_listener_table[i].flags|=FLAGS_USED;
880 return &(tcp_listener_table[i].listener._super);
887 static const struct NyLPC_TiNetInterface_Interface _interface=
892 NyLPC_cMiMicIpNetIf_start,
893 NyLPC_cMiMicIpNetIf_stop,
894 NyLPC_cMiMicIpNetIf_sendArpRequest,
895 NyLPC_cMiMicIpNetIf_hasArpInfo,
896 isInitService,//NyLPC_TiNetInterface_isInitService isinitservice;
897 NyLPC_cMiMicIpNetIf_getInterfaceInfo
899 //--------------------------------------------------------------------------------
900 // インスタンスのリリース(protected)
902 void NyLPC_cMiMicIpNetIf_releaseTcpSocketMemory(const NyLPC_TcMiMicIpTcpSocket_t* i_inst)
906 for(i=0;i<NyLPC_cMiMicIpNetIf_config_TCPSOCKET_MAX;i++){
907 if((&tcp_socket_table[i].socket)==i_inst){
908 tcp_socket_table[i].flags&=~FLAGS_USED;
914 void NyLPC_cMiMicIpNetIf_releaseUdpSocketMemory(const NyLPC_TcMiMicIpUdpSocket_t* i_inst)
917 for(i=0;i<NyLPC_cMiMicIpNetIf_config_UDPSOCKET_MAX;i++){
918 if((&udp_socket_table[i].socket)==i_inst){
919 udp_socket_table[i].flags&=~FLAGS_USED;
923 for(i=0;i<NyLPC_cMiMicIpNetIf_config_NB_UDPSOCKET_MAX;i++){
924 if((&udp_socket_nb_table[i].socket)==i_inst){
925 udp_socket_nb_table[i].flags&=~FLAGS_USED;
931 void NyLPC_cMiMicIpNetIf_releaseTcpListenerMemory(const NyLPC_TcMiMicIpTcpListener_t* i_inst)
935 for(i=0;i<NyLPC_cMiMicIpNetIf_config_TCPLISTENER_MAX;i++){
936 if((&tcp_listener_table[i].listener)==i_inst){
937 tcp_listener_table[i].flags&=~FLAGS_USED;
944 static NyLPC_TcMiMicIpNetIf_t _netif;
946 const struct NyLPC_TiNetInterface_Interface* NyLPC_cMiMicIpNetIf_getNetInterface(void)
948 NyLPC_cMiMicIpNetIf_initialize(&_netif);