⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pkthandler.c

📁 lwip tcp/ip 协议栈 adsp BF533 DSP 移植 用 visual dsp++ 编译
💻 C
字号:
/*
 * Descripton:
 *  Contains packet callbacks, dhcp, buffer handling functionlity
 */
#include "lwip/debug.h"
#include "lwip/ip.h"
#include "lwip/tcpip.h"
#include "lwip/netif.h"
#include "netif/etharp.h"

#include <cglobals.h>
#include <kernel_abs.h>
#include <sys/exception.h>
#include <services/services.h>
#include <drivers/adi_dev.h>
#include <services/adi_dcb.h>
#include <services/adi_dma.h>
#include <services/adi_int.h>
#include <services/adi_ebiu.h>
#include "netif/nifce_driver.h"
#include <ADI_ETHER.h>

// Enable it to print the obtained IP address.
//#define _LWIP_DEBUG_

// Maximum number of supported interfaces.
#define MAX_NETWORK_IF 2 

// struct to hold network driver instance specific information.
//
struct network_info {
  int                       num_if;
  int                       imask[MAX_NETWORK_IF]; 
  struct nifce_info          vinfo[MAX_NETWORK_IF];
  struct netif*             netif[MAX_NETWORK_IF];
  struct ip_addr            ipaddr[MAX_NETWORK_IF];
  struct ip_addr            netmask[MAX_NETWORK_IF];
  struct ip_addr            gateway[MAX_NETWORK_IF];
};

// The below two external variables will be  defined in the generated user 
// configuration file
//
extern net_config_info user_net_config_info[];
extern int user_net_num_ifces;

// global statics
static struct network_info  netinfo = {0};
static ADI_DEV_DEVICE_HANDLE pli_services[MAX_NETWORK_IF];
ADI_ETHER_BUFFER *rcv_list=NULL,*xmt_list=NULL;
void lwip_init(u8_t *lwip_memory);
void dhcp_timer_init(void);



void   etharp_timer_init();
int    dhcp_configure(void);
void   nifce_driver_poll(void*);

/****************************************************************
 *
 *  Append the packet the passed list. list could be recv list
 *  or transmit list.must be called in critical region.
 *  list could be rcv_list or xmt_list
 ****************************************************************/
static void append_list(ADI_ETHER_BUFFER **list,ADI_ETHER_BUFFER *b)
{
	ADI_ETHER_BUFFER *t;

	if(*list == NULL)
		*list = b;
	else
	{
		t = *list;
		while(t->pNext != NULL)
			t= t->pNext;
		t->pNext = b;
	}
}

/****************************************************************
 *
 * callback function that puts in poll function in the tcpip queue.
 * the enqued callback function is exectued by the tcpip thread.
 * enques callbacks for all n/w interfaces.
 ****************************************************************/
void tcpip_q_callback(void *in_args)
{
	int i,poll_period = (int)in_args;
	if(poll_period == 0) poll_period = 10;
    
	while (1)
    {
	  ker_sleep(poll_period);
	 
      for (i = 0; i < netinfo.num_if; i += 1)
        tcpip_callback(nifce_driver_poll, netinfo.netif[i]);
	}
		
}


/****************************************************************
 *
 * Deffered callback handler. Called in-response to device drivers
 * Post call.
 * TODO: Optimize to process xmt packets in the callback
 ****************************************************************/
void stack_callback_handler(void *arg1,unsigned int event,void* pack_list)
{
	if((ADI_ETHER_BUFFER*)pack_list != NULL)
	{
		int int_sts = ker_disable_interrupts(ker_kPriorityLevelAll);
		switch(event)
		{
			case ADI_ETHER_EVENT_FRAME_RCVD:
					append_list(&rcv_list,(ADI_ETHER_BUFFER*)pack_list);
					
					break;
			
			case ADI_ETHER_EVENT_FRAME_XMIT:
					append_list(&xmt_list,(ADI_ETHER_BUFFER*)pack_list);
					
				break;
		
			case ADI_ETHER_EVENT_INTERRUPT:	
				break;
		}
		ker_enable_interrupts(int_sts);	
	}
}


/****************************************************************
 * Initializes the stack and starts the packet handler thread
 * with the supplied priority and the supplied thread pool time
 *
 * Buffer structure
 * 
 *   ---------  ----------  --------------- --------------->
 *     buffer_t  buffer_info buffer overhead  actual buffer
 *	 ---------  ----------  ---------------  -------------->
 ****************************************************************/

