724 lines
18 KiB
C

#include "WiFiCtrl.h"
#include "string.h"
#include "driver/source/nmasic.h"
#include <stdint.h>
//#include "socket/include/socket.h"
#include "define.h"
#include "Terminal.h"
#include "driver/include/m2m_periph.h"
#include "ProtocolDefs.h"
#include "BoardCfg.h"
#include "timer.h"
#include "BootloaderProtocol.h"
/** IP address of host. */
uint32 gu32HostIp = 0;
/** Retry count. */
uint8 gu8RetryCount = 0;
/** TCP client socket handlers. */
static SOCKET tcp_client_socket = -1;
SOCKET TerminalSocket = -1, TerminalServerSocket = -1;
uint8 TerminalRxBuf[1024];
#ifdef USE_SYSLOG
SOCKET SyslogSocket = -1, SyslogServerSocket = -1;
uint8 SyslogRxBuf[200]; //Syslog shall not receive much data
#endif
SOCKET NetworkSocket = -1, NetworkServerSocket = -1;
uint8 NetworkRxBuf[1024];
SOCKET BootloaderSocket = -1, BootloaderServerSocket = -1;
uint8 BootloaderRxBuf[1024];
/** Receive buffer definition. */
static uint8 gau8ReceivedBuffer[MAIN_WIFI_M2M_BUFFER_SIZE] = {0};
/** Wi-Fi status variable. */
static bool gbConnectedWifi = false;
/** Get host IP status variable. */
static bool gbHostIpByName = false;
/** TCP Connection status variable. */
static bool gbTcpConnection = false;
/** Server host name. */
static char server_host_name[] = MAIN_WEATHER_SERVER_NAME;
tstrWifiInitParam param;
uint8 mac_addr[6];
uint8 u8IsMacAddrValid;
struct sockaddr_in addr_in;
tstrM2MIPConfig mModuleIPConfig;
bool mWiFiInitOK = false;
char mWiFiState = WIFI_UNKNOWN_STATE;
/**
* \brief Callback function of IP address.
*
* \param[in] hostName Domain name.
* \param[in] hostIp Server IP.
*
* \return None.
*/
static void resolve_cb(uint8 *hostName, uint32 hostIp)
{
gu32HostIp = hostIp;
gbHostIpByName = true;
printf("Host IP is %d.%d.%d.%d\r\n",
(int)IPV4_BYTE(hostIp, 0),
(int)IPV4_BYTE(hostIp, 1),
(int)IPV4_BYTE(hostIp, 2),
(int)IPV4_BYTE(hostIp, 3));
printf("Host Name is %s\r\n", hostName);
}
static void socket_cb(SOCKET sock, uint8 u8Msg, void *pvMsg)
{
/* Check for socket event on TCP socket. */
//if(sock == TerminalSocket)
{
switch(u8Msg)
{
case SOCKET_MSG_BIND:
{
tstrSocketBindMsg *pstrBind = (tstrSocketBindMsg*)pvMsg;
if(pstrBind->status == 0)
{
if(sock == TerminalServerSocket)
{
listen(TerminalServerSocket, 0);
}
else if(sock == SyslogServerSocket)
{
listen(SyslogServerSocket,0);
}
else if(sock == NetworkServerSocket)
{
listen(NetworkServerSocket,0);
}
else if(sock == BootloaderServerSocket)
{
listen(BootloaderServerSocket,0);
printf("Bootloader server started\n");
}
}
else
{
printf("Bind Failed\n");
}
break;
}
case SOCKET_MSG_LISTEN:
{
tstrSocketListenMsg *pstrListen = (tstrSocketListenMsg*)pvMsg;
if(pstrListen->status != 0)
{
printf("socket %d listen Failed. Error: %d\n",(int)sock, pstrListen->status);
break;
}
if(sock == SyslogServerSocket)
{
m2m_periph_gpio_set_val(M2M_PERIPH_GPIO3,1);
}
break;
}
case SOCKET_MSG_ACCEPT:
{
// New Socket is accepted.
tstrSocketAcceptMsg *pstrAccept = (tstrSocketAcceptMsg *)pvMsg;
if(pstrAccept->sock >= 0)
{
if(sock == TerminalServerSocket)
{
memset(TerminalRxBuf,0,sizeof(TerminalRxBuf));
// Get the accepted socket.
TerminalSocket = pstrAccept->sock;
recv(TerminalSocket, TerminalRxBuf, sizeof(TerminalRxBuf), 0);
SendTerminalData("Bienvenue au chalet!\nLe chalet parle en anglais comme Mr. Pepin\nIf you need help... type help\n\n",strlen("Bienvenue au chalet!\nLe chalet parle en anglais comme Mr. Pepin\nIf you need help... type help\n\n"));
// SendSyslogData("Terminal client connected\n",strlen("Terminal client connected\n"));
printf("Terminal client connected\n");
// m2m_periph_gpio_set_val(M2M_PERIPH_GPIO4,1);
}
else if(sock == SyslogServerSocket)
{
memset(SyslogRxBuf,0,sizeof(SyslogRxBuf));
// Get the accepted socket.
SyslogSocket = pstrAccept->sock;
recv(SyslogSocket, SyslogRxBuf, sizeof(SyslogRxBuf), 0);
m2m_periph_gpio_set_val(M2M_PERIPH_GPIO4,1);
SendSyslogData("Syslog Welcome\n",strlen("Syslog Welcome\n"));
}
else if(sock == NetworkServerSocket)
{
memset(NetworkRxBuf,0,sizeof(NetworkRxBuf));
// Get the accepted socket.
NetworkSocket = pstrAccept->sock;
recv(NetworkSocket, NetworkRxBuf, sizeof(NetworkRxBuf), 0);
printf("Network client connected\n");
}
else if(sock == BootloaderServerSocket)
{
memset(BootloaderRxBuf,0,sizeof(BootloaderRxBuf));
// Get the accepted socket.
BootloaderSocket = pstrAccept->sock;
recv(BootloaderSocket, BootloaderRxBuf, sizeof(BootloaderRxBuf), 0);
printf("Bootloader client connected\n");
}
}
else
{
printf("Socket %d : Accept Failed\n", sock);
}
break;
}
case SOCKET_MSG_RECV:
{
tstrSocketRecvMsg *pstrRecvMsg = (tstrSocketRecvMsg*)pvMsg;
if((pstrRecvMsg->pu8Buffer != NULL) && (pstrRecvMsg->s16BufferSize > 0))
{
// Process the received message
if(sock == TerminalSocket)
{
//Fwd data to Terminal...
recv(TerminalSocket, TerminalRxBuf, sizeof(TerminalRxBuf), 0);
RxTerminalBuf(TerminalRxBuf, pstrRecvMsg->s16BufferSize);
}
else if(sock == SyslogSocket)
{
//Fwd data to stdin...
recv(SyslogSocket, SyslogRxBuf, sizeof(SyslogRxBuf), 0);
//Syslog shall ignore data...
}
else if(sock == NetworkSocket)
{
//Fwd data to Network...
recv(NetworkSocket, NetworkRxBuf, sizeof(NetworkRxBuf), 0);
}
else if(sock == BootloaderSocket)
{
//Fwd data to Network...
if(recv(BootloaderSocket, BootloaderRxBuf, sizeof(BootloaderRxBuf), 0) != 0)
{
char toto;
toto = 1;
}
BootloaderProtocolProtocolAnalyzeNewData(pstrRecvMsg->pu8Buffer, pstrRecvMsg->s16BufferSize);
}
}
else //Socket must be closed.
{
if(sock == TerminalSocket)
{
close(TerminalSocket);
TerminalSocket = -1;
// SendSyslogData("Terminal client disconnected\n",strlen("Terminal client disconnected\n"));
printf("Terminal client disconnected\n");
// m2m_periph_gpio_set_val(M2M_PERIPH_GPIO4,0);
}
else if(sock == SyslogSocket)
{
close(SyslogSocket);
SyslogSocket = -1;
m2m_periph_gpio_set_val(M2M_PERIPH_GPIO4,0);
}
else if(sock == NetworkSocket)
{
close(NetworkSocket);
NetworkSocket = -1;
printf("Network client disconnected\n");
}
else if(sock == BootloaderSocket)
{
close(BootloaderSocket);
BootloaderSocket = -1;
printf("Bootloader client disconnected\n");
BootloaderDeactivateBootloader();
}
}
break;
}
case SOCKET_MSG_SEND:
{
if(sock == SyslogSocket)
{
}
}
}
}
}
static void set_dev_name_to_mac(uint8 *name, uint8 *mac_addr)
{
/* Name must be in the format WINC1500_00:00 */
uint16 len;
len = m2m_strlen(name);
if (len >= 5) {
name[len - 1] = MAIN_HEX2ASCII((mac_addr[5] >> 0) & 0x0f);
name[len - 2] = MAIN_HEX2ASCII((mac_addr[5] >> 4) & 0x0f);
name[len - 4] = MAIN_HEX2ASCII((mac_addr[4] >> 0) & 0x0f);
name[len - 5] = MAIN_HEX2ASCII((mac_addr[4] >> 4) & 0x0f);
}
}
/**
* \brief Callback to get the Wi-Fi status update.
*
* \param[in] u8MsgType Type of Wi-Fi notification.
* \param[in] pvMsg A pointer to a buffer containing the notification parameters.
*
* \return None.
*/
static void wifi_cb(uint8 u8MsgType, void *pvMsg)
{
switch (u8MsgType) {
case M2M_WIFI_RESP_CON_STATE_CHANGED: {
tstrM2mWifiStateChanged *pstrWifiState = (tstrM2mWifiStateChanged *)pvMsg;
if (pstrWifiState->u8CurrState == M2M_WIFI_CONNECTED)
{
printf("Wi-Fi connected\r\n");
#ifndef USE_STATIC_IP
m2m_wifi_request_dhcp_client();
#else
m2m_wifi_set_static_ip(&mModuleIPConfig);
gbConnectedWifi = true;
#endif
mWiFiState = WIFI_CONNECTED_STATE;
} else if (pstrWifiState->u8CurrState == M2M_WIFI_DISCONNECTED)
{
printf("Wi-Fi disconnected\r\n");
gbConnectedWifi = false;
mWiFiState = WIFI_DISCONNECTED_STATE;
CloseSockets();
m2m_periph_gpio_set_val(M2M_PERIPH_GPIO3,0);
}
break;
}
case M2M_WIFI_REQ_DHCP_CONF:
{
uint8 *pu8IPAddress = (uint8 *)pvMsg;
/* Turn LED0 on to declare that IP address received. */
printf("Wi-Fi IP is %u.%u.%u.%u\r\n", pu8IPAddress[0], pu8IPAddress[1], pu8IPAddress[2], pu8IPAddress[3]);
gbConnectedWifi = true;
/* Obtain the IP Address by network name */
gethostbyname((uint8 *)server_host_name);
break;
}
case M2M_WIFI_RESP_PROVISION_INFO:
{
tstrM2MProvisionInfo *pstrProvInfo = (tstrM2MProvisionInfo *)pvMsg;
printf("wifi_cb: M2M_WIFI_RESP_PROVISION_INFO.\r\n");
if (pstrProvInfo->u8Status == M2M_SUCCESS) {
m2m_wifi_connect((char *)pstrProvInfo->au8SSID,
strlen((char *)pstrProvInfo->au8SSID),
pstrProvInfo->u8SecType,
pstrProvInfo->au8Password,
M2M_WIFI_CH_ALL);
} else {
printf("wifi_cb: Provision failed.\r\n");
}
} break;
default: {
break;
}
}
}
int InitWiFi()
{
tstrWifiInitParam param;
int8_t ret;
gbTcpConnection = false;
TimerStart(WIFI_RECONNECT_TIMER,1);
memset(&mModuleIPConfig,0,sizeof(mModuleIPConfig));
mModuleIPConfig.u32StaticIP = IP_TO_U32(STATIC_IP_ADDRESS_1,STATIC_IP_ADDRESS_2,STATIC_IP_ADDRESS_3,STATIC_IP_ADDRESS_4);
mModuleIPConfig.u32DNS = IP_TO_U32(DEFAULT_DNS_ADD_1,DEFAULT_DNS_ADD_2,DEFAULT_DNS_ADD_3,DEFAULT_DNS_ADD_4);
// mModuleIPConfig.u32AlternateDNS = IP_TO_U32(ALT_DNS_ADD_1,ALT_DNS_ADD_2,ALT_DNS_ADD_3,ALT_DNS_ADD_4);
mModuleIPConfig.u32Gateway = IP_TO_U32(GATEWAY_ADDRESS_1,GATEWAY_ADDRESS_2,GATEWAY_ADDRESS_3,GATEWAY_ADDRESS_4);
mModuleIPConfig.u32SubnetMask = IP_TO_U32(SUBNET_MASK_1,SUBNET_MASK_2,SUBNET_MASK_3,SUBNET_MASK_4);
/* Initialize the BSP. */
nm_bsp_init();
/* Initialize Wi-Fi parameters structure. */
memset((uint8_t *)&param, 0, sizeof(tstrWifiInitParam));
/* Initialize Wi-Fi driver with data and status callbacks. */
param.pfAppWifiCb = wifi_cb;
ret = m2m_wifi_init(&param);
if (M2M_SUCCESS != ret)
{
mWiFiInitOK = false;
mWiFiState = WIFI_INIT_ERROR_STATE;
return RET_ERROR;
}
mWiFiInitOK = true;
mWiFiState = WIFI_DISCONNECTED_STATE;
socketInit();
registerSocketCallback(socket_cb, resolve_cb);
//Get MAC address from the module
m2m_wifi_get_otp_mac_address(mac_addr, &u8IsMacAddrValid);
if (!u8IsMacAddrValid) {
m2m_wifi_set_mac_address(gau8MacAddr);
}
//Get the working MAC address from driver.
m2m_wifi_get_mac_address(gau8MacAddr);
//Initialize the human readable MAC address based on the working MAC
set_dev_name_to_mac((uint8 *)gacDeviceName, gau8MacAddr);
//Use the MAC to define the SSID of the module
set_dev_name_to_mac((uint8 *)gstrM2MAPConfig.au8SSID, gau8MacAddr);
m2m_wifi_set_device_name((uint8 *)gacDeviceName, (uint8)m2m_strlen((uint8 *)gacDeviceName));
#ifdef USE_STATIC_IP
//Use static ip --> disable dhcp client before connecting
m2m_wifi_enable_dhcp(0);
#endif
if(m2m_wifi_connect(HOME_AP_NAME,sizeof(HOME_AP_NAME),HOME_AP_SEC_TYPE,HOME_AP_PWD,M2M_WIFI_CH_ALL) != M2M_SUCCESS)
{
//wifi connect error...
printf("error");
}
tstrPerphInitParam tst;
m2m_periph_init(&tst);
//Set all IOs as inputs except the LED (IO3)..
m2m_periph_gpio_set_dir(M2M_PERIPH_GPIO3,1);
m2m_periph_gpio_set_dir(M2M_PERIPH_GPIO4,1);
m2m_periph_gpio_set_dir(M2M_PERIPH_GPIO15,1);
m2m_periph_gpio_set_dir(M2M_PERIPH_GPIO16,0);
m2m_periph_gpio_set_dir(M2M_PERIPH_GPIO18,0);
// m2m_periph_gpio_set_dir(M2M_PERIPH_GPIO6,0);
m2m_periph_gpio_set_val(M2M_PERIPH_GPIO3,0);
m2m_periph_gpio_set_val(M2M_PERIPH_GPIO4,0);
m2m_periph_gpio_set_val(M2M_PERIPH_GPIO15,0);
m2m_periph_gpio_set_val(M2M_PERIPH_GPIO16,0);
m2m_periph_gpio_set_val(M2M_PERIPH_GPIO18,0);
// m2m_periph_gpio_set_val(M2M_PERIPH_GPIO6,0);
TimerStart(WIFI_RECONNECT_TIMER,WIFI_CONNECT_TIMEOUT);
// m2m_wifi_start_provision_mode((tstrM2MAPConfig *)&gstrM2MAPConfig, (char *)gacHttpProvDomainName, 1);
// printf("Provision Mode started.\r\nConnect to [%s] via AP[%s] and fill up the page.\r\n",
// MAIN_HTTP_PROV_SERVER_DOMAIN_NAME,
// gstrM2MAPConfig.au8SSID);
}
int TurnOFFWiFi()
{
int shit;
CloseSockets();
socketDeinit();
m2m_wifi_disconnect();
m2m_wifi_deinit(&shit);
WIFI_CHP_EN_PIN = 0;
WIFI_CHP_RST_PIN = 0;
mWiFiInitOK = false;
gbConnectedWifi = false;
HEARTBEAT_LED_2_PIN = LED_OFF;
// WIFI
mWiFiState = WIFI_MODULE_OFF_STATE;
return RET_OK;
}
int CloseSockets()
{
gbTcpConnection = false;
close(TerminalServerSocket);
if(TerminalSocket != -1)
{
close(TerminalSocket);
}
close(NetworkServerSocket);
if(NetworkSocket != -1)
{
close(NetworkSocket);
}
#ifdef USE_SYSLOG
close(SyslogServerSocket);
if(SyslogSocket != -1)
{
close(SyslogSocket);
}
#endif
close(BootloaderServerSocket);
if(BootloaderSocket != -1)
{
close(BootloaderSocket);
}
}
char GetWiFiSate()
{
return mWiFiState;
}
void TickWiFi()
{
if(mWiFiInitOK == false)
{
return;
}
if(mWiFiState == WIFI_DISCONNECTED_STATE && gbConnectedWifi == false)//we should be connected.. if the timer is expired, retry
{
if(IsTimerExpired(WIFI_RECONNECT_TIMER))
{
//m2m_wifi_disconnect();
m2m_wifi_connect(HOME_AP_NAME,sizeof(HOME_AP_NAME),HOME_AP_SEC_TYPE,HOME_AP_PWD,M2M_WIFI_CH_ALL);
TimerStart(WIFI_RECONNECT_TIMER,WIFI_CONNECT_TIMEOUT);
}
}
// if(IsTimerExpired(WIFI_TICK_TIMER))
// {
m2m_wifi_handle_events(NULL);
// TimerStart(WIFI_TICK_TIMER,1);
// }
if (gbConnectedWifi && !gbTcpConnection)
{
OpenTerminalServer();
//OpenNetworkServer();
// OpenBootloaderServer();
BootloaderActivateBootloader();
#ifdef USE_SYSLOG
OpenSyslogServer();
#endif
gbTcpConnection = true;
}
}
//Terminal server implementation
int OpenTerminalServer()
{
struct sockaddr_in strAddr;
TerminalServerSocket = socket(AF_INET, SOCK_STREAM,0);
uint16 TerminalPort = TERMINAL_SERVER_PORT;
if(TerminalServerSocket >= 0)
{
strAddr.sin_family = AF_INET;
strAddr.sin_port = _htons(TerminalPort);
strAddr.sin_addr.s_addr = 0;
bind(TerminalServerSocket, (struct sockaddr*)&strAddr, sizeof(struct sockaddr_in));
return RET_OK;
}
else
{
return RET_ERROR;
}
}
void SendTerminalData(uint8 *data, int size)
{
if(TerminalSocket != -1)
{
send(TerminalSocket,data,size,0);
recv(TerminalSocket,TerminalRxBuf,sizeof(TerminalRxBuf),0);
}
}
void SentTerminalByte(uint8 data)
{
if(TerminalSocket != -1)
{
send(TerminalSocket,&data,1,0);
recv(TerminalSocket,TerminalRxBuf,sizeof(TerminalRxBuf),0);
}
}
int OpenNetworkServer()
{
struct sockaddr_in strAddr;
NetworkServerSocket = socket(AF_INET, SOCK_STREAM,0);
uint16 ServerPort = NETWORK_SERVER_PORT;
if(NetworkServerSocket >= 0)
{
strAddr.sin_family = AF_INET;
strAddr.sin_port = _htons(ServerPort);
strAddr.sin_addr.s_addr = 0;
bind(NetworkServerSocket, (struct sockaddr*)&strAddr, sizeof(struct sockaddr_in));
return RET_OK;
}
else
{
return RET_ERROR;
}
}
void SendNetworkData(uint8 *data, int size)
{
if(NetworkSocket != -1)
{
send(NetworkSocket,data,size,0);
recv(NetworkSocket,TerminalRxBuf,sizeof(TerminalRxBuf),0);
}
}
void SentNetworkByte(uint8 data)
{
if(NetworkSocket != -1)
{
send(NetworkSocket,&data,1,0);
recv(NetworkSocket,TerminalRxBuf,sizeof(TerminalRxBuf),0);
}
}
//Printf Server Implementation
#ifdef USE_SYSLOG
int OpenSyslogServer()
{
struct sockaddr_in strAddr;
SyslogServerSocket = socket(AF_INET, SOCK_STREAM,0);
uint16 ServerPort = SYSLOG_SERVER_PORT;
if(SyslogServerSocket >= 0)
{
strAddr.sin_family = AF_INET;
strAddr.sin_port = _htons(ServerPort);
strAddr.sin_addr.s_addr = 0;
bind(SyslogServerSocket, (struct sockaddr*)&strAddr, sizeof(struct sockaddr_in));
return RET_OK;
}
else
{
return RET_ERROR;
}
}
void SendSyslogData(uint8 *data, int size)
{
if(SyslogSocket != -1);
{
send(SyslogSocket,data,size,0);
recv(SyslogSocket,SyslogRxBuf,sizeof(SyslogRxBuf),0);
}
}
void SendSyslogByte(uint8 data)
{
if(SyslogSocket != -1)
{
send(SyslogSocket,&data,1,0);
recv(SyslogSocket,SyslogRxBuf,sizeof(SyslogRxBuf),0);
}
}
int IsSyslogClientConnected()
{
if(SyslogSocket == -1)
{
return 0;
}
return 1;
}
#endif
int OpenBootloaderServer()
{
struct sockaddr_in strAddr;
BootloaderServerSocket = socket(AF_INET, SOCK_STREAM,0);
uint16 ServerPort = BOOTLOADER_SERVER_PORT;
if(BootloaderServerSocket >= 0)
{
strAddr.sin_family = AF_INET;
strAddr.sin_port = _htons(ServerPort);
strAddr.sin_addr.s_addr = 0;
bind(BootloaderServerSocket, (struct sockaddr*)&strAddr, sizeof(struct sockaddr_in));
return RET_OK;
}
else
{
return RET_ERROR;
}
}
int CloseBootloaderServer()
{
close(BootloaderServerSocket);
BootloaderServerSocket = -1;
if(BootloaderSocket != -1)
{
close(BootloaderSocket);
BootloaderSocket = -1;
}
}
void SendBootloaderData(uint8 *data, int size)
{
if(BootloaderSocket != -1);
{
send(BootloaderSocket,data,size,0);
recv(BootloaderSocket,SyslogRxBuf,sizeof(SyslogRxBuf),0);
}
}
void SendSBootloaderByte(uint8 data)
{
if(BootloaderSocket != -1)
{
send(BootloaderSocket,&data,1,0);
recv(BootloaderSocket,SyslogRxBuf,sizeof(SyslogRxBuf),0);
}
}
int IsBootloaderClientConnected()
{
if(BootloaderSocket == -1)
{
return 0;
}
return 1;
}