TI's CC3100 host driver and demo. Experimental and a work in progress.
main.cpp
- Committer:
- dflet
- Date:
- 2014-11-18
- Revision:
- 1:da33a9116bda
- Parent:
- 0:bbe98578d4c0
- Child:
- 2:a3e52cf86086
File content as of revision 1:da33a9116bda:
/*
* main.c - sample application to switch to AP mode and ping client
*
* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "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 COPYRIGHT
* OWNER OR CONTRIBUTORS 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.
*
*/
/*
* Application Name - Getting started with Wi-Fi Access-Point mode
* Application Overview - This sample application demonstrates how
* to configure CC3100 in Access-Point mode. Any
* WLAN station in its range can connect/communicate
* to/with it as per the standard networking protocols.
* On a successful connection, the device ping's the
* connected station.
* Application Details - http://processors.wiki.ti.com/index.php/CC31xx_Getting_Started_with_WLAN_AP
* doc\examples\getting_started_with_wlan_ap.pdf
*/
#include "mbed.h"
#include "cc3100_simplelink.h"
#include "cc3100_sl_common.h"
#include "BoardInit.h"
#if (THIS_BOARD == MBED_BOARD_LPC1768)
Serial pc(USBTX, USBRX);//lpc1768
#elif (THIS_BOARD == ST_MBED_NUCLEOF411)
Serial pc(SERIAL_TX, SERIAL_RX);//nucleoF411
#else
#endif
//using namespace mbed_cc3100;
#define APPLICATION_VERSION "1.1.0"
#define SL_STOP_TIMEOUT 0xFF
/* Use bit 32: Lower bits of status variable are used for NWP events
* 1 in a 'status_variable', the device has completed the ping operation
* 0 in a 'status_variable', the device has not completed the ping operation
*/
//#define STATUS_BIT_PING_DONE 31
#define CONFIG_IP SL_IPV4_VAL(192,168,0,1) /* Static IP to be configured */
#define CONFIG_MASK SL_IPV4_VAL(255,255,255,0) /* Subnet Mask for the station */
#define CONFIG_GATEWAY SL_IPV4_VAL(192,168,0,1) /* Default Gateway address */
#define CONFIG_DNS SL_IPV4_VAL(192,168,0,1) /* DNS Server Address */
#define DHCP_START_IP SL_IPV4_VAL(192,168,0,100) /* DHCP start IP address */
#define DHCP_END_IP SL_IPV4_VAL(192,168,0,200) /* DHCP End IP address */
#define IP_LEASE_TIME 3600
#define PING_INTERVAL 1000
#define PING_SIZE 20
#define PING_REQUEST_TIMEOUT 3000
#define PING_ATTEMPT 3
/* Application specific status/error codes */
typedef enum{
LAN_CONNECTION_FAILED = -0x7D0, /* Choosing this number to avoid overlap with host-driver's error codes */
INTERNET_CONNECTION_FAILED = LAN_CONNECTION_FAILED - 1,
DEVICE_NOT_IN_STATION_MODE = INTERNET_CONNECTION_FAILED - 1,
STATUS_CODE_MAX = -0xBB8
}e_AppStatusCodes;
/*
#define IS_PING_DONE(status_variable) GET_STATUS_BIT(status_variable, \
STATUS_BIT_PING_DONE)
*/
/*
* GLOBAL VARIABLES -- Start
*/
//extern unsigned int g_GatewayIP = 0;
//extern unsigned int g_StationIP = 0;
unsigned int g_PingPacketsRecv = 0;
/*
* GLOBAL VARIABLES -- End
*/
/*
* STATIC FUNCTION DEFINITIONS -- Start
*/
static signed int configureSimpleLinkToDefaultState();
static signed int initializeAppVariables();
static void displayBanner();
/*
* STATIC FUNCTION DEFINITIONS -- End
*/
/*
* ASYNCHRONOUS EVENT HANDLERS -- Start
*/
/*!
\brief This function handles ping report events
\param[in] pPingReport holds the ping report statistics
\return None
\note
\warning
*/
static void SimpleLinkPingReport(SlPingReport_t *pPingReport)
{
SET_STATUS_BIT(g_Status, STATUS_BIT_PING_DONE);
if(pPingReport == NULL)
printf(" [PING REPORT] NULL Pointer Error\r\n");
g_PingPacketsRecv = pPingReport->PacketsReceived;
}
/*
* ASYNCHRONOUS EVENT HANDLERS -- End
*/
/*
* Application's entry point
*/
int main()
{
pc.baud(115200);
SlPingStartCommand_t PingParams = {0};
SlPingReport_t Report = {0};
SlNetCfgIpV4Args_t ipV4 = {0};
SlNetAppDhcpServerBasicOpt_t dhcpParams = {0};
unsigned char SecType = 0;
signed int mode = ROLE_STA;
signed int retVal = -1;
retVal = initializeAppVariables();
ASSERT_ON_ERROR(retVal);
displayBanner();
CLR_STATUS_BIT(g_Status, STATUS_BIT_PING_DONE);
g_PingPacketsRecv = 0;
/*
* Following function configures the device to default state by cleaning
* the persistent settings stored in NVMEM (viz. connection profiles &
* policies, power policy etc)
*
* Applications may choose to skip this step if the developer is sure
* that the device is in its default state at start of application
*
* Note that all profiles and persistent settings that were done on the
* device will be lost
*/
retVal = configureSimpleLinkToDefaultState();
if(retVal < 0)
{
if (DEVICE_NOT_IN_STATION_MODE == retVal)
printf(" Failed to configure the device in its default state \n\r");
LOOP_FOREVER();
}
printf(" Device is configured in default state \n\r");
/*
* Assumption is that the device is configured in station mode already
* and it is in its default state
*/
mode = sl_Start(0, 0, 0);
if (ROLE_AP == mode)
{
/* If the device is in AP mode, we need to wait for this event before doing anything */
while(!IS_IP_ACQUIRED(g_Status)) { _SlNonOsMainLoopTask(); }
}
else
{
/* Configure CC3100 to start in AP mode */
retVal = sl_WlanSetMode(ROLE_AP);
if(retVal < 0)
LOOP_FOREVER();
retVal = sl_Stop(SL_STOP_TIMEOUT);
if(retVal < 0)
LOOP_FOREVER();
CLR_STATUS_BIT(g_Status, STATUS_BIT_IP_ACQUIRED);
mode = sl_Start(0, 0, 0);
if (ROLE_AP == mode)
{
/* If the device is in AP mode, we need to wait for this event before doing anything */
while(!IS_IP_ACQUIRED(g_Status)) { _SlNonOsMainLoopTask(); }
}
else
{
printf(" Device couldn't be configured in AP mode \n\r");
LOOP_FOREVER();
}
}
printf(" Ready to configue SSID\r\n");
/* Configure the SSID of the CC3100 */
retVal = sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SSID,
pal_Strlen(SSID_AP_MODE), (unsigned char *)SSID_AP_MODE);
if(retVal < 0)
LOOP_FOREVER();
SecType = SEC_TYPE_AP_MODE;
/* Configure the Security parameter the AP mode */
retVal = sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SECURITY_TYPE, 1,
(unsigned char *)&SecType);
if(retVal < 0)
LOOP_FOREVER();
retVal = sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_PASSWORD, pal_Strlen(PASSWORD_AP_MODE),
(unsigned char *)PASSWORD_AP_MODE);
if(retVal < 0)
LOOP_FOREVER();
ipV4.ipV4 = CONFIG_IP;
ipV4.ipV4Mask = CONFIG_MASK;
ipV4.ipV4Gateway = CONFIG_GATEWAY;
ipV4.ipV4DnsServer = CONFIG_DNS;
/* Configure the Static IP */
retVal = sl_NetCfgSet(SL_IPV4_AP_P2P_GO_STATIC_ENABLE,1,sizeof(SlNetCfgIpV4Args_t),
(unsigned char *)&ipV4);
if(retVal < 0)
LOOP_FOREVER();
dhcpParams.lease_time = IP_LEASE_TIME;
dhcpParams.ipv4_addr_start = DHCP_START_IP;
dhcpParams.ipv4_addr_last = DHCP_END_IP;
retVal = sl_NetAppSet(SL_NET_APP_DHCP_SERVER_ID, NETAPP_SET_DHCP_SRV_BASIC_OPT,
sizeof(SlNetAppDhcpServerBasicOpt_t), (unsigned char*)&dhcpParams);
if(retVal < 0)
LOOP_FOREVER();
/* Restart the CC3100 */
retVal = sl_Stop(SL_STOP_TIMEOUT);
if(retVal < 0)
LOOP_FOREVER();
g_Status = 0;
mode = sl_Start(0, 0, 0);
if (ROLE_AP == mode)
{
/* If the device is in AP mode, we need to wait for this event before doing anything */
while(!IS_IP_ACQUIRED(g_Status)) { _SlNonOsMainLoopTask(); }
}
else
{
printf(" Device couldn't come in AP mode \n\r");
LOOP_FOREVER();
}
printf(" Device started as Access Point\n\r");
/* Wait */
printf(" Waiting for clients to connect...!\n\r");
while((!IS_IP_LEASED(g_Status)) || (!IS_STA_CONNECTED(g_Status))) { _SlNonOsMainLoopTask(); }
printf(" Client connected to the device \n\r");
printf(" Pinging...! \n\r");
/* Set the ping parameters */
PingParams.PingIntervalTime = PING_INTERVAL;
PingParams.PingSize = PING_SIZE;
PingParams.PingRequestTimeout = PING_REQUEST_TIMEOUT;
PingParams.TotalNumberOfAttempts = PING_ATTEMPT;
PingParams.Flags = 0;
PingParams.Ip = g_StationIP; /* Fill the station IP address connected to CC3100 */
/* Ping client connected to CC3100 */
retVal = sl_NetAppPingStart((SlPingStartCommand_t*)&PingParams, SL_AF_INET,
(SlPingReport_t*)&Report, SimpleLinkPingReport);
if(retVal < 0)
LOOP_FOREVER();
/* Wait */
while(!IS_PING_DONE(g_Status)) { _SlNonOsMainLoopTask(); }
if (0 == g_PingPacketsRecv)
{
printf(" A STATION couldn't connect to the device \n\r");
ASSERT_ON_ERROR(LAN_CONNECTION_FAILED);
}
printf(" Device and the station are successfully connected \n\r");
return SUCCESS;
}
/*!
\brief This function configure the SimpleLink device in its default state. It:
- Sets the mode to STATION
- Configures connection policy to Auto and AutoSmartConfig
- Deletes all the stored profiles
- Enables DHCP
- Disables Scan policy
- Sets Tx power to maximum
- Sets power policy to normal
- Unregisters mDNS services
- Remove all filters
\param[in] none
\return On success, zero is returned. On error, negative is returned
*/
static signed int configureSimpleLinkToDefaultState()
{
SlVersionFull ver = {0};
_WlanRxFilterOperationCommandBuff_t RxFilterIdMask = {0};
unsigned char val = 1;
unsigned char configOpt = 0;
unsigned char configLen = 0;
unsigned char power = 0;
signed int retVal = -1;
signed int mode = -1;
mode = sl_Start(0, 0, 0);
ASSERT_ON_ERROR(mode);
/* If the device is not in station-mode, try configuring it in station-mode */
if (ROLE_STA != mode)
{
if (ROLE_AP == mode)
{
/* If the device is in AP mode, we need to wait for this event before doing anything */
while(!IS_IP_ACQUIRED(g_Status)) { _SlNonOsMainLoopTask(); }
}
/* Switch to STA role and restart */
retVal = sl_WlanSetMode(ROLE_STA);
ASSERT_ON_ERROR(retVal);
retVal = sl_Stop(SL_STOP_TIMEOUT);
ASSERT_ON_ERROR(retVal);
retVal = sl_Start(0, 0, 0);
ASSERT_ON_ERROR(retVal);
/* Check if the device is in station again */
if (ROLE_STA != retVal)
{
/* We don't want to proceed if the device is not coming up in station-mode */
ASSERT_ON_ERROR(DEVICE_NOT_IN_STATION_MODE);
}
}
/* Get the device's version-information */
configOpt = SL_DEVICE_GENERAL_VERSION;
configLen = sizeof(ver);
retVal = sl_DevGet(SL_DEVICE_GENERAL_CONFIGURATION, &configOpt, &configLen, (unsigned char *)(&ver));
ASSERT_ON_ERROR(retVal);
/* Set connection policy to Auto + SmartConfig (Device's default connection policy) */
retVal = sl_WlanPolicySet(SL_POLICY_CONNECTION, SL_CONNECTION_POLICY(1, 0, 0, 0, 1), NULL, 0);
ASSERT_ON_ERROR(retVal);
/* Remove all profiles */
retVal = sl_WlanProfileDel(0xFF);
ASSERT_ON_ERROR(retVal);
/*
* Device in station-mode. Disconnect previous connection if any
* The function returns 0 if 'Disconnected done', negative number if already disconnected
* Wait for 'disconnection' event if 0 is returned, Ignore other return-codes
*/
retVal = sl_WlanDisconnect();
if(0 == retVal)
{
/* Wait */
while(IS_CONNECTED(g_Status)) { _SlNonOsMainLoopTask(); }
}
/* Enable DHCP client*/
retVal = sl_NetCfgSet(SL_IPV4_STA_P2P_CL_DHCP_ENABLE,1,1,&val);
ASSERT_ON_ERROR(retVal);
/* Disable scan */
configOpt = SL_SCAN_POLICY(0);
retVal = sl_WlanPolicySet(SL_POLICY_SCAN , configOpt, NULL, 0);
ASSERT_ON_ERROR(retVal);
/* Set Tx power level for station mode
Number between 0-15, as dB offset from maximum power - 0 will set maximum power */
power = 0;
retVal = sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_STA_TX_POWER, 1, (unsigned char *)&power);
ASSERT_ON_ERROR(retVal);
/* Set PM policy to normal */
retVal = sl_WlanPolicySet(SL_POLICY_PM , SL_NORMAL_POLICY, NULL, 0);
ASSERT_ON_ERROR(retVal);
/* Unregister mDNS services */
retVal = sl_NetAppMDNSUnRegisterService(0, 0);
ASSERT_ON_ERROR(retVal);
/* Remove all 64 filters (8*8) */
pal_Memset(RxFilterIdMask.FilterIdMask, 0xFF, 8);
retVal = sl_WlanRxFilterSet(SL_REMOVE_RX_FILTER, (unsigned char *)&RxFilterIdMask,
sizeof(_WlanRxFilterOperationCommandBuff_t));
ASSERT_ON_ERROR(retVal);
retVal = sl_Stop(SL_STOP_TIMEOUT);
ASSERT_ON_ERROR(retVal);
retVal = initializeAppVariables();
ASSERT_ON_ERROR(retVal);
return retVal; /* Success */
}
/*!
\brief This function initializes the application variables
\param[in] None
\return 0 on success, negative error-code on error
*/
static signed int initializeAppVariables()
{
//g_Status = 0;
//g_PingPacketsRecv = 0;
//g_StationIP = 0;
return SUCCESS;
}
/*!
\brief This function displays the application's banner
\param None
\return None
*/
static void displayBanner()
{
printf("\n\r\n\r");
printf(" Getting started with WLAN access-point application - Version ");
printf("%s",APPLICATION_VERSION);
printf("\n\r*******************************************************************\n\r");
}