int init_stack(int inThreadPriority, int inThreadPollTime, int inMemSize, char *MemArea)
{
	int i,overhead=0;
	int nw_ifce_buffer_length = 0;
	int total_buffer_length =0;
	unsigned int LWIP_AREA_START=0;
	unsigned int BUFF_AREA_START=0;
	unsigned int BUFF_AREA_LEN=0; 
   	unsigned int buff_overhead;

	BUFF_AREA_START = (unsigned int)MemArea;
	BUFF_AREA_LEN   = (unsigned int)inMemSize;

	overhead        = sizeof(ADI_ETHER_BUFFER) + sizeof(struct buffer_info);

	// defined in the user configruation file.
	netinfo.num_if =	user_net_num_ifces;

	nw_ifce_buffer_length = 0;
			

	// Caluculate the total buffer space for rx/tx and for all n/w interfaces.
	//
	for (i = 0; i < netinfo.num_if; i += 1)
	{
		nw_ifce_buffer_length += user_net_config_info[i].rx_buffs * user_net_config_info[i].rx_buff_datalen;
		nw_ifce_buffer_length += user_net_config_info[i].tx_buffs * user_net_config_info[i].tx_buff_datalen;
		nw_ifce_buffer_length  += user_net_config_info[i].rx_buffs * overhead;
		nw_ifce_buffer_length  += user_net_config_info[i].tx_buffs * overhead;
	}

	// base address for major lwip data areas
	//
  	LWIP_AREA_START = BUFF_AREA_START+nw_ifce_buffer_length;
	
	// Initialize lwip stack modules.
	//
	lwip_init((u8_t*)LWIP_AREA_START);

	// Setup interface's and their associated buffers.
	//
	for (i = 0; i < netinfo.num_if; i += 1)
	{
		struct nifce_info* nip = &netinfo.vinfo[i];
		struct netif*  ni;
		void *handle = pli_services[i];

		nip->handle = handle;

		// Compute the size of the memory area with the user given pli buffer
		// size and its length.
		nw_ifce_buffer_length = 0;

		// Add rx buffer area
		nw_ifce_buffer_length += user_net_config_info[i].rx_buffs * user_net_config_info[i].rx_buff_datalen;

		// Add Tx buffer area.
		nw_ifce_buffer_length += user_net_config_info[i].tx_buffs * user_net_config_info[i].tx_buff_datalen;

		// reserve space for overhead also.
		nw_ifce_buffer_length  += user_net_config_info[i].rx_buffs * overhead;
		nw_ifce_buffer_length  += user_net_config_info[i].tx_buffs * overhead;

		nip->rx_buffs = user_net_config_info[i].rx_buffs;
		nip->tx_buffs = user_net_config_info[i].tx_buffs;
		nip->rx_buff_datalen = user_net_config_info[i].rx_buff_datalen;
		nip->tx_buff_datalen = user_net_config_info[i].tx_buff_datalen;
		nip->buff_area = (char*)(BUFF_AREA_START + total_buffer_length);
		nip->buff_area_size = nw_ifce_buffer_length;
		nip->use_DHCP = user_net_config_info[i].use_dhcp;

		// add it to the total length
		total_buffer_length += nw_ifce_buffer_length;

		// If DHCP is not enabled then we have user specified IP address,
		// Subnet mask, Gateway
		//
		if(nip->use_DHCP == 0)
		{
		IP4_ADDR(&netinfo.ipaddr[i],
				(user_net_config_info[i].ipaddr >> 24) & 0x000000ff , 
				(user_net_config_info[i].ipaddr >> 16) & 0x000000ff, 
				( user_net_config_info[i].ipaddr>> 8) & 0x000000ff,
				( user_net_config_info[i].ipaddr >> 0) & 0x000000ff);

		IP4_ADDR(&netinfo.netmask[i],
				(user_net_config_info[i].netmask >> 24) & 0x000000ff , 
				(user_net_config_info[i].netmask >> 16) & 0x000000ff, 
				( user_net_config_info[i].netmask>> 8) & 0x000000ff,
				( user_net_config_info[i].netmask >> 0) & 0x000000ff);

		IP4_ADDR(&netinfo.gateway[i],
				(user_net_config_info[i].gateway >> 24) & 0x000000ff , 
				(user_net_config_info[i].gateway >> 16) & 0x000000ff, 
				( user_net_config_info[i].gateway>> 8) & 0x000000ff,
				( user_net_config_info[i].gateway >> 0) & 0x000000ff);
		}

		// get if Mac address is specified. If user specified is 0 then
		// we will query the supllied IPLI to get the actual address.
		//
		if(memcmp(user_net_config_info[i].mac_addr,"\x00\x00\x00\x00\x00\x00",6))
		{
			memcpy(&netinfo.vinfo[i].ia[0], user_net_config_info[i].mac_addr, 6);
			adi_dev_Control(pli_services[i],ADI_ETHER_CMD_SET_MAC_ADDR,(void*)&user_net_config_info[i].mac_addr);
		}
		else
		{
		  // Applicatons must set up the physical address of the interface
		  // before.
		  char m_addr[] = { 0,0,0,0,0,0 };
		  adi_dev_Control(pli_services[i],ADI_ETHER_CMD_GET_MAC_ADDR,(void*)&m_addr);
		  memcpy(&netinfo.vinfo[i].ia[0],m_addr,6);
		}

		adi_dev_Control(pli_services[i],ADI_ETHER_CMD_GET_BUFFER_PREFIX,(void*)&buff_overhead);

        nip->buff_overhead = (size_t)buff_overhead;     

		ni = netinfo.netif[i] = netif_add(
								  &netinfo.ipaddr[i],
								  &netinfo.netmask[i],
								  &netinfo.gateway[i],
								  &netinfo.vinfo[i],
								  nifce_driver_init,
								  ip_input
								);
		LWIP_ASSERT("boot thread: failed to add network interface", ni != NULL);

#ifdef LWIP_DEBUG
		printf(
		  "Network Interface %c%c%d: %d.%d.%d.%d : "
		  "%02X-%02X-%02X-%02X-%02X-%02X : RX buffs = %d : TX buffs = %d\n",
		  ni->name[0], ni->name[1], ni->num,
		  ip4_addr1(&ni->ip_addr), ip4_addr2(&ni->ip_addr),
		  ip4_addr3(&ni->ip_addr), ip4_addr4(&ni->ip_addr),
		  ni->hwaddr[0], ni->hwaddr[1], ni->hwaddr[2],
		  ni->hwaddr[3], ni->hwaddr[4], ni->hwaddr[5],
		  ((struct nifce_info*)ni->state)->rx_buffs,
		  ((struct nifce_info*)ni->state)->tx_buffs
		);
#endif /* LWIP_DEBUG */

	}

  // set the default network interface
  //
  netif_set_default(netinfo.netif[0]);

  // start the ARP update thread
   etharp_timer_init();

  // Create pkthandler thread that processes the packets.
  //
  sys_thread_new(tcpip_q_callback,(void*)inThreadPollTime,inThreadPriority);
  return 1;
}

