This commit is contained in:
pvvx 2017-04-23 12:27:41 +03:00
parent 88eff2e9c2
commit 5c5f5e9b5a
18 changed files with 2484 additions and 3181 deletions

View file

@ -1068,6 +1068,7 @@ int wifi_off(void) {
#if CONFIG_LWIP_LAYER #if CONFIG_LWIP_LAYER
dhcps_deinit(); dhcps_deinit();
LwIP_DHCP(0, DHCP_STOP); LwIP_DHCP(0, DHCP_STOP);
LwIP_DHCP(1, DHCP_STOP);
#endif #endif
#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP #if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP
if ((wifi_mode == RTW_MODE_AP) || (wifi_mode == RTW_MODE_STA_AP)) if ((wifi_mode == RTW_MODE_AP) || (wifi_mode == RTW_MODE_STA_AP))

View file

@ -57,7 +57,7 @@ WIFI_CONFIG wifi_cfg = {
SOFTAP_CONFIG wifi_ap_cfg = { SOFTAP_CONFIG wifi_ap_cfg = {
.ssid = DEF_AP_SSID, .ssid = DEF_AP_SSID,
.password = DEF_AP_PASSWORD, .password = DEF_AP_PASSWORD,
.security_type = DEF_AP_SECURITY, .security_type = DEF_AP_SECURITY, // RTW_SECURITY_WPA2_AES_PSK or RTW_SECURITY_OPEN
.beacon_interval = DEF_AP_BEACON, .beacon_interval = DEF_AP_BEACON,
.channel = DEF_AP_CHANNEL, .channel = DEF_AP_CHANNEL,
.ssid_hidden = 0, .ssid_hidden = 0,
@ -185,7 +185,7 @@ char wlan_st_netifn = 0;
char wlan_ap_netifn = 1; char wlan_ap_netifn = 1;
extern rtw_mode_t wifi_mode; // новый режим работы extern rtw_mode_t wifi_mode; // новый режим работы
uint8 chk_ap_netif_num(void) LOCAL uint8 chk_ap_netif_num(void)
{ {
if (wifi_mode == RTW_MODE_AP) { if (wifi_mode == RTW_MODE_AP) {
wlan_st_name[4] = '1'; wlan_st_name[4] = '1';
@ -204,7 +204,6 @@ uint8 chk_ap_netif_num(void)
rtw_result_t wifi_run_ap(void) { rtw_result_t wifi_run_ap(void) {
chk_ap_netif_num(); chk_ap_netif_num();
rtw_result_t ret = RTW_NOTAP; rtw_result_t ret = RTW_NOTAP;
if( (wifi_mode == RTW_MODE_AP) || (wifi_mode == RTW_MODE_STA_AP) ){ if( (wifi_mode == RTW_MODE_AP) || (wifi_mode == RTW_MODE_STA_AP) ){
info_printf("Starting AP (%s, netif%d)...\n", wlan_ap_name, wlan_ap_netifn); info_printf("Starting AP (%s, netif%d)...\n", wlan_ap_name, wlan_ap_netifn);
@ -245,6 +244,7 @@ rtw_result_t wifi_run_ap(void) {
info_printf("AP '%s' started after %d ms\n", info_printf("AP '%s' started after %d ms\n",
wifi_ap_cfg.ssid, xTaskGetTickCount()); wifi_ap_cfg.ssid, xTaskGetTickCount());
show_wifi_ap_ip(); show_wifi_ap_ip();
show_wifi_st_ip();
if(wifi_cfg.save_flg & (BID_WIFI_AP_CFG | BID_AP_DHCP_CFG)) if(wifi_cfg.save_flg & (BID_WIFI_AP_CFG | BID_AP_DHCP_CFG))
write_wifi_cfg(wifi_cfg.save_flg & (BID_WIFI_AP_CFG | BID_AP_DHCP_CFG)); write_wifi_cfg(wifi_cfg.save_flg & (BID_WIFI_AP_CFG | BID_AP_DHCP_CFG));
ret = RTW_SUCCESS; ret = RTW_SUCCESS;
@ -264,7 +264,7 @@ rtw_result_t wifi_run_ap(void) {
return ret; return ret;
} }
rtw_result_t StartStDHCPClient(void) LOCAL rtw_result_t StartStDHCPClient(void)
{ {
debug_printf("Start DHCPClient...\n"); debug_printf("Start DHCPClient...\n");
int ret = RTW_SUCCESS; int ret = RTW_SUCCESS;
@ -274,12 +274,10 @@ rtw_result_t StartStDHCPClient(void)
if((mode == 3) // Auto fix if((mode == 3) // Auto fix
&& p->ip != IP4ADDR(255,255,255,255) && p->ip != IP4ADDR(255,255,255,255)
&& p->ip != IP4ADDR(0,0,0,0)) { && p->ip != IP4ADDR(0,0,0,0)) {
// mode = 2; // fixed ip
} }
else mode = 1; // DHCP On else mode = 1; // DHCP On
if(mode == 2) { // fixed ip if(mode == 2) { // fixed ip
netif_set_addr(pnetif, (ip_addr_t *)&p->ip, (ip_addr_t *)&p->mask, (ip_addr_t *)&p->gw); netif_set_addr(pnetif, (ip_addr_t *)&p->ip, (ip_addr_t *)&p->mask, (ip_addr_t *)&p->gw);
// dhcps_init(pnetif);
} }
else if(mode) { else if(mode) {
UBaseType_t savePriority = uxTaskPriorityGet(NULL); UBaseType_t savePriority = uxTaskPriorityGet(NULL);
@ -357,7 +355,6 @@ LOCAL void wifi_autoreconnect_hdl_(rtw_security_t security_type, char *ssid,
&wifi_autoreconnect, tskIDLE_PRIORITY + 1, NULL); &wifi_autoreconnect, tskIDLE_PRIORITY + 1, NULL);
} }
LOCAL void st_set_autoreconnect(uint8 mode, uint8 count, uint16 timeout) { LOCAL void st_set_autoreconnect(uint8 mode, uint8 count, uint16 timeout) {
p_wlan_autoreconnect_hdl = wifi_autoreconnect_hdl_; p_wlan_autoreconnect_hdl = wifi_autoreconnect_hdl_;
_adapter * ad = *(_adapter **)((rltk_wlan_info[0].dev)->priv); _adapter * ad = *(_adapter **)((rltk_wlan_info[0].dev)->priv);
@ -367,7 +364,6 @@ LOCAL void st_set_autoreconnect(uint8 mode, uint8 count, uint16 timeout) {
ad->mlmeextpriv.auto_reconnect = (mode != 0); ad->mlmeextpriv.auto_reconnect = (mode != 0);
} }
rtw_result_t wifi_run_st(void) { rtw_result_t wifi_run_st(void) {
rtw_result_t ret = RTW_SUCCESS; rtw_result_t ret = RTW_SUCCESS;
chk_ap_netif_num(); chk_ap_netif_num();
@ -427,6 +423,7 @@ int _wifi_on(rtw_mode_t mode) {
} }
wifi_mode = mode; wifi_mode = mode;
info_printf("Initializing WIFI...\n"); info_printf("Initializing WIFI...\n");
// set wifi mib // set wifi mib
// adaptivity // adaptivity
wext_set_adaptivity(RTW_ADAPTIVITY_DISABLE); wext_set_adaptivity(RTW_ADAPTIVITY_DISABLE);
@ -438,9 +435,13 @@ int _wifi_on(rtw_mode_t mode) {
ret = rltk_wlan_init(0, mode); ret = rltk_wlan_init(0, mode);
if (ret < 0) return ret; if (ret < 0) return ret;
if(devnum) { if(devnum) {
netif_set_up(&xnetif[1]);
ret = rltk_wlan_init(1, mode); ret = rltk_wlan_init(1, mode);
if (ret < 0) return ret; if (ret < 0) return ret;
} }
else {
netif_set_down(&xnetif[1]);
}
rltk_wlan_start(0); rltk_wlan_start(0);
if(devnum) rltk_wlan_start(1); if(devnum) rltk_wlan_start(1);
while (1) { while (1) {
@ -506,35 +507,23 @@ int wifi_run(rtw_mode_t mode) {
#if CONFIG_DEBUG_LOG > 4 #if CONFIG_DEBUG_LOG > 4
debug_printf("\n%s(%d), %d\n", __func__, mode, wifi_run_mode); debug_printf("\n%s(%d), %d\n", __func__, mode, wifi_run_mode);
#endif #endif
if(wifi_run_mode & RTW_MODE_AP) { if(wifi_run_mode != mode) {
info_printf("Deinit old AP...\n"); if(wifi_run_mode & RTW_MODE_AP) {
LwIP_DHCP(WLAN_AP_NETIF_NUM, DHCP_STOP);
#if CONFIG_DEBUG_LOG > 4 #if CONFIG_DEBUG_LOG > 4
debug_printf("dhcps_deinit()\n"); debug_printf("dhcps_deinit()\n");
#endif #endif
dhcps_deinit(); dhcps_deinit();
wifi_run_mode &= ~RTW_MODE_AP; }
}; info_printf("Deinitializing WIFI ...\n");
if(wifi_run_mode & RTW_MODE_STA) { wifi_off();
info_printf("Deinit old ST...\n"); wifi_run_mode = RTW_MODE_NONE;
LwIP_DHCP(WLAN_ST_NETIF_NUM, DHCP_STOP); vTaskDelay(30);
wifi_run_mode &= ~RTW_MODE_STA; if (_wifi_on(mode) < 0) {
}; error_printf("Wifi On failed!\n");
// if(mode != wifi_mode) goto error_end;
// wifi_mode = mode;
// chk_ap_netif_num();
if (mode != RTW_MODE_NONE) {
if(mode != (volatile)wifi_mode) {
info_printf("Deinitializing WIFI ...\n");
wifi_off();
vTaskDelay(30);
debug_printf("WiFi_on(%d)\n", mode);
if (_wifi_on(mode) < 0) {
error_printf("Wifi On failed!\n");
goto error_end;
};
wifi_mode = mode;
}; };
};
if (mode != RTW_MODE_NONE) {
if(wifi_set_country(wifi_cfg.country_code) != RTW_SUCCESS) { if(wifi_set_country(wifi_cfg.country_code) != RTW_SUCCESS) {
error_printf("Error set tx country_code (%d)!", wifi_cfg.country_code); error_printf("Error set tx country_code (%d)!", wifi_cfg.country_code);
}; };
@ -548,9 +537,7 @@ int wifi_run(rtw_mode_t mode) {
error_printf("Error set network mode (%d)!", wifi_cfg.bgn); error_printf("Error set network mode (%d)!", wifi_cfg.bgn);
} }
debug_printf("mode == wifi_mode? (%d == %d?)\n", mode, wifi_mode); debug_printf("mode == wifi_mode? (%d == %d?)\n", mode, wifi_mode);
// if(mode == wifi_mode) switch(wifi_mode) {
{
switch(wifi_mode) {
case RTW_MODE_STA_AP: case RTW_MODE_STA_AP:
wifi_run_ap(); wifi_run_ap();
wifi_run_st(); wifi_run_st();
@ -571,16 +558,14 @@ int wifi_run(rtw_mode_t mode) {
#endif #endif
default: default:
error_printf("Error WiFi mode(%d)\n", wifi_mode); error_printf("Error WiFi mode(%d)\n", wifi_mode);
} }
#if CONFIG_INTERACTIVE_MODE #if CONFIG_INTERACTIVE_MODE
/* Initial uart rx swmaphore*/ /* Initial uart rx swmaphore*/
vSemaphoreCreateBinary(uart_rx_interrupt_sema); vSemaphoreCreateBinary(uart_rx_interrupt_sema);
xSemaphoreTake(uart_rx_interrupt_sema, 1/portTICK_RATE_MS); xSemaphoreTake(uart_rx_interrupt_sema, 1/portTICK_RATE_MS);
start_interactive_mode(); start_interactive_mode();
#endif #endif
// if(wifi_run_mode == wifi_cfg.mode) ret = 1;
ret = 1;
};
} else { } else {
ret = 1; ret = 1;
error_end: error_end:
@ -610,31 +595,30 @@ void wifi_init(void) {
wifi_run(wifi_cfg.mode); wifi_run(wifi_cfg.mode);
} }
rtw_security_t translate_rtw_security(u8 security_type) uint32 tab_rtw_security[] = {
{ RTW_SECURITY_OPEN, //0 Open security
rtw_security_t security_mode = RTW_SECURITY_OPEN; RTW_SECURITY_WEP_PSK, //1 WEP Security with open authentication
RTW_SECURITY_WEP_SHARED, //2 WEP Security with shared authentication
RTW_SECURITY_WPA_TKIP_PSK, //3 WPA Security with TKIP
RTW_SECURITY_WPA_AES_PSK, //4 WPA Security with AES
RTW_SECURITY_WPA2_AES_PSK, //5 WPA2 Security with AES
RTW_SECURITY_WPA2_TKIP_PSK, //6 WPA2 Security with TKIP
RTW_SECURITY_WPA2_MIXED_PSK,//7 WPA2 Security with AES & TKIP
RTW_SECURITY_WPA_WPA2_MIXED //8 WPA/WPA2 Security
};
switch (security_type) {
// case RTW_ENCRYPTION_OPEN: rtw_security_t translate_val_to_rtw_security(uint8 security_type)
// security_mode = RTW_SECURITY_OPEN; {
// break; if(security_type > 8) security_type = 5;
case RTW_ENCRYPTION_WEP40: return (rtw_security_t)tab_rtw_security[security_type];
case RTW_ENCRYPTION_WEP104: }
security_mode = RTW_SECURITY_WEP_PSK;
break; uint8 translate_rtw_security_to_val(rtw_security_t security_type)
case RTW_ENCRYPTION_WPA_TKIP: {
case RTW_ENCRYPTION_WPA_AES: uint8 i = 0;
case RTW_ENCRYPTION_WPA2_TKIP: while(i < 9 && tab_rtw_security[i] != security_type) i++;
case RTW_ENCRYPTION_WPA2_AES: return i;
case RTW_ENCRYPTION_WPA2_MIXED:
security_mode = RTW_SECURITY_WPA2_AES_PSK;
break;
// case RTW_ENCRYPTION_UNKNOWN:
// case RTW_ENCRYPTION_UNDEF:
// default:
//security_mode = RTW_SECURITY_OPEN;
}
return security_mode;
} }

View file

@ -63,7 +63,7 @@ typedef struct _wifi_config {
typedef struct _softap_config { typedef struct _softap_config {
unsigned char ssid[NDIS_802_11_LENGTH_SSID]; unsigned char ssid[NDIS_802_11_LENGTH_SSID];
unsigned char password[IW_PASSPHRASE_MAX_SIZE]; unsigned char password[IW_PASSPHRASE_MAX_SIZE];
rtw_security_t security_type; // RTW_SECURITY_OPEN, RTW_SECURITY_WEP_PSK rtw_security_t security_type; // RTW_SECURITY_WPA2_AES_PSK or RTW_SECURITY_OPEN
uint16 beacon_interval; // Note: support 100 ~ 60000 ms, default 100 uint16 beacon_interval; // Note: support 100 ~ 60000 ms, default 100
unsigned char channel; // 1..14 unsigned char channel; // 1..14
unsigned char ssid_hidden; // Note: default 0 unsigned char ssid_hidden; // Note: default 0
@ -122,6 +122,9 @@ uint32 write_wifi_cfg(uint32 flg);
int wifi_run(rtw_mode_t mode); int wifi_run(rtw_mode_t mode);
void wifi_init(void); void wifi_init(void);
rtw_security_t translate_val_to_rtw_security(uint8 security_type);
uint8 translate_rtw_security_to_val(rtw_security_t security_type);
void _LwIP_Init(void); void _LwIP_Init(void);
#endif // _WIFI_API_H_ #endif // _WIFI_API_H_

View file

@ -1,4 +1,5 @@
#include "dhcp.h"
#include "dhcps.h" #include "dhcps.h"
#include "tcpip.h" #include "tcpip.h"
@ -25,7 +26,7 @@ static struct ip_addr dhcps_owned_first_ip;
static struct ip_addr dhcps_owned_last_ip; static struct ip_addr dhcps_owned_last_ip;
static uint8_t dhcps_num_of_available_ips; static uint8_t dhcps_num_of_available_ips;
#endif #endif
static struct dhcp_msg *dhcp_message_repository; static struct dhcps_msg *dhcp_message_repository;
static int dhcp_message_total_options_lenth; static int dhcp_message_total_options_lenth;
/* allocated IP range */ /* allocated IP range */
@ -162,13 +163,25 @@ static void add_offer_options(uint8_t *option_start_address)
This option specifies the Maximum transmission unit to use */ This option specifies the Maximum transmission unit to use */
temp_option_addr = fill_one_option_content(temp_option_addr, temp_option_addr = fill_one_option_content(temp_option_addr,
DHCP_OPTION_CODE_INTERFACE_MTU, DHCP_OPTION_LENGTH_TWO, DHCP_OPTION_CODE_INTERFACE_MTU, DHCP_OPTION_LENGTH_TWO,
(void *) &dhcp_option_interface_mtu_576); (void *) &dhcp_option_interface_mtu);
/* add DHCP options 31. /* add DHCP options 31.
This option specifies whether or not the client should solicit routers */ This option specifies whether or not the client should solicit routers */
temp_option_addr = fill_one_option_content(temp_option_addr, temp_option_addr = fill_one_option_content(temp_option_addr,
DHCP_OPTION_CODE_PERFORM_ROUTER_DISCOVERY, DHCP_OPTION_LENGTH_ONE, DHCP_OPTION_CODE_PERFORM_ROUTER_DISCOVERY, DHCP_OPTION_LENGTH_ONE,
NULL); NULL);
*temp_option_addr++ = DHCP_OPTION_CODE_END; #if LWIP_NETIF_HOSTNAME
/* add DHCP options 12 HostName */
const char *p = dhcps_netif->hostname;
uint8_t len;
if(p && (len = strlen(p)) != 0) {
*temp_option_addr++ = DHCP_OPTION_HOSTNAME;
*temp_option_addr++ = len;
while(len--) {
*temp_option_addr++ = *p++;
}
}
#endif
*temp_option_addr = DHCP_OPTION_CODE_END;
} }
@ -178,7 +191,7 @@ static void add_offer_options(uint8_t *option_start_address)
* @param m the pointer which point to the dhcp message store in. * @param m the pointer which point to the dhcp message store in.
* @retval None. * @retval None.
*/ */
static void dhcps_initialize_message(struct dhcp_msg *dhcp_message_repository, struct ip_addr yiaddr) static void dhcps_initialize_message(struct dhcps_msg *dhcp_message_repository, struct ip_addr yiaddr)
{ {
dhcp_message_repository->op = DHCP_MESSAGE_OP_REPLY; dhcp_message_repository->op = DHCP_MESSAGE_OP_REPLY;
@ -220,7 +233,7 @@ static void dhcps_initialize_message(struct dhcp_msg *dhcp_message_repository, s
static void dhcps_send_offer(struct pbuf *packet_buffer) static void dhcps_send_offer(struct pbuf *packet_buffer)
{ {
uint8_t temp_ip = 0; uint8_t temp_ip = 0;
dhcp_message_repository = (struct dhcp_msg *)packet_buffer->payload; dhcp_message_repository = (struct dhcps_msg *)packet_buffer->payload;
#if (!IS_USE_FIXED_IP) #if (!IS_USE_FIXED_IP)
if ((ip4_addr4(&dhcps_allocated_client_address) != 0) && if ((ip4_addr4(&dhcps_allocated_client_address) != 0) &&
(memcmp((void *)&dhcps_allocated_client_address, (void *)&client_request_ip, 4) == 0) && (memcmp((void *)&dhcps_allocated_client_address, (void *)&client_request_ip, 4) == 0) &&
@ -271,7 +284,7 @@ static void dhcps_send_nak(struct pbuf *packet_buffer)
struct ip_addr zero_address; struct ip_addr zero_address;
IP4_ADDR(&zero_address, 0, 0, 0, 0); IP4_ADDR(&zero_address, 0, 0, 0, 0);
dhcp_message_repository = (struct dhcp_msg *)packet_buffer->payload; dhcp_message_repository = (struct dhcps_msg *)packet_buffer->payload;
dhcps_initialize_message(dhcp_message_repository, zero_address); dhcps_initialize_message(dhcp_message_repository, zero_address);
add_msg_type(&dhcp_message_repository->options[4], DHCP_MESSAGE_TYPE_NAK); add_msg_type(&dhcp_message_repository->options[4], DHCP_MESSAGE_TYPE_NAK);
udp_sendto_if(dhcps_pcb, packet_buffer, udp_sendto_if(dhcps_pcb, packet_buffer,
@ -285,7 +298,7 @@ static void dhcps_send_nak(struct pbuf *packet_buffer)
*/ */
static void dhcps_send_ack(struct pbuf *packet_buffer) static void dhcps_send_ack(struct pbuf *packet_buffer)
{ {
dhcp_message_repository = (struct dhcp_msg *)packet_buffer->payload; dhcp_message_repository = (struct dhcps_msg *)packet_buffer->payload;
dhcps_initialize_message(dhcp_message_repository, dhcps_allocated_client_address); dhcps_initialize_message(dhcp_message_repository, dhcps_allocated_client_address);
add_offer_options(add_msg_type(&dhcp_message_repository->options[4], add_offer_options(add_msg_type(&dhcp_message_repository->options[4],
DHCP_MESSAGE_TYPE_ACK)); DHCP_MESSAGE_TYPE_ACK));
@ -407,7 +420,7 @@ static uint8_t dhcps_handle_msg_options(uint8_t *option_start, int16_t total_opt
static uint8_t dhcps_check_msg_and_handle_options(struct pbuf *packet_buffer) static uint8_t dhcps_check_msg_and_handle_options(struct pbuf *packet_buffer)
{ {
int dhcp_message_option_offset; int dhcp_message_option_offset;
dhcp_message_repository = (struct dhcp_msg *)packet_buffer->payload; dhcp_message_repository = (struct dhcps_msg *)packet_buffer->payload;
memcpy(dhcp_client_ethernet_address, dhcp_message_repository->chaddr, sizeof(dhcp_client_ethernet_address)); memcpy(dhcp_client_ethernet_address, dhcp_message_repository->chaddr, sizeof(dhcp_client_ethernet_address));
dhcp_message_option_offset = ((int)dhcp_message_repository->options dhcp_message_option_offset = ((int)dhcp_message_repository->options
- (int)packet_buffer->payload); - (int)packet_buffer->payload);
@ -435,7 +448,7 @@ struct pbuf *udp_packet_buffer, struct ip_addr *sender_addr, uint16_t sender_por
int16_t total_length_of_packet_buffer; int16_t total_length_of_packet_buffer;
struct pbuf *merged_packet_buffer = NULL; struct pbuf *merged_packet_buffer = NULL;
dhcp_message_repository = (struct dhcp_msg *)udp_packet_buffer->payload; dhcp_message_repository = (struct dhcps_msg *)udp_packet_buffer->payload;
if (udp_packet_buffer == NULL) { if (udp_packet_buffer == NULL) {
printf("Error! System doesn't allocate any buffer\n"); printf("Error! System doesn't allocate any buffer\n");
return; return;

View file

@ -65,7 +65,7 @@
#define HW_ADDRESS_LENGTH (6) #define HW_ADDRESS_LENGTH (6)
/* Reference by RFC 2131 */ /* Reference by RFC 2131 */
struct dhcp_msg { struct dhcps_msg {
uint8_t op; /* Message op code/message type. 1 = BOOTREQUEST, 2 = BOOTREPLY */ uint8_t op; /* Message op code/message type. 1 = BOOTREQUEST, 2 = BOOTREPLY */
uint8_t htype; /* Hardware address type */ uint8_t htype; /* Hardware address type */
uint8_t hlen; /* Hardware address length */ uint8_t hlen; /* Hardware address length */
@ -92,8 +92,13 @@ struct dhcp_msg {
/* use this to check whether the message is dhcp related or not */ /* use this to check whether the message is dhcp related or not */
static const uint8_t dhcp_magic_cookie[4] = {99, 130, 83, 99}; static const uint8_t dhcp_magic_cookie[4] = {99, 130, 83, 99};
static const uint8_t dhcp_option_lease_time_one_day[] = {0x00, 0x01, 0x51, 0x80}; static const uint8_t dhcp_option_lease_time_one_day[] = {0x00, 0x01, 0x51, 0x80};
static const uint8_t dhcp_option_interface_mtu_576[] = {0x02, 0x40};
#ifdef CLASS_B_NET
static const uint8_t dhcp_option_interface_mtu[] = {0x05, 0xDC}; // 1500
#else
static const uint8_t dhcp_option_interface_mtu[] = {0x02, 0x40}; // 576
#endif
struct table { struct table {
uint32_t ip_range[8]; uint32_t ip_range[8];

View file

@ -1,727 +0,0 @@
/**
* @file
* SNTP client module
*/
/*
* Copyright (c) 2007-2009 Frédéric Bernon, Simon Goldschmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Frédéric Bernon, Simon Goldschmidt
*/
/**
* @defgroup sntp SNTP
* @ingroup apps
*
* This is simple "SNTP" client for the lwIP raw API.
* It is a minimal implementation of SNTPv4 as specified in RFC 4330.
*
* For a list of some public NTP servers, see this link :
* http://support.ntp.org/bin/view/Servers/NTPPoolServers
*
* @todo:
* - set/change servers at runtime
* - complete SNTP_CHECK_RESPONSE checks 3 and 4
*/
#include "lwip/apps/sntp.h"
#include "lwip/opt.h"
#include "lwip/timeouts.h"
#include "lwip/udp.h"
#include "lwip/dns.h"
#include "lwip/ip_addr.h"
#include "lwip/pbuf.h"
#include "lwip/dhcp.h"
#include <string.h>
#include <time.h>
#if LWIP_UDP
/* Handle support for more than one server via SNTP_MAX_SERVERS */
#if SNTP_MAX_SERVERS > 1
#define SNTP_SUPPORT_MULTIPLE_SERVERS 1
#else /* NTP_MAX_SERVERS > 1 */
#define SNTP_SUPPORT_MULTIPLE_SERVERS 0
#endif /* NTP_MAX_SERVERS > 1 */
#if (SNTP_UPDATE_DELAY < 15000) && !defined(SNTP_SUPPRESS_DELAY_CHECK)
#error "SNTPv4 RFC 4330 enforces a minimum update time of 15 seconds (define SNTP_SUPPRESS_DELAY_CHECK to disable this error)!"
#endif
/* Configure behaviour depending on microsecond or second precision */
#ifdef SNTP_SET_SYSTEM_TIME_US
#define SNTP_CALC_TIME_US 1
#define SNTP_RECEIVE_TIME_SIZE 2
#else
#define SNTP_SET_SYSTEM_TIME_US(sec, us)
#define SNTP_CALC_TIME_US 0
#define SNTP_RECEIVE_TIME_SIZE 1
#endif
/* the various debug levels for this file */
#define SNTP_DEBUG_TRACE (SNTP_DEBUG | LWIP_DBG_TRACE)
#define SNTP_DEBUG_STATE (SNTP_DEBUG | LWIP_DBG_STATE)
#define SNTP_DEBUG_WARN (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING)
#define SNTP_DEBUG_WARN_STATE (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING | LWIP_DBG_STATE)
#define SNTP_DEBUG_SERIOUS (SNTP_DEBUG | LWIP_DBG_LEVEL_SERIOUS)
#define SNTP_ERR_KOD 1
/* SNTP protocol defines */
#define SNTP_MSG_LEN 48
#define SNTP_OFFSET_LI_VN_MODE 0
#define SNTP_LI_MASK 0xC0
#define SNTP_LI_NO_WARNING 0x00
#define SNTP_LI_LAST_MINUTE_61_SEC 0x01
#define SNTP_LI_LAST_MINUTE_59_SEC 0x02
#define SNTP_LI_ALARM_CONDITION 0x03 /* (clock not synchronized) */
#define SNTP_VERSION_MASK 0x38
#define SNTP_VERSION (4/* NTP Version 4*/<<3)
#define SNTP_MODE_MASK 0x07
#define SNTP_MODE_CLIENT 0x03
#define SNTP_MODE_SERVER 0x04
#define SNTP_MODE_BROADCAST 0x05
#define SNTP_OFFSET_STRATUM 1
#define SNTP_STRATUM_KOD 0x00
#define SNTP_OFFSET_ORIGINATE_TIME 24
#define SNTP_OFFSET_RECEIVE_TIME 32
#define SNTP_OFFSET_TRANSMIT_TIME 40
/* number of seconds between 1900 and 1970 (MSB=1)*/
#define DIFF_SEC_1900_1970 (2208988800UL)
/* number of seconds between 1970 and Feb 7, 2036 (6:28:16 UTC) (MSB=0) */
#define DIFF_SEC_1970_2036 (2085978496UL)
/**
* SNTP packet format (without optional fields)
* Timestamps are coded as 64 bits:
* - 32 bits seconds since Jan 01, 1970, 00:00
* - 32 bits seconds fraction (0-padded)
* For future use, if the MSB in the seconds part is set, seconds are based
* on Feb 07, 2036, 06:28:16.
*/
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct sntp_msg {
PACK_STRUCT_FLD_8(u8_t li_vn_mode);
PACK_STRUCT_FLD_8(u8_t stratum);
PACK_STRUCT_FLD_8(u8_t poll);
PACK_STRUCT_FLD_8(u8_t precision);
PACK_STRUCT_FIELD(u32_t root_delay);
PACK_STRUCT_FIELD(u32_t root_dispersion);
PACK_STRUCT_FIELD(u32_t reference_identifier);
PACK_STRUCT_FIELD(u32_t reference_timestamp[2]);
PACK_STRUCT_FIELD(u32_t originate_timestamp[2]);
PACK_STRUCT_FIELD(u32_t receive_timestamp[2]);
PACK_STRUCT_FIELD(u32_t transmit_timestamp[2]);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
/* function prototypes */
static void sntp_request(void *arg);
/** The operating mode */
static u8_t sntp_opmode;
/** The UDP pcb used by the SNTP client */
static struct udp_pcb* sntp_pcb;
/** Names/Addresses of servers */
struct sntp_server {
#if SNTP_SERVER_DNS
char* name;
#endif /* SNTP_SERVER_DNS */
ip_addr_t addr;
};
static struct sntp_server sntp_servers[SNTP_MAX_SERVERS];
#if SNTP_GET_SERVERS_FROM_DHCP
static u8_t sntp_set_servers_from_dhcp;
#endif /* SNTP_GET_SERVERS_FROM_DHCP */
#if SNTP_SUPPORT_MULTIPLE_SERVERS
/** The currently used server (initialized to 0) */
static u8_t sntp_current_server;
#else /* SNTP_SUPPORT_MULTIPLE_SERVERS */
#define sntp_current_server 0
#endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */
#if SNTP_RETRY_TIMEOUT_EXP
#define SNTP_RESET_RETRY_TIMEOUT() sntp_retry_timeout = SNTP_RETRY_TIMEOUT
/** Retry time, initialized with SNTP_RETRY_TIMEOUT and doubled with each retry. */
static u32_t sntp_retry_timeout;
#else /* SNTP_RETRY_TIMEOUT_EXP */
#define SNTP_RESET_RETRY_TIMEOUT()
#define sntp_retry_timeout SNTP_RETRY_TIMEOUT
#endif /* SNTP_RETRY_TIMEOUT_EXP */
#if SNTP_CHECK_RESPONSE >= 1
/** Saves the last server address to compare with response */
static ip_addr_t sntp_last_server_address;
#endif /* SNTP_CHECK_RESPONSE >= 1 */
#if SNTP_CHECK_RESPONSE >= 2
/** Saves the last timestamp sent (which is sent back by the server)
* to compare against in response */
static u32_t sntp_last_timestamp_sent[2];
#endif /* SNTP_CHECK_RESPONSE >= 2 */
/**
* SNTP processing of received timestamp
*/
static void
sntp_process(u32_t *receive_timestamp)
{
/* convert SNTP time (1900-based) to unix GMT time (1970-based)
* if MSB is 0, SNTP time is 2036-based!
*/
u32_t rx_secs = lwip_ntohl(receive_timestamp[0]);
int is_1900_based = ((rx_secs & 0x80000000) != 0);
u32_t t = is_1900_based ? (rx_secs - DIFF_SEC_1900_1970) : (rx_secs + DIFF_SEC_1970_2036);
time_t tim = t;
#if SNTP_CALC_TIME_US
u32_t us = lwip_ntohl(receive_timestamp[1]) / 4295;
SNTP_SET_SYSTEM_TIME_US(t, us);
/* display local time from GMT time */
LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_process: %s, %"U32_F" us", ctime(&tim), us));
#else /* SNTP_CALC_TIME_US */
/* change system time and/or the update the RTC clock */
SNTP_SET_SYSTEM_TIME(t);
/* display local time from GMT time */
LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_process: %s", ctime(&tim)));
#endif /* SNTP_CALC_TIME_US */
LWIP_UNUSED_ARG(tim);
}
/**
* Initialize request struct to be sent to server.
*/
static void
sntp_initialize_request(struct sntp_msg *req)
{
memset(req, 0, SNTP_MSG_LEN);
req->li_vn_mode = SNTP_LI_NO_WARNING | SNTP_VERSION | SNTP_MODE_CLIENT;
#if SNTP_CHECK_RESPONSE >= 2
{
u32_t sntp_time_sec, sntp_time_us;
/* fill in transmit timestamp and save it in 'sntp_last_timestamp_sent' */
SNTP_GET_SYSTEM_TIME(sntp_time_sec, sntp_time_us);
sntp_last_timestamp_sent[0] = lwip_htonl(sntp_time_sec + DIFF_SEC_1900_1970);
req->transmit_timestamp[0] = sntp_last_timestamp_sent[0];
/* we send/save us instead of fraction to be faster... */
sntp_last_timestamp_sent[1] = lwip_htonl(sntp_time_us);
req->transmit_timestamp[1] = sntp_last_timestamp_sent[1];
}
#endif /* SNTP_CHECK_RESPONSE >= 2 */
}
/**
* Retry: send a new request (and increase retry timeout).
*
* @param arg is unused (only necessary to conform to sys_timeout)
*/
static void
sntp_retry(void* arg)
{
LWIP_UNUSED_ARG(arg);
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_retry: Next request will be sent in %"U32_F" ms\n",
sntp_retry_timeout));
/* set up a timer to send a retry and increase the retry delay */
sys_timeout(sntp_retry_timeout, sntp_request, NULL);
#if SNTP_RETRY_TIMEOUT_EXP
{
u32_t new_retry_timeout;
/* increase the timeout for next retry */
new_retry_timeout = sntp_retry_timeout << 1;
/* limit to maximum timeout and prevent overflow */
if ((new_retry_timeout <= SNTP_RETRY_TIMEOUT_MAX) &&
(new_retry_timeout > sntp_retry_timeout)) {
sntp_retry_timeout = new_retry_timeout;
}
}
#endif /* SNTP_RETRY_TIMEOUT_EXP */
}
#if SNTP_SUPPORT_MULTIPLE_SERVERS
/**
* If Kiss-of-Death is received (or another packet parsing error),
* try the next server or retry the current server and increase the retry
* timeout if only one server is available.
* (implicitly, SNTP_MAX_SERVERS > 1)
*
* @param arg is unused (only necessary to conform to sys_timeout)
*/
static void
sntp_try_next_server(void* arg)
{
u8_t old_server, i;
LWIP_UNUSED_ARG(arg);
old_server = sntp_current_server;
for (i = 0; i < SNTP_MAX_SERVERS - 1; i++) {
sntp_current_server++;
if (sntp_current_server >= SNTP_MAX_SERVERS) {
sntp_current_server = 0;
}
if (!ip_addr_isany(&sntp_servers[sntp_current_server].addr)
#if SNTP_SERVER_DNS
|| (sntp_servers[sntp_current_server].name != NULL)
#endif
) {
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_try_next_server: Sending request to server %"U16_F"\n",
(u16_t)sntp_current_server));
/* new server: reset retry timeout */
SNTP_RESET_RETRY_TIMEOUT();
/* instantly send a request to the next server */
sntp_request(NULL);
return;
}
}
/* no other valid server found */
sntp_current_server = old_server;
sntp_retry(NULL);
}
#else /* SNTP_SUPPORT_MULTIPLE_SERVERS */
/* Always retry on error if only one server is supported */
#define sntp_try_next_server sntp_retry
#endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */
/** UDP recv callback for the sntp pcb */
static void
sntp_recv(void *arg, struct udp_pcb* pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
u8_t mode;
u8_t stratum;
u32_t receive_timestamp[SNTP_RECEIVE_TIME_SIZE];
err_t err;
LWIP_UNUSED_ARG(arg);
LWIP_UNUSED_ARG(pcb);
/* packet received: stop retry timeout */
sys_untimeout(sntp_try_next_server, NULL);
sys_untimeout(sntp_request, NULL);
err = ERR_ARG;
#if SNTP_CHECK_RESPONSE >= 1
/* check server address and port */
if (((sntp_opmode != SNTP_OPMODE_POLL) || ip_addr_cmp(addr, &sntp_last_server_address)) &&
(port == SNTP_PORT))
#else /* SNTP_CHECK_RESPONSE >= 1 */
LWIP_UNUSED_ARG(addr);
LWIP_UNUSED_ARG(port);
#endif /* SNTP_CHECK_RESPONSE >= 1 */
{
/* process the response */
if (p->tot_len == SNTP_MSG_LEN) {
pbuf_copy_partial(p, &mode, 1, SNTP_OFFSET_LI_VN_MODE);
mode &= SNTP_MODE_MASK;
/* if this is a SNTP response... */
if (((sntp_opmode == SNTP_OPMODE_POLL) && (mode == SNTP_MODE_SERVER)) ||
((sntp_opmode == SNTP_OPMODE_LISTENONLY) && (mode == SNTP_MODE_BROADCAST))) {
pbuf_copy_partial(p, &stratum, 1, SNTP_OFFSET_STRATUM);
if (stratum == SNTP_STRATUM_KOD) {
/* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */
err = SNTP_ERR_KOD;
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Received Kiss-of-Death\n"));
} else {
#if SNTP_CHECK_RESPONSE >= 2
/* check originate_timetamp against sntp_last_timestamp_sent */
u32_t originate_timestamp[2];
pbuf_copy_partial(p, &originate_timestamp, 8, SNTP_OFFSET_ORIGINATE_TIME);
if ((originate_timestamp[0] != sntp_last_timestamp_sent[0]) ||
(originate_timestamp[1] != sntp_last_timestamp_sent[1]))
{
LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid originate timestamp in response\n"));
} else
#endif /* SNTP_CHECK_RESPONSE >= 2 */
/* @todo: add code for SNTP_CHECK_RESPONSE >= 3 and >= 4 here */
{
/* correct answer */
err = ERR_OK;
pbuf_copy_partial(p, &receive_timestamp, SNTP_RECEIVE_TIME_SIZE * 4, SNTP_OFFSET_TRANSMIT_TIME);
}
}
} else {
LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid mode in response: %"U16_F"\n", (u16_t)mode));
/* wait for correct response */
err = ERR_TIMEOUT;
}
} else {
LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid packet length: %"U16_F"\n", p->tot_len));
}
}
#if SNTP_CHECK_RESPONSE >= 1
else {
/* packet from wrong remote address or port, wait for correct response */
err = ERR_TIMEOUT;
}
#endif /* SNTP_CHECK_RESPONSE >= 1 */
pbuf_free(p);
if (err == ERR_OK) {
sntp_process(receive_timestamp);
/* Set up timeout for next request (only if poll response was received)*/
if (sntp_opmode == SNTP_OPMODE_POLL) {
/* Correct response, reset retry timeout */
SNTP_RESET_RETRY_TIMEOUT();
sys_timeout((u32_t)SNTP_UPDATE_DELAY, sntp_request, NULL);
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Scheduled next time request: %"U32_F" ms\n",
(u32_t)SNTP_UPDATE_DELAY));
}
} else if (err != ERR_TIMEOUT) {
/* Errors are only processed in case of an explicit poll response */
if (sntp_opmode == SNTP_OPMODE_POLL) {
if (err == SNTP_ERR_KOD) {
/* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */
sntp_try_next_server(NULL);
} else {
/* another error, try the same server again */
sntp_retry(NULL);
}
}
}
}
/** Actually send an sntp request to a server.
*
* @param server_addr resolved IP address of the SNTP server
*/
static void
sntp_send_request(const ip_addr_t *server_addr)
{
struct pbuf* p;
p = pbuf_alloc(PBUF_TRANSPORT, SNTP_MSG_LEN, PBUF_RAM);
if (p != NULL) {
struct sntp_msg *sntpmsg = (struct sntp_msg *)p->payload;
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_send_request: Sending request to server\n"));
/* initialize request message */
sntp_initialize_request(sntpmsg);
/* send request */
udp_sendto(sntp_pcb, p, server_addr, SNTP_PORT);
/* free the pbuf after sending it */
pbuf_free(p);
/* set up receive timeout: try next server or retry on timeout */
sys_timeout((u32_t)SNTP_RECV_TIMEOUT, sntp_try_next_server, NULL);
#if SNTP_CHECK_RESPONSE >= 1
/* save server address to verify it in sntp_recv */
ip_addr_set(&sntp_last_server_address, server_addr);
#endif /* SNTP_CHECK_RESPONSE >= 1 */
} else {
LWIP_DEBUGF(SNTP_DEBUG_SERIOUS, ("sntp_send_request: Out of memory, trying again in %"U32_F" ms\n",
(u32_t)SNTP_RETRY_TIMEOUT));
/* out of memory: set up a timer to send a retry */
sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_request, NULL);
}
}
#if SNTP_SERVER_DNS
/**
* DNS found callback when using DNS names as server address.
*/
static void
sntp_dns_found(const char* hostname, const ip_addr_t *ipaddr, void *arg)
{
LWIP_UNUSED_ARG(hostname);
LWIP_UNUSED_ARG(arg);
if (ipaddr != NULL) {
/* Address resolved, send request */
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_dns_found: Server address resolved, sending request\n"));
sntp_send_request(ipaddr);
} else {
/* DNS resolving failed -> try another server */
LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_dns_found: Failed to resolve server address resolved, trying next server\n"));
sntp_try_next_server(NULL);
}
}
#endif /* SNTP_SERVER_DNS */
/**
* Send out an sntp request.
*
* @param arg is unused (only necessary to conform to sys_timeout)
*/
static void
sntp_request(void *arg)
{
ip_addr_t sntp_server_address;
err_t err;
LWIP_UNUSED_ARG(arg);
/* initialize SNTP server address */
#if SNTP_SERVER_DNS
if (sntp_servers[sntp_current_server].name) {
/* always resolve the name and rely on dns-internal caching & timeout */
ip_addr_set_zero(&sntp_servers[sntp_current_server].addr);
err = dns_gethostbyname(sntp_servers[sntp_current_server].name, &sntp_server_address,
sntp_dns_found, NULL);
if (err == ERR_INPROGRESS) {
/* DNS request sent, wait for sntp_dns_found being called */
LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_request: Waiting for server address to be resolved.\n"));
return;
} else if (err == ERR_OK) {
sntp_servers[sntp_current_server].addr = sntp_server_address;
}
} else
#endif /* SNTP_SERVER_DNS */
{
sntp_server_address = sntp_servers[sntp_current_server].addr;
err = (ip_addr_isany_val(sntp_server_address)) ? ERR_ARG : ERR_OK;
}
if (err == ERR_OK) {
LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_request: current server address is %s\n",
ipaddr_ntoa(&sntp_server_address)));
sntp_send_request(&sntp_server_address);
} else {
/* address conversion failed, try another server */
LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_request: Invalid server address, trying next server.\n"));
sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_try_next_server, NULL);
}
}
/**
* @ingroup sntp
* Initialize this module.
* Send out request instantly or after SNTP_STARTUP_DELAY(_FUNC).
*/
void
sntp_init(void)
{
#ifdef SNTP_SERVER_ADDRESS
#if SNTP_SERVER_DNS
sntp_setservername(0, SNTP_SERVER_ADDRESS);
#else
#error SNTP_SERVER_ADDRESS string not supported SNTP_SERVER_DNS==0
#endif
#endif /* SNTP_SERVER_ADDRESS */
if (sntp_pcb == NULL) {
sntp_pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
LWIP_ASSERT("Failed to allocate udp pcb for sntp client", sntp_pcb != NULL);
if (sntp_pcb != NULL) {
udp_recv(sntp_pcb, sntp_recv, NULL);
if (sntp_opmode == SNTP_OPMODE_POLL) {
SNTP_RESET_RETRY_TIMEOUT();
#if SNTP_STARTUP_DELAY
sys_timeout((u32_t)SNTP_STARTUP_DELAY_FUNC, sntp_request, NULL);
#else
sntp_request(NULL);
#endif
} else if (sntp_opmode == SNTP_OPMODE_LISTENONLY) {
ip_set_option(sntp_pcb, SOF_BROADCAST);
udp_bind(sntp_pcb, IP_ANY_TYPE, SNTP_PORT);
}
}
}
}
/**
* @ingroup sntp
* Stop this module.
*/
void
sntp_stop(void)
{
if (sntp_pcb != NULL) {
sys_untimeout(sntp_request, NULL);
sys_untimeout(sntp_try_next_server, NULL);
udp_remove(sntp_pcb);
sntp_pcb = NULL;
}
}
/**
* @ingroup sntp
* Get enabled state.
*/
u8_t sntp_enabled(void)
{
return (sntp_pcb != NULL)? 1 : 0;
}
/**
* @ingroup sntp
* Sets the operating mode.
* @param operating_mode one of the available operating modes
*/
void
sntp_setoperatingmode(u8_t operating_mode)
{
LWIP_ASSERT("Invalid operating mode", operating_mode <= SNTP_OPMODE_LISTENONLY);
LWIP_ASSERT("Operating mode must not be set while SNTP client is running", sntp_pcb == NULL);
sntp_opmode = operating_mode;
}
/**
* @ingroup sntp
* Gets the operating mode.
*/
u8_t
sntp_getoperatingmode(void)
{
return sntp_opmode;
}
#if SNTP_GET_SERVERS_FROM_DHCP
/**
* Config SNTP server handling by IP address, name, or DHCP; clear table
* @param set_servers_from_dhcp enable or disable getting server addresses from dhcp
*/
void
sntp_servermode_dhcp(int set_servers_from_dhcp)
{
u8_t new_mode = set_servers_from_dhcp ? 1 : 0;
if (sntp_set_servers_from_dhcp != new_mode) {
sntp_set_servers_from_dhcp = new_mode;
}
}
#endif /* SNTP_GET_SERVERS_FROM_DHCP */
/**
* @ingroup sntp
* Initialize one of the NTP servers by IP address
*
* @param idx the index of the NTP server to set must be < SNTP_MAX_SERVERS
* @param server IP address of the NTP server to set
*/
void
sntp_setserver(u8_t idx, const ip_addr_t *server)
{
if (idx < SNTP_MAX_SERVERS) {
if (server != NULL) {
sntp_servers[idx].addr = (*server);
} else {
ip_addr_set_zero(&sntp_servers[idx].addr);
}
#if SNTP_SERVER_DNS
sntp_servers[idx].name = NULL;
#endif
}
}
#if LWIP_DHCP && SNTP_GET_SERVERS_FROM_DHCP
/**
* Initialize one of the NTP servers by IP address, required by DHCP
*
* @param numdns the index of the NTP server to set must be < SNTP_MAX_SERVERS
* @param dnsserver IP address of the NTP server to set
*/
void
dhcp_set_ntp_servers(u8_t num, const ip4_addr_t *server)
{
LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp: %s %u.%u.%u.%u as NTP server #%u via DHCP\n",
(sntp_set_servers_from_dhcp ? "Got" : "Rejected"),
ip4_addr1(server), ip4_addr2(server), ip4_addr3(server), ip4_addr4(server), num));
if (sntp_set_servers_from_dhcp && num) {
u8_t i;
for (i = 0; (i < num) && (i < SNTP_MAX_SERVERS); i++) {
ip_addr_t addr;
ip_addr_copy_from_ip4(addr, server[i]);
sntp_setserver(i, &addr);
}
for (i = num; i < SNTP_MAX_SERVERS; i++) {
sntp_setserver(i, NULL);
}
}
}
#endif /* LWIP_DHCP && SNTP_GET_SERVERS_FROM_DHCP */
/**
* @ingroup sntp
* Obtain one of the currently configured by IP address (or DHCP) NTP servers
*
* @param idx the index of the NTP server
* @return IP address of the indexed NTP server or "ip_addr_any" if the NTP
* server has not been configured by address (or at all).
*/
const ip_addr_t*
sntp_getserver(u8_t idx)
{
if (idx < SNTP_MAX_SERVERS) {
return &sntp_servers[idx].addr;
}
return IP_ADDR_ANY;
}
#if SNTP_SERVER_DNS
/**
* Initialize one of the NTP servers by name
*
* @param numdns the index of the NTP server to set must be < SNTP_MAX_SERVERS
* @param dnsserver DNS name of the NTP server to set, to be resolved at contact time
*/
void
sntp_setservername(u8_t idx, char *server)
{
if (idx < SNTP_MAX_SERVERS) {
sntp_servers[idx].name = server;
}
}
/**
* Obtain one of the currently configured by name NTP servers.
*
* @param numdns the index of the NTP server
* @return IP address of the indexed NTP server or NULL if the NTP
* server has not been configured by name (or at all)
*/
char *
sntp_getservername(u8_t idx)
{
if (idx < SNTP_MAX_SERVERS) {
return sntp_servers[idx].name;
}
return NULL;
}
#endif /* SNTP_SERVER_DNS */
#endif /* LWIP_UDP */

View file

@ -157,15 +157,16 @@ void sntp_get_lasttime(long *sec, long *usec, unsigned int *tick)
*tick = sntp_update_tick; *tick = sntp_update_tick;
} }
struct tm sntp_gen_system_time(int timezone) time_t sntp_gen_system_time(int timezone)
{ {
struct tm current_tm; struct tm current_tm;
unsigned int update_tick = 0; unsigned int update_tick;
long update_sec = 0, update_usec = 0, current_sec = 0; long update_sec, update_usec, current_sec = 0;
unsigned int current_tick = xTaskGetTickCount();
sntp_get_lasttime(&update_sec, &update_usec, &update_tick); sntp_get_lasttime(&update_sec, &update_usec, &update_tick);
unsigned int current_tick = xTaskGetTickCount();
if(update_tick) { if(update_tick) {
long tick_diff_sec, tick_diff_ms; long tick_diff_sec, tick_diff_ms;
@ -176,14 +177,17 @@ struct tm sntp_gen_system_time(int timezone)
current_sec = update_sec + update_usec / 1000000 + timezone * 3600; current_sec = update_sec + update_usec / 1000000 + timezone * 3600;
} }
else { else {
current_sec = current_tick / configTICK_RATE_HZ; // current_sec = current_tick / configTICK_RATE_HZ;
current_sec = update_usec;
} }
return current_sec;
/*
current_tm = *(localtime(&current_sec)); current_tm = *(localtime(&current_sec));
current_tm.tm_year += 1900; current_tm.tm_year += 1900;
current_tm.tm_mon += 1; current_tm.tm_mon += 1;
return current_tm; return current_tm;
*/
} }
/* End of Realtek added */ /* End of Realtek added */
@ -635,6 +639,7 @@ sntp_init(void)
#else #else
sntp_request(NULL); sntp_request(NULL);
#endif #endif
rtl_printf("SNTP start.\n");
} }
} }
} }
@ -649,6 +654,7 @@ sntp_stop(void)
sys_untimeout(sntp_request, NULL); sys_untimeout(sntp_request, NULL);
udp_remove(sntp_pcb); udp_remove(sntp_pcb);
sntp_pcb = NULL; sntp_pcb = NULL;
rtl_printf("SNTP stop.\n");
} }
} }
#endif /* LWIP_UDP */ #endif /* LWIP_UDP */

View file

@ -12,7 +12,7 @@ void sntp_stop(void);
/* Realtek added */ /* Realtek added */
void sntp_get_lasttime(long *sec, long *usec, unsigned int *tick); void sntp_get_lasttime(long *sec, long *usec, unsigned int *tick);
struct tm sntp_gen_system_time(int timezone); time_t sntp_gen_system_time(int timezone);
#ifdef __cplusplus #ifdef __cplusplus
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -194,7 +194,7 @@
=3 errors + warning + info, =3 errors + warning + info,
=4 errors + warning + info + debug, =4 errors + warning + info + debug,
=5 full */ =5 full */
#define CONFIG_DEBUG_LOG 2 #define CONFIG_DEBUG_LOG 4
#if CONFIG_DEBUG_LOG > 0 #if CONFIG_DEBUG_LOG > 0
//#define CONFIG_DEBUG_ERR_MSG 1 //#define CONFIG_DEBUG_ERR_MSG 1
#define CONFIG_DEBUG_LOG_ADC_HAL 1 #define CONFIG_DEBUG_LOG_ADC_HAL 1

View file

@ -34,6 +34,7 @@
#include "user/atcmd_user.h" #include "user/atcmd_user.h"
#include "main.h" #include "main.h"
#include "wifi_api.h" #include "wifi_api.h"
#include "rtl8195a/rtl_libc.h"
/* --------------------------------------------------- /* ---------------------------------------------------
* Customized Signature (Image Name) * Customized Signature (Image Name)
@ -71,13 +72,14 @@ static char sampCntAdd;
static char sampDelCnt; static char sampDelCnt;
static int sampCnt; static int sampCnt;
#endif #endif
#define ID_FEEP_MP3 0x5000
mp3_server_setings mp3_serv = {0,{0}}; //{ PLAY_PORT, { PLAY_SERVER }}; mp3_server_setings mp3_serv = {0,{0}}; //{ PLAY_PORT, { PLAY_SERVER }};
static int mp3_cfg_read(void) LOCAL int mp3_cfg_read(void)
{ {
bzero(&mp3_serv, sizeof(mp3_serv)); rtl_memset(&mp3_serv, 0, sizeof(mp3_serv));
if(flash_read_cfg(mp3_serv, 0x5000, sizeof(mp3_serv.port) + 2) >= sizeof(mp3_serv.port) + 2) { if(flash_read_cfg(&mp3_serv, ID_FEEP_MP3, sizeof(mp3_serv.port) + 2) >= sizeof(mp3_serv.port) + 2) {
mp3_serv.port = PLAY_PORT; mp3_serv.port = PLAY_PORT;
strcpy(mp3_serv.url, PLAY_SERVER); strcpy(mp3_serv.url, PLAY_SERVER);
} }
@ -167,7 +169,7 @@ static enum mad_flow input(struct mad_stream *stream) {
} }
//Routine to print out an error //Routine to print out an error
static enum mad_flow error(void *data, struct mad_stream *stream, LOCAL enum mad_flow error(void *data, struct mad_stream *stream,
struct mad_frame *frame) { struct mad_frame *frame) {
#if DEBUG_MAIN_LEVEL > 0 #if DEBUG_MAIN_LEVEL > 0
DBG_8195A("MAD: Dec err 0x%04x (%s)\n", stream->error, DBG_8195A("MAD: Dec err 0x%04x (%s)\n", stream->error,
@ -176,11 +178,11 @@ static enum mad_flow error(void *data, struct mad_stream *stream,
return MAD_FLOW_CONTINUE; return MAD_FLOW_CONTINUE;
} }
void tskreader(void *pvParameters); LOCAL void tskreader(void *pvParameters);
//This is the main mp3 decoding task. It will grab data from the input buffer FIFO in the SPI ram and //This is the main mp3 decoding task. It will grab data from the input buffer FIFO in the SPI ram and
//output it to the I2S port. //output it to the I2S port.
void tskmad(void *pvParameters) { LOCAL void tskmad(void *pvParameters) {
//Initialize I2S //Initialize I2S
if (i2sInit(-1, I2S_DMA_PAGE_WAIT_MS_MIN * I2S_DMA_PAGE_SIZE_MS_96K, WL_24b)) { // min 2 ms x I2S_DMA_PAGE_SIZE buffers if (i2sInit(-1, I2S_DMA_PAGE_WAIT_MS_MIN * I2S_DMA_PAGE_SIZE_MS_96K, WL_24b)) { // min 2 ms x I2S_DMA_PAGE_SIZE buffers
//Allocate structs needed for mp3 decoding //Allocate structs needed for mp3 decoding
@ -263,7 +265,7 @@ exit:
vTaskDelete(NULL); vTaskDelete(NULL);
} }
int getIpForHost(const char *host, struct sockaddr_in *ip) { LOCAL int getIpForHost(const char *host, struct sockaddr_in *ip) {
struct hostent *he; struct hostent *he;
struct in_addr **addr_list; struct in_addr **addr_list;
he = gethostbyname(host); he = gethostbyname(host);
@ -277,11 +279,11 @@ int getIpForHost(const char *host, struct sockaddr_in *ip) {
//Open a connection to a webserver and request an URL. Yes, this possibly is one of the worst ways to do this, //Open a connection to a webserver and request an URL. Yes, this possibly is one of the worst ways to do this,
//but RAM is at a premium here, and this works for most of the cases. //but RAM is at a premium here, and this works for most of the cases.
int openConn(const char *streamHost, const char *streamPath, int streamPort) { LOCAL int openConn(const char *streamHost, const char *streamPath, int streamPort) {
int n = 5; int n = 5;
while (tskreader_enable == 1) { while (tskreader_enable == 1) {
struct sockaddr_in remote_ip; struct sockaddr_in remote_ip;
bzero(&remote_ip, sizeof(struct sockaddr_in)); rtl_memset(&remote_ip, 0, sizeof(struct sockaddr_in));
if (!getIpForHost(streamHost, &remote_ip)) { if (!getIpForHost(streamHost, &remote_ip)) {
vTaskDelay(1000 / portTICK_RATE_MS); vTaskDelay(1000 / portTICK_RATE_MS);
if(n--) continue; if(n--) continue;
@ -328,7 +330,7 @@ int openConn(const char *streamHost, const char *streamPath, int streamPort) {
} }
int http_head_read(unsigned char *buf, int len, int ff) { LOCAL int http_head_read(unsigned char *buf, int len, int ff) {
int flg_head = 0; int flg_head = 0;
int n, ret = 0; int n, ret = 0;
if ((n = read(ff, buf, len)) <= 0) return 0; if ((n = read(ff, buf, len)) <= 0) return 0;
@ -373,7 +375,7 @@ int http_head_read(unsigned char *buf, int len, int ff) {
} }
//Reader task. This will try to read data from a TCP socket into the SPI fifo buffer. //Reader task. This will try to read data from a TCP socket into the SPI fifo buffer.
void tskreader(void *pvParameters) { LOCAL void tskreader(void *pvParameters) {
char wbuf[SOCK_READ_BUF]; char wbuf[SOCK_READ_BUF];
int n; int n;
if (RamFifoInit(mMIN(xPortGetFreeHeapSize() - MIN_FIFO_HEAP, MAX_FIFO_SIZE))) { if (RamFifoInit(mMIN(xPortGetFreeHeapSize() - MIN_FIFO_HEAP, MAX_FIFO_SIZE))) {
@ -509,13 +511,16 @@ void ShowMemInfo(void)
} }
void user_init_thrd(void) { LOCAL void user_init_thrd(void) {
mp3_cfg_read();
wifi_init(); wifi_init();
/* Initilaize the console stack */ /* Initilaize the console stack */
console_init(); console_init();
/* Kill init thread after all init tasks done */ /* Kill init thread after all init tasks done */
vTaskDelete(NULL); vTaskDelete(NULL);
} }
@ -554,8 +559,6 @@ void main(void)
ShowMemInfo(); // RAM/TCM/Heaps info ShowMemInfo(); // RAM/TCM/Heaps info
#endif #endif
mp3_cfg_read();
/* wlan & user_start intialization */ /* wlan & user_start intialization */
xTaskCreate(user_init_thrd, "user_init", 1024, NULL, tskIDLE_PRIORITY + 0 + PRIORITIE_OFFSET, NULL); xTaskCreate(user_init_thrd, "user_init", 1024, NULL, tskIDLE_PRIORITY + 0 + PRIORITIE_OFFSET, NULL);
@ -573,7 +576,7 @@ void main(void)
//--- CONSOLE --- //--- CONSOLE ---
// MP3 Set server, Close/Open connect // MP3 Set server, Close/Open connect
void fATWS(int argc, char *argv[]){ LOCAL void fATWS(int argc, char *argv[]){
if (argc == 2) { if (argc == 2) {
StrUpr(argv[1]); StrUpr(argv[1]);
if(argv[1][0] == '?') { if(argv[1][0] == '?') {
@ -597,7 +600,7 @@ void fATWS(int argc, char *argv[]){
} }
else if(argv[1][0] == 'S') { // strcmp(argv[1], "save") == 0 else if(argv[1][0] == 'S') { // strcmp(argv[1], "save") == 0
printf("%s: %s,%d\n", argv[0], mp3_serv.url, mp3_serv.port); printf("%s: %s,%d\n", argv[0], mp3_serv.url, mp3_serv.port);
if(flash_write_cfg(&mp3_serv, 0x5000, strlen(mp3_serv.port) + strlen(mp3_serv.url))) if(flash_write_cfg(&mp3_serv, ID_FEEP_MP3, strlen(mp3_serv.port) + strlen(mp3_serv.url)))
printf("ATWS: saved\n", mp3_serv.url, mp3_serv.port); printf("ATWS: saved\n", mp3_serv.url, mp3_serv.port);
return; return;
} }
@ -612,5 +615,5 @@ void fATWS(int argc, char *argv[]){
} }
MON_RAM_TAB_SECTION COMMAND_TABLE console_commands_main[] = { MON_RAM_TAB_SECTION COMMAND_TABLE console_commands_main[] = {
{"ATWS", 1, fATWS, "=<URL,PORT>: MP3 Connect to URL\nATWS=<c>[lose]: Close MP3\nATWS=<r>[ead]: Read MP3 URL\nATWS=<s>[ave]: Save MP3 URL\nATWS=<?>: URL Info"} {"ATWS", 1, fATWS, "=<URL,PORT>: MP3 Connect to URL\nATWS=<c>: Close MP3\nATWS=<r>: Read MP3 URL\nATWS=<s>: Save MP3 URL\nATWS=<?>: URL Info"}
}; };

View file

@ -22,7 +22,6 @@ extern struct netif xnetif[NET_IF_NUM];
//========================================================== //==========================================================
//--- CONSOLE -------------------------- //--- CONSOLE --------------------------
extern rtw_security_t translate_rtw_security(u8 security_type);
// ATPN=<SSID>[,password[,encryption[,auto reconnect[,reconnect pause]]]: WIFI Connect to AP // ATPN=<SSID>[,password[,encryption[,auto reconnect[,reconnect pause]]]: WIFI Connect to AP
LOCAL void fATPN(int argc, char *argv[]){ LOCAL void fATPN(int argc, char *argv[]){
if(argc > 1) { if(argc > 1) {
@ -31,13 +30,14 @@ LOCAL void fATPN(int argc, char *argv[]){
} }
else { else {
strncpy(wifi_st_cfg.ssid, argv[1], NDIS_802_11_LENGTH_SSID); strncpy(wifi_st_cfg.ssid, argv[1], NDIS_802_11_LENGTH_SSID);
int pswlen;
if(argc > 2) { if(argc > 2) {
pswlen = strlen(wifi_st_cfg.password);
strncpy(wifi_st_cfg.password, argv[2], NDIS_802_11_LENGTH_SSID); strncpy(wifi_st_cfg.password, argv[2], NDIS_802_11_LENGTH_SSID);
int i = strlen(wifi_st_cfg.password); if(pswlen > 7) {
if(i > 7) {
wifi_st_cfg.security_type = RTW_SECURITY_WPA2_AES_PSK; wifi_st_cfg.security_type = RTW_SECURITY_WPA2_AES_PSK;
} }
else if(!i) { else if(!pswlen) {
wifi_st_cfg.security_type = RTW_SECURITY_OPEN; wifi_st_cfg.security_type = RTW_SECURITY_OPEN;
} }
else { else {
@ -46,18 +46,25 @@ LOCAL void fATPN(int argc, char *argv[]){
} }
} }
else { else {
// default
wifi_st_cfg.password[0] = 0; wifi_st_cfg.password[0] = 0;
wifi_st_cfg.security_type = RTW_SECURITY_OPEN; wifi_st_cfg.security_type = RTW_SECURITY_OPEN;
} }
if(argc > 3) { if(argc > 3) {
wifi_st_cfg.security_type = translate_rtw_security(atoi(argv[3])); if(pswlen > 7) {
wifi_st_cfg.security_type = translate_val_to_rtw_security(atoi(argv[3]));
}
else {
printf("password len < 8!\n");
wifi_st_cfg.security_type = RTW_SECURITY_OPEN;
}
} }
if(argc > 4) { if(argc > 4) {
wifi_st_cfg.autoreconnect = atoi(argv[3]); wifi_st_cfg.autoreconnect = atoi(argv[4]);
} }
else wifi_st_cfg.autoreconnect = 0; else wifi_st_cfg.autoreconnect = 0;
if(argc > 5) { if(argc > 5) {
wifi_st_cfg.reconnect_pause = atoi(argv[3]); wifi_st_cfg.reconnect_pause = atoi(argv[5]);
} }
else wifi_st_cfg.reconnect_pause = 5; else wifi_st_cfg.reconnect_pause = 5;
show_wifi_st_cfg(); show_wifi_st_cfg();
@ -93,7 +100,7 @@ LOCAL void fATPA(int argc, char *argv[]){
wifi_ap_cfg.security_type = RTW_SECURITY_OPEN; wifi_ap_cfg.security_type = RTW_SECURITY_OPEN;
} }
if(argc > 3) { if(argc > 3) {
wifi_ap_cfg.security_type = translate_rtw_security(atoi(argv[3])); wifi_ap_cfg.security_type = (argv[3][0] == '0')? RTW_SECURITY_OPEN : RTW_SECURITY_WPA2_AES_PSK;
} }
if(argc > 4) { if(argc > 4) {
wifi_ap_cfg.channel = atoi(argv[4]); wifi_ap_cfg.channel = atoi(argv[4]);