diff --git a/ports/win32/pktdrv.c b/ports/win32/pktdrv.c index a77d510..2125392 100644 --- a/ports/win32/pktdrv.c +++ b/ports/win32/pktdrv.c @@ -94,6 +94,9 @@ struct packet_adapter { char buffer[PACKET_INPUT_BUFSIZE]; }; +static int get_link_state(struct packet_adapter *pa, NDIS_MEDIA_STATE *linkstate); + + /** Get a list of adapters * * @param adapter_list void* array: list where the adapters are stored @@ -173,10 +176,11 @@ get_adapter_index(const char* adapter_guid) * @param mac_addr the MAC address of the adapter is stored here (if != NULL) * @param input a function to call to receive a packet * @param arg argument to pass to input + * @param linkstate the initial link state * @return an adapter handle on success, NULL on failure */ void* -init_adapter(int adapter_num, char *mac_addr, input_fn input, void *arg) +init_adapter(int adapter_num, char *mac_addr, input_fn input, void *arg, enum link_adapter_event *linkstate) { char *AdapterList[MAX_NUM_ADAPTERS]; int i; @@ -185,6 +189,7 @@ init_adapter(int adapter_num, char *mac_addr, input_fn input, void *arg) PPACKET_OID_DATA ppacket_oid_data; unsigned char ethaddr[ETHARP_HWADDR_LEN]; struct packet_adapter *pa; + NDIS_MEDIA_STATE mediastate; pa = (struct packet_adapter *)malloc(sizeof(struct packet_adapter)); if (!pa) { @@ -285,6 +290,10 @@ init_adapter(int adapter_num, char *mac_addr, input_fn input, void *arg) } PacketInitPacket(pa->lpPacket,(char*)pa->buffer, sizeof(pa->buffer)); + if(get_link_state(pa, &mediastate)) { + *linkstate = (mediastate == NdisMediaStateConnected ? LINKEVENT_UP : LINKEVENT_DOWN); + } + return pa; } @@ -413,6 +422,34 @@ update_adapter(void *adapter) } } +/** Get the current linkg status + * @param adapter adapter handle received by a call to init_adapter + * @param linkstate the current link state + * @return 1: succeeded, 0: failed + */ +static int +get_link_state(struct packet_adapter *pa, NDIS_MEDIA_STATE *linkstate) +{ + int ret = 0; + if(pa != NULL) { + PPACKET_OID_DATA ppacket_oid_data; + + /* get the media connect status of the selected adapter */ + ppacket_oid_data = (PPACKET_OID_DATA)malloc(sizeof(PACKET_OID_DATA) + sizeof(NDIS_MEDIA_STATE)); + if (ppacket_oid_data != NULL) { + ppacket_oid_data->Oid = OID_GEN_MEDIA_CONNECT_STATUS; + ppacket_oid_data->Length = sizeof(NDIS_MEDIA_STATE); + if (PacketRequest(pa->lpAdapter, FALSE, ppacket_oid_data)) { + *linkstate = (*((PNDIS_MEDIA_STATE)(ppacket_oid_data->Data))); + ret = 1; + } + free(ppacket_oid_data); + } + } + + return ret; +} + /** * Check for link state changes. Called in the main loop: 'interrupt' mode is not * really supported :( @@ -426,23 +463,12 @@ link_adapter(void *adapter) struct packet_adapter *pa = (struct packet_adapter*)adapter; if (pa != NULL) { - PPACKET_OID_DATA ppacket_oid_data; - NDIS_MEDIA_STATE fNdisMediaState = pa->fNdisMediaState; - - /* get the media connect status of the selected adapter */ - ppacket_oid_data = (PPACKET_OID_DATA)malloc(sizeof(PACKET_OID_DATA) + sizeof(NDIS_MEDIA_STATE)); - if (ppacket_oid_data) { - ppacket_oid_data->Oid = OID_GEN_MEDIA_CONNECT_STATUS; - ppacket_oid_data->Length = sizeof(NDIS_MEDIA_STATE); - if (PacketRequest(pa->lpAdapter, FALSE, ppacket_oid_data)) { - fNdisMediaState = (*((PNDIS_MEDIA_STATE)(ppacket_oid_data->Data))); + NDIS_MEDIA_STATE fNdisMediaState; + if (get_link_state(pa, &fNdisMediaState)) { + if (pa->fNdisMediaState != fNdisMediaState) { + pa->fNdisMediaState = fNdisMediaState; + return ((fNdisMediaState == NdisMediaStateConnected) ? LINKEVENT_UP : LINKEVENT_DOWN); } - free(ppacket_oid_data); - } - - if (pa->fNdisMediaState != fNdisMediaState) { - pa->fNdisMediaState = fNdisMediaState; - return ((fNdisMediaState == NdisMediaStateConnected) ? LINKEVENT_UP : LINKEVENT_DOWN); } } diff --git a/ports/win32/pktdrv.h b/ports/win32/pktdrv.h index a1ea7f0..3a2e251 100644 --- a/ports/win32/pktdrv.h +++ b/ports/win32/pktdrv.h @@ -13,7 +13,7 @@ enum link_adapter_event { LINKEVENT_DOWN }; -void* init_adapter (int adapter_num, char *mac_addr, input_fn input, void *arg); +void* init_adapter (int adapter_num, char *mac_addr, input_fn input, void *arg, enum link_adapter_event *linkstate); void shutdown_adapter(void *adapter); int packet_send (void *adapter, void *buffer, int len); void update_adapter (void *adapter); diff --git a/ports/win32/pktif.c b/ports/win32/pktif.c index ae5f740..bfabead 100644 --- a/ports/win32/pktif.c +++ b/ports/win32/pktif.c @@ -107,9 +107,9 @@ /* link state notification macro */ #if NO_SYS -#define NOTIFY_LINKSTATE(netif,linkfunc) linkfunc(netif) +#define NOTIFY_LINKSTATE(netif, linkfunc) linkfunc(netif) #else /* NO_SYS*/ -#define NOTIFY_LINKSTATE(netif,linkfunc) tcpip_timeout(PHY_LINKUP_DELAY, (sys_timeout_handler)linkfunc, netif) +#define NOTIFY_LINKSTATE(netif, linkfunc) tcpip_timeout(PHY_LINKUP_DELAY, (sys_timeout_handler)linkfunc, netif) #endif /* NO_SYS*/ /* Forward declarations. */ @@ -122,6 +122,7 @@ low_level_init(struct netif *netif) char adapter_mac_addr[ETHARP_HWADDR_LEN]; u8_t my_mac_addr[ETHARP_HWADDR_LEN] = LWIP_MAC_ADDR_BASE; int adapter_num = PACKET_LIB_ADAPTER_NR; + enum link_adapter_event linkstate; #ifdef PACKET_LIB_ADAPTER_GUID /* get adapter index for guid string */ @@ -135,7 +136,7 @@ low_level_init(struct netif *netif) /* Do whatever else is needed to initialize interface. */ if ((netif->state = init_adapter(adapter_num, adapter_mac_addr, - ethernetif_process_input, netif)) == NULL) { + ethernetif_process_input, netif, &linkstate)) == NULL) { printf("ERROR initializing network adapter %d!\n", PACKET_LIB_ADAPTER_NR); LWIP_ASSERT("ERROR initializing network adapter!\n", 0); return; @@ -147,6 +148,12 @@ low_level_init(struct netif *netif) /* Copy MAC addr */ memcpy(&netif->hwaddr, my_mac_addr, ETHARP_HWADDR_LEN); + if (linkstate == LINKEVENT_UP) { + netif_set_link_up(netif); + } else { + netif_set_link_down(netif); + } + LWIP_DEBUGF(NETIF_DEBUG, ("pktif: eth_addr %02X%02X%02X%02X%02X%02X\n",netif->hwaddr[0],netif->hwaddr[1],netif->hwaddr[2],netif->hwaddr[3],netif->hwaddr[4],netif->hwaddr[5])); } @@ -361,11 +368,12 @@ ethernetif_init(struct netif *netif) #endif /* LWIP_NETIF_HOSTNAME */ netif->mtu = 1500; - netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP | NETIF_FLAG_LINK_UP; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP; netif->hwaddr_len = ETHARP_HWADDR_LEN; NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 100000000); + /* sets link up or down based on current status */ low_level_init(netif); return ERR_OK; @@ -382,7 +390,6 @@ ethernetif_poll(struct netif *netif) { update_adapter(netif->state); -#if LWIP_NETIF_LINK_CALLBACK /* Process the link status change */ switch (link_adapter(netif->state)) { case LINKEVENT_UP: { @@ -394,7 +401,6 @@ ethernetif_poll(struct netif *netif) break; } } -#endif /* LWIP_NETIF_LINK_CALLBACK */ } /*-----------------------------------------------------------------------------------*/