/****************************************************************
 * Invoked when users calls StartStack on the TCP/IP component.
 * Currently only DHCP configuration is checked. If DHCP is enabled
 * stack checks the DHCP server and gets the addres.
 ****************************************************************/
int start_stack()
{
 return dhcp_configure();
}

/****************************************************************
 * Gets the address from the DHCP server. DHCP is checked for only
 * the interface on which the DHCP is enabled in the UI.
 ****************************************************************/
int dhcp_configure(void)
{
  int i;
  long time_slept=0;
  int  success_flag = 1;
  dhcp_timer_init();
  
  for (i = 0; i < netinfo.num_if; i += 1) {
    struct netif* ni = netinfo.netif[i];

	if(user_net_config_info[i].use_dhcp == 1)
	{
		dhcp_start(ni);

		// Wait for 50ms and check for the DHCP status.
		//
		ker_sleep(50);
		while (*(volatile u8_t*)&ni->dhcp->state != DHCP_BOUND) {
		  // sleep for 500ms and check again, for 2 min..
			ker_sleep(500);
		  time_slept += 500;

		  if(time_slept > 120*1000)
		  {
			  success_flag = 0;
			  break;
		  }
		}

#ifdef _LWIP_DEBUG_
		printf(
		  "Network Interface %c%c%d: %d.%d.%d.%d : "
		  "%02X-%02X-%02X-%02X-%02X-%02X : RX buffs = %d : TX buffs = %d\n",
		  ni->name[0], ni->name[1], ni->num,
		  ip4_addr1(&ni->ip_addr), ip4_addr2(&ni->ip_addr),
		  ip4_addr3(&ni->ip_addr), ip4_addr4(&ni->ip_addr),
		  ni->hwaddr[0], ni->hwaddr[1], ni->hwaddr[2],
		  ni->hwaddr[3], ni->hwaddr[4], ni->hwaddr[5],
		  ((struct nifce_info*)ni->state)->rx_buffs,
		  ((struct nifce_info*)ni->state)->tx_buffs
		);
#endif /* _LWIP_DEBUG_ */
	}
  }
  return success_flag;
}

/****************************************************************
 * gethostaddr() gets the primary network interfaces IP address
 * in dot notation form.
 ****************************************************************/
int gethostaddr(int nwifce_no,char *host_addr)
{

	if(nwifce_no >= 0 && nwifce_no < netinfo.num_if)
	{
    	struct netif* ni = netinfo.netif[nwifce_no];
		u32_t ipaddr = ni->ip_addr.addr;
		u8_t *ip_in_dot = inet_ntoa(ipaddr);
		 memcpy(host_addr,ip_in_dot,16);
		 return 1;
	}
	return -1;
}

// sets the pli services for stack to use
int set_pli_services(int num_services, ADI_DEV_DEVICE_HANDLE *pservices)
{
	int i=0;
	for (i=0; i<num_services; i++)
			pli_services[i]= (ADI_DEV_DEVICE_HANDLE)pservices[i];
	return 1;
}
// return default gateway
struct ip_addr get_default_gateway()
{
	struct netif* ni = netinfo.netif[0];
	return (ni->gw);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -