0条评论
cmd_size = (uint8_t *)(auth + 1) - wifi_buffer_command;
if (security == WIFI_SECURITYTYPE_WPA || security == WIFI_SECURITYTYPE_WPA2)
{
// WPA网络必须在命令中加入Vendor参数才能成功连接
vendor = (MrvlIETypes_VendorParamSet_t *)(auth + 1);
memcpy(vendor, &wifi_ssid_info.wpa, TLV_STRUCTLEN(wifi_ssid_info.wpa));
cmd_size += TLV_STRUCTLEN(wifi_ssid_info.wpa);
}
然后在WiFi_EAPOLProcess函数中,也把添加RSN参数的代码去掉(选择WPA方式认证):/* 在待发送的Message 2中添加Key Data信息 */
// https://community.arubanetworks.com/t5/Technology-Blog/A-closer-look-at-WiFi-Security-IE-Information-Elements/ba-p/198867
// 使用WPA的热点一定有WPA IE信息项,一定没有RSN IE信息项
// 使用WPA2的热点一定有RSN IE信息项,可能有WPA IE信息项
packet_tx = (WiFi_EAPOLKeyFrame *)WiFi_GetPacketBuffer();
kde = (WiFi_KDE *)packet_tx->key_data;
if (wifi_ssid_info.wpa.header.type)
{
// 路由器提供了WPA IE信息项时可直接复制
//printf("WPA IE copied!
");
kde->type = WIFI_MRVLIETYPES_VENDORPARAMSET;
kde->length = wifi_ssid_info.wpa.header.length;
memcpy(kde->oui, wifi_ssid_info.wpa.vendor, wifi_ssid_info.wpa.header.length);
key_data_len = sizeof(kde->type) + sizeof(kde->length) + kde->length;
}
else
{
printf("IE not copied!
");
key_data_len = 0;
}
这样,关联时就会强制采用WPA方式认证,每次关联时都可以产生Group key handshake,不用再等上一天了。/* 获取RTC分频计数器的值 */
uint32_t rtc_divider(void)
{
uint32_t div[2];
do
{
div[0] = RTC_GetDivider();
div[1] = RTC_GetDivider();
} while ((div[0] >> 16) != (div[1] >> 16));
// RTC_GetDivider函数先读取DIVH再读取DIVL
// 如果更新发生在第一次读取DIVH或DIVL后, 则div[0]和div[1]的高16位不相等, 两个值都会被丢弃
// 如果更新发生在第二次读取DIVH后, 则div[0]和div[1]的高16位相等, 且div[0]值的高、低16位匹配,div[1]值的高、低16位不匹配
return div[0]; // 所以应该取第一次读取的值
}
/* RTC时间转化为毫秒数 (lwip协议栈要求实现的函数) */
// 该函数必须保证: 除非定时器溢出, 否则后获取的时间必须大于先获取的时间
uint32_t sys_now(void)
{
uint32_t sec[2];
uint32_t div, milli;
do
{
time(&sec[0]); // 秒
div = rtc_divider();
time(&sec[1]);
} while (sec[0] != sec[1]);
// CNT是在DIV从P-1跳变到P-2瞬间发生更新的 (P=RTC_PRESCALER)
if (div == RTC_PRESCALER - 1)
milli = div;
else
milli = RTC_PRESCALER - div - 2;
milli = milli * 1000 / RTC_PRESCALER; // 毫秒
return sec[0] * 1000 + milli;
}
/* 获取RTC秒数 */
time_t time(time_t *timer)
{
// CNTH和CNTL是同时更新的
// 但由于这两个寄存器不是同时读取的, 所以有可能一个读到的是更新前的值, 另一个读到的是更新后的值
uint32_t now[2];
do
{
now[0] = RTC_GetCounter();
now[1] = RTC_GetCounter();
} while ((now[0] >> 16) != (now[1] >> 16)); // 使用循环可以避免中断的影响
// RTC_GetCounter函数先读取CNTL再读取CNTH
// 如果更新发生在第一次读取CNTL后, 则now[0]和now[1]的高16位相等, 且now[0]值的高、低16位不匹配,now[1]值的高、低16位匹配
// 如果更新发生在第一次读取CNTH后或第二次读取CNTL后, 则now[0]和now[1]的高16位不相等, 两个值都会被丢弃
if (timer)
*timer = now[1];
return now[1]; // 所以应该取第二次读取的值
}
STM32F103RE SDIO 88W8686
RESPCMD63, RESP1_90ff8000
RESPCMD63, RESP1_90300000
Number of I/O Functions: 1
Memory Present: 0
Relative Card Address: 0x0001
Card selected! RESP1_00001e00
SDIO Clock: 24MHz
[CIS] func=0, ptr=0x00008000
Product Information: Marvell 802.11 SDIO ID: 0B
Manufacturer Code: 0x02df
Manufacturer Information: 0x9103
Card Function Code: 0x0c
System Initialization Bit Mask: 0x00
Maximum Block Size: 256
Maximum Transfer Rate Code: 0x32
[CIS] func=1, ptr=0x00008080
Card Function Code: 0x0c
System Initialization Bit Mask: 0x00
Maximum Block Size: 256
Firmware is successfully downloaded!
MAC Addr: 00:1A:6B:A4:AA:B4
SSID 'CMCC-EDU', MAC 96:14:4B:6F:A5:DA, RSSI 73, Channel 1
Capability: 0x0621 (Security: Unsecured, Mode: Infrastructure)
SSID 'CMCC-Young', MAC 96:14:4B:6F:A5:DB, RSSI 69, Channel 1
Capability: 0x0621 (Security: Unsecured, Mode: Infrastructure)
SSID '???????', MAC BC:46:99:9B:1E:E4, RSSI 71, Channel 1
Capability: 0x0431 (Security: WPA2, Mode: Infrastructure)
SSID 'CMCC-EDU', MAC E6:14:4B:57:40:0F, RSSI 75, Channel 1
Capability: 0x0621 (Security: Unsecured, Mode: Infrastructure)
SSID 'CMCC-Young', MAC E6:14:4B:57:40:00, RSSI 75, Channel 1
Capability: 0x0621 (Security: Unsecured, Mode: Infrastructure)
SSID 'CMCC-EDU', MAC F6:14:4B:6C:19:50, RSSI 86, Channel 6
Capability: 0x0621 (Security: Unsecured, Mode: Infrastructure)
SSID 'TP-LINK_PLC', MAC 30:FC:68:38:6E:2C, RSSI 66, Channel 6
Capability: 0x0431 (Security: WPA2, Mode: Infrastructure)
SSID 'TP-LINK_ORANGE', MAC B0:95:8E:05:82:CA, RSSI 56, Channel 6
Capability: 0x0431 (Security: WPA2, Mode: Infrastructure)
SSID 'vivo Y29L', MAC F4:29:81:98:F3:78, RSSI 49, Channel 6
Capability: 0x8431 (Security: WPA2, Mode: Infrastructure)
SSID 'CDU_Free', MAC D4:61:FE:71:36:D0, RSSI 72, Channel 6
Capability: 0x8421 (Security: Unsecured, Mode: Infrastructure)
SSID 'CDU', MAC D4:61:FE:71:36:D1, RSSI 73, Channel 6
Capability: 0x0431 (Security: WPA2, Mode: Infrastructure)
SSID 'CMCC-EDU', MAC D6:14:4B:6F:A6:0E, RSSI 58, Channel 11
Capability: 0x0621 (Security: Unsecured, Mode: Infrastructure)
SSID 'CMCC-Young', MAC D6:14:4B:6F:A6:0F, RSSI 58, Channel 11
Capability: 0x0621 (Security: Unsecured, Mode: Infrastructure)
SSID 'xgxy666', MAC DC:FE:18:67:76:14, RSSI 73, Channel 11
Capability: 0x0431 (Security: WPA2, Mode: Infrastructure)
SSID '10505diansai', MAC 50:FA:84:53:5B:8E, RSSI 77, Channel 13
Capability: 0x0411 (Security: WPA2, Mode: Infrastructure)
Scan finished!
Waiting for authentication!
Message 1 received!
Message 2 sent!
Message 3 received!
Message 4 sent!
Authenticated!
[Send] len=350
PTK & GTK set!
[Recv] len=351
[Send] len=350
[Recv] len=351
[Send] len=42
[Send] len=42
[Send] len=42
[Send] len=42
[Send] len=42
[Send] len=42
[Send] len=42
DHCP supplied address at 0.65s!
IP address: 192.168.43.64
Subnet mask: 255.255.255.0
Default gateway: 192.168.43.1
DNS Server: 192.168.43.1
[Send] len=42
Not in cache! err=-5
[Recv] len=42
[Send] len=76
[Recv] len=92
DNS Found IP: 106.186.126.193
Connecting to 106.186.126.193...
[Send] len=58
[Recv] len=58
Connected! err=0
Connection is successfully closed!
[Send] len=54
[Send] len=42
[Recv] len=54
[Send] len=54
[Send] len=42
[Send] len=42
[Send] len=42
[Recv] len=74
[Send] len=58
[Recv] len=54
[Recv] len=524
[Send] len=590
[Send] len=590
[Recv] len=54
[Send] len=590
[Recv] len=54
[Send] len=304
[Recv] len=54
[Recv] len=54
[Send] len=54
[Recv] len=74
[Send] len=58
[Recv] len=54
[Recv] len=488
[Send] len=590
[Send] len=349
[Recv] len=54
[Recv] len=54
[Send] len=54
[Recv] len=74
[Send] len=58
[Recv] len=54
[Recv] len=419
[Send] len=590
[Send] len=202
[Recv] len=54
[Recv] len=54
[Send] len=54
#include // http服务器
#include // NetBIOS服务
#include // DHCP客户端
#include // DNS客户端
#include // lwip_init函数所在的头文件
#include // sys_check_timeouts函数所在的头文件
#include // ethernet_input函数所在头文件
#include
#include
#include "common.h"
#include "WiFi.h"
// 这两个函数位于ethernetif.c中, 但没有头文件声明
err_t ethernetif_init(struct netif *netif);
void ethernetif_input(struct netif *netif);
// 这两个函数位于dns_test.c中
void dns_test(void);
void display_time(void);
static struct netif wifi_88w8686;
#if LWIP_DHCP
static uint32_t dhcp_start_time = 0;
#endif
int fputc(int ch, FILE *fp)
{
if (fp == stdout)
{
if (ch == '
')
{
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); // 等待前一字符发送完毕
USART_SendData(USART1, '
');
}
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, ch);
}
return ch;
}
/* 通知lwip网卡的连接状态 */
static void set_netif(struct netif *netif, uint8_t up)
{
if (up)
{
if (!netif_is_up(netif))
{
netif_set_up(netif);
#if LWIP_DHCP
dhcp_start(netif); // 路由器中显示的DHCP客户名称在ethernetif_init函数中设置
dhcp_start_time = sys_now();
#endif
}
}
else
{
netif_set_down(netif);
#if LWIP_DHCP
dhcp_release(netif);
dhcp_stop(netif);
#endif
}
}
/* WiFi认证成功回调函数 */
void WiFi_AuthenticationCompleteHandler(void)
{
printf("Authenticated!
");
set_netif(&wifi_88w8686, 1); // 在lwip中启用WiFi网卡
}
/* WiFi事件回调函数 */
void WiFi_EventHandler(const WiFi_Event *event)
{
printf("[Event %d] size=%d", event->event_id, event->header.length);
if (event->header.length >= sizeof(WiFi_Event) - sizeof(event->mac_addr))
printf(", reason=%d", event->reason_code);
if (event->header.length >= sizeof(WiFi_Event))
printf(", MAC: %02X:%02X:%02X:%02X:%02X:%02X", event->mac_addr[0], event->mac_addr[1], event->mac_addr[2], event->mac_addr[3], event->mac_addr[4], event->mac_addr[5]);
printf("
");
switch (event->event_id)
{
case 3:
// 收不到信号 (例如和手机热点建立连接后, 把手机拿走), WiFi模块不会自动重连
printf("Beacon Loss/Link Loss
");
set_netif(&wifi_88w8686, 0);
break;
case 4:
// Ad-Hoc网络中不止1个结点, 且连接数发生了变化
printf("The number of stations in this ad hoc newtork has changed!
");
set_netif(&wifi_88w8686, 1);
break;
case 8:
// 认证已解除 (例如手机关闭了热点, 或者连接路由器后因认证失败而自动断开连接)
printf("Deauthenticated!
");
set_netif(&wifi_88w8686, 0);
break;
case 9:
// 解除了关联
printf("Disassociated!
");
set_netif(&wifi_88w8686, 0);
break;
case 17:
// Ad-Hoc网络中只剩本结点
printf("All other stations have been away from this ad hoc network!
");
set_netif(&wifi_88w8686, 0);
break;
case 30:
printf("IBSS coalescing process is finished and BSSID has changed!
");
break;
}
if (event->header.length > sizeof(WiFi_Event))
dump_data(event + 1, event->header.length - sizeof(WiFi_Event));
}
/* WiFi模块收到新的数据帧 */
void WiFi_PacketHandler(const WiFi_DataRx *data)
{
ethernetif_input(&wifi_88w8686); // 交给lwip处理
}
void associate_callback(void *arg, void *data, WiFi_Status status)
{
switch (status)
{
case WIFI_STATUS_OK:
printf("Associated!
");
set_netif(&wifi_88w8686, 1); // 在lwip中启用WiFi网卡
break;
case WIFI_STATUS_NOTFOUND:
printf("SSID not found!
");
break;
case WIFI_STATUS_FAIL:
printf("Association failed!
");
break;
case WIFI_STATUS_INPROGRESS:
printf("Waiting for authentication!
");
break;
default:
printf("Unknown error! status=%d
", status);
}
}
void associate_example(void)
{
WiFi_Connection conn;
//WiFi_WEPKey wepkey = {0}; // 未使用的成员必须设为0
/*
conn.security = WIFI_SECURITYTYPE_WEP;
conn.ssid = "Oct1158-2";
conn.password = &wepkey;
wepkey.keys[0] = "1234567890123";
wepkey.index = 0; // 密钥序号必须要正确
WiFi_AssociateEx(&conn, WIFI_AUTH_MODE_OPEN, -1, associate_callback, NULL); // 开放系统方式
//WiFi_AssociateEx(&conn, WIFI_AUTH_MODE_SHARED, -1, associate_callback, NULL); // 共享密钥方式
*/
conn.security = WIFI_SECURITYTYPE_WPA; // WPA和WPA2都可以使用此选项
conn.ssid = "vivo Y29L";
conn.password = "2345678am"; // WPA密码直接指定, 不需要WiFi_WEPKey结构体
WiFi_AssociateEx(&conn, WIFI_AUTH_MODE_OPEN, -1, associate_callback, NULL); // 必须使用WIFI_AUTH_MODE_OPEN选项
}
void adhoc_callback(void *arg, void *data, WiFi_Status status)
{
if (status == WIFI_STATUS_OK)
printf("ADHOC %sed!
", (char *)arg);
else
printf("Cannot %s ADHOC!
", (char *)arg);
}
void adhoc_example(void)
{
WiFi_Connection conn;
WiFi_WEPKey wepkey = {0}; // 未使用的成员必须设为0
/*
conn.security = WIFI_SECURITYTYPE_WEP;
conn.ssid = "Octopus-WEP";
conn.password = &wepkey;
wepkey.keys[0] = "3132333435";
wepkey.index = 0; // 范围: 0~3
WiFi_JoinADHOCEx(&conn, -1, adhoc_callback, "join");
*/
///*
// 注意: 电脑上无论密码输入是否正确都可以连接, 但只有正确的密码才可以通信
conn.security = WIFI_SECURITYTYPE_WEP;
conn.ssid = "WM-G-MR-09";
conn.password = &wepkey;
wepkey.keys[0] = "1234567890123";
wepkey.index = 0;
WiFi_StartADHOCEx(&conn, adhoc_callback, "start");
//*/
/*
conn.security = WIFI_SECURITYTYPE_NONE;
conn.ssid = "Octopus-WEP";
WiFi_JoinADHOCEx(&conn, -1, adhoc_callback, "join");
*/
/*
conn.security = WIFI_SECURITYTYPE_NONE;
conn.ssid = "WM-G-MR-09";
WiFi_StartADHOCEx(&conn, adhoc_callback, "start");
*/
}
void scan_callback(void *arg, void *data, WiFi_Status status)
{
if (status == WIFI_STATUS_OK)
printf("Scan finished!
");
else
printf("Scan failed!
");
//adhoc_example();
associate_example();
}
// 获取网卡MAC地址成功后, 就立即将网卡添加到lwip中, 但暂不把网卡设为"已连接"状态
void mac_address_callback(void *arg, void *data, WiFi_Status status)
{
#if !LWIP_DHCP
struct ip4_addr ipaddr, netmask, gw;
#endif
if (status == WIFI_STATUS_OK)
{
WiFi_Scan(scan_callback, NULL); // 扫描热点
memcpy(wifi_88w8686.hwaddr, data, 6); // 将获得的MAC地址复制到全局变量中
printf("MAC Addr: %02X:%02X:%02X:%02X:%02X:%02X
", wifi_88w8686.hwaddr[0], wifi_88w8686.hwaddr[1], wifi_88w8686.hwaddr[2], wifi_88w8686.hwaddr[3], wifi_88w8686.hwaddr[4], wifi_88w8686.hwaddr[5]);
#if LWIP_DHCP
netif_add(&wifi_88w8686, IP_ADDR_ANY, IP_ADDR_ANY, IP_ADDR_ANY, NULL, ethernetif_init, ethernet_input);
#else
IP4_ADDR(&ipaddr, 192, 168, 43, 15); // IP地址
IP4_ADDR(&netmask, 255, 255, 255, 0); // 子网掩码
IP4_ADDR(&gw, 192, 168, 43, 1); // 网关
netif_add(&wifi_88w8686, &ipaddr, &netmask, &gw, NULL, ethernetif_init, ethernet_input); // 添加WiFi模块到lwip中
#if LWIP_DNS
IP4_ADDR(&ipaddr, 8, 8, 8, 8); // 首选DNS服务器
dns_setserver(0, &ipaddr);
IP4_ADDR(&ipaddr, 8, 8, 4, 4); // 备用DNS服务器
dns_setserver(1, &ipaddr);
#endif
#endif
netif_set_default(&wifi_88w8686); // 设为默认网卡
}
else
printf("Cannot get MAC address!
");
}
void stop_callback(void *arg, void *data, WiFi_Status status)
{
char *s1 = (char *)arg;
char *s2 = s1 + strlen(s1) + 1;
if (status == WIFI_STATUS_OK)
{
set_netif(&wifi_88w8686, 0);
printf("%s %s!
", s1, s2);
}
else
printf("%s not %s!
", s1, s2);
}
int main(void)
{
GPIO_InitTypeDef gpio;
USART_InitTypeDef usart;
#if LWIP_DHCP
struct dhcp *dhcp;
#endif
uint8_t data;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
// 串口发送引脚PA9设为复用推挽输出, 串口接收引脚PA10保持默认的浮空输入
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
gpio.GPIO_Pin = GPIO_Pin_9;
gpio.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpio);
USART_StructInit(&usart);
usart.USART_BaudRate = 115200;
USART_Init(USART1, &usart);
USART_Cmd(USART1, ENABLE);
printf("STM32F103RE SDIO 88W8686
");
rtc_init();
WiFi_Init();
WiFi_GetMACAddress(mac_address_callback, NULL);
lwip_init();
netbiosns_init();
netbiosns_set_name("STM32F103RE"); // 计算机名
httpd_init();
while (1)
{
// WiFi模块中断和超时处理
if (SDIO_GetFlagStatus(SDIO_FLAG_SDIOIT) == SET)
{
SDIO_ClearFlag(SDIO_FLAG_SDIOIT);
WiFi_Input();
}
else
WiFi_CheckTimeout();
// lwip协议栈定时处理函数
sys_check_timeouts();
// 显示DHCP获取到的IP地址
#if LWIP_DHCP
if (dhcp_supplied_address(&wifi_88w8686))
{
if (dhcp_start_time != 0)
{
printf("DHCP supplied address at %.2fs!
", (sys_now() - dhcp_start_time) / 1000.0);
dhcp_start_time = 0;
dhcp = netif_dhcp_data(&wifi_88w8686);
printf("IP address: %s
", ip4addr_ntoa(&dhcp->offered_ip_addr));
printf("Subnet mask: %s
", ip4addr_ntoa(&dhcp->offered_sn_mask));
printf("Default gateway: %s
", ip4addr_ntoa(&dhcp->offered_gw_addr));
#if LWIP_DNS
printf("DNS Server: %s
", ip4addr_ntoa(dns_getserver(0)));
dns_test();
#endif
}
}
#endif
// 串口调试命令
if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET)
{
data = USART_ReceiveData(USART1);
switch (data)
{
case 'A':
// 离开ADHOC网络
WiFi_StopADHOC(stop_callback, "ADHOC
0条评论
还没有人评论过~