Frank Vannieuwkerke / Mbed 2 deprecated Wi-Go_IOT_Demo

Dependencies:   mbed CC3000_Hostdriver TEMT6200 TSI Wi-Go_eCompass_Lib_V3 WiGo_BattCharger

Fork of CC3000_Simple_Socket by Frank Vannieuwkerke

cc3000.cpp

Committer:
frankvnk
Date:
2013-12-11
Revision:
16:dceb9f5108f7
Parent:
9:5d431f47ac93

File content as of revision 16:dceb9f5108f7:

/*****************************************************************************
*
*  cc3000 - CC3000 Functions Implementation
*  Copyright (C) 2011 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.
*
*****************************************************************************/

#include "cc3000.h"
#include "doTCPIP.h"

DigitalOut ledr (LED_RED);
DigitalOut ledg (LED_GREEN);
DigitalOut ledb (LED_BLUE);
DigitalOut led1 (PTB8);
DigitalOut led2 (PTB9);
DigitalOut led3 (PTB10);

long ulSocket;

unsigned char pucIP_Addr[4];
unsigned char pucIP_DefaultGWAddr[4];
unsigned char pucSubnetMask[4];
unsigned char pucDNS[4];

sockaddr tSocketAddr;

unsigned char prefixChangeFlag = 0;
unsigned char prefixFromUser[3] = {0};
char * ftcPrefixptr;

char aucCC3000_prefix[] = {'T', 'T', 'T'};      // Smart Config Prefix

tNetappIpconfigRetArgs ipinfo;

char cc3000state = CC3000_UNINIT;
extern unsigned char ConnectUsingSmartConfig; 
extern volatile unsigned long ulCC3000Connected;
extern volatile unsigned long SendmDNSAdvertisment;
extern int server_running;
extern char DevServname[];
volatile unsigned long ulSmartConfigFinished, ulCC3000DHCP, OkToDoShutDown, ulCC3000DHCP_configured;
volatile unsigned char ucStopSmartConfig;
unsigned char pucCC3000_Rx_Buffer[CC3000_APP_BUFFER_SIZE + CC3000_RX_BUFFER_OVERHEAD_SIZE];

#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
const unsigned char smartconfigkey[] = {0x73,0x6d,0x61,0x72,0x74,0x63,0x6f,0x6e,0x66,0x69,0x67,0x41,0x45,0x53,0x31,0x36};
#endif


void initLEDs(void)
{
    RED_OFF;
    GREEN_OFF;
    BLUE_OFF;
    LED_D1_OFF;
    LED_D2_OFF;
    LED_D3_OFF;
}


int ConnectUsingSSID(char * ssidName)
{
    unsetCC3000MachineState(CC3000_ASSOC);
    // Disable Profiles and Fast Connect
    wlan_ioctl_set_connection_policy(0, 0, 0);
    wlan_disconnect();
    wait_ms(2);
    // This triggers the CC3000 to connect to specific AP with certain parameters
    //sends a request to connect (does not necessarily connect - callback checks that for me)
    // wlan_connect(SECURITY, SSID, strlen(SSID), NULL, PASSPHRASE, strlen(PASSPHRASE));
#ifndef CC3000_TINY_DRIVER
    #ifndef AP_KEY 
        wlan_connect(0, ssidName, strlen(ssidName), NULL, NULL, 0);
    #else
        wlan_connect(AP_SECURITY, ssidName, strlen(ssidName), NULL, (unsigned char *)AP_KEY , strlen(AP_KEY));
    #endif
#else
    wlan_connect(ssidName, strlen(ssidName));
#endif
    // We don't wait for connection. This is handled somewhere else (in the main loop for example).
    return 0;      
}


void CC3000_UsynchCallback(long lEventType, char * data, unsigned char length)
{
    if (lEventType == HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE)
    {
        ulSmartConfigFinished = 1;
        ucStopSmartConfig     = 1;  
    }
    if (lEventType == HCI_EVNT_WLAN_UNSOL_CONNECT)
    {
        ulCC3000Connected = 1;
        LED_D2_ON;
    }
    if (lEventType == HCI_EVNT_WLAN_UNSOL_DISCONNECT)
    {       
        ulCC3000Connected = 0;
        ulCC3000DHCP      = 0;
        ulCC3000DHCP_configured = 0;
        LED_D2_OFF;
        LED_D3_OFF;
    }
    if (lEventType == HCI_EVNT_WLAN_UNSOL_DHCP)
    {
        // Notes: 
        // 1) IP config parameters are received swapped
        // 2) IP config parameters are valid only if status is OK, i.e. ulCC3000DHCP becomes 1
        // only if status is OK, the flag is set to 1 and the addresses are valid
        if ( *(data + NETAPP_IPCONFIG_MAC_OFFSET) == 0)
        {
            sprintf( (char*)pucCC3000_Rx_Buffer,"IP:%d.%d.%d.%d\f\r", data[3],data[2], data[1], data[0] );
            ulCC3000DHCP = 1;
            LED_D3_ON;
        }
        else
        {
            ulCC3000DHCP = 0;
            LED_D3_OFF;
        }
    }
    if (lEventType == HCI_EVENT_CC3000_CAN_SHUT_DOWN)
    {
        OkToDoShutDown = 1;
    }
}


int initDriver(void)
{
    wlan_start(0);
#if IP_ALLOC_METHOD == USE_DHCP
    
    // DHCP is used by default
    // Subnet mask is assumed to be 255.255.255.0
    pucSubnetMask[0] = 0;
    pucSubnetMask[1] = 0;
    pucSubnetMask[2] = 0;
    pucSubnetMask[3] = 0;
    
    // CC3000's IP
    pucIP_Addr[0] = 0;
    pucIP_Addr[1] = 0;
    pucIP_Addr[2] = 0;
    pucIP_Addr[3] = 0;
    
    // Default Gateway/Router IP
    // 192.168.1.1
    pucIP_DefaultGWAddr[0] = 0;
    pucIP_DefaultGWAddr[1] = 0;
    pucIP_DefaultGWAddr[2] = 0;
    pucIP_DefaultGWAddr[3] = 0;
    
    // We assume the router is also a DNS server
    pucDNS[0] = 0;
    pucDNS[1] = 0;
    pucDNS[2] = 0;
    pucDNS[3] = 0;
    
    // Force DHCP
    netapp_dhcp((unsigned long *)pucIP_Addr,
                (unsigned long *)pucSubnetMask, 
                (unsigned long *)pucIP_DefaultGWAddr,
                (unsigned long *)pucDNS);

    // reset the CC3000
    wlan_stop();
    wait_ms(500);
    wlan_start(0);
    
#elif IP_ALLOC_METHOD == USE_STATIC_IP

    // Subnet mask is assumed to be 255.255.255.0
    pucSubnetMask[0] = 0xFF;
    pucSubnetMask[1] = 0xFF;
    pucSubnetMask[2] = 0xFF;
    pucSubnetMask[3] = 0x0;
    
    // CC3000's IP
    pucIP_Addr[0] = STATIC_IP_OCT1;
    pucIP_Addr[1] = STATIC_IP_OCT2;
    pucIP_Addr[2] = STATIC_IP_OCT3;
    pucIP_Addr[3] = STATIC_IP_OCT4;
    
    // Default Gateway/Router IP
    // 192.168.1.1
    pucIP_DefaultGWAddr[0] = STATIC_IP_OCT1;
    pucIP_DefaultGWAddr[1] = STATIC_IP_OCT2;
    pucIP_DefaultGWAddr[2] = STATIC_IP_OCT3;
    pucIP_DefaultGWAddr[3] = STATIC_GW_OCT4;
    
    // We assume the router is also a DNS server
    pucDNS[0] = STATIC_IP_OCT1;
    pucDNS[1] = STATIC_IP_OCT2;
    pucDNS[2] = STATIC_IP_OCT3;
    pucDNS[3] = STATIC_GW_OCT4;
    
    netapp_dhcp((unsigned long *)pucIP_Addr,
                (unsigned long *)pucSubnetMask, 
                (unsigned long *)pucIP_DefaultGWAddr,
                (unsigned long *)pucDNS);    

    // reset the CC3000 to apply Static Setting
    wlan_stop();
    wait_ms(500);
    wlan_start(0);
    
#else 
#error No IP Configuration Method Selected. One must be configured.
#endif

    // Mask out all non-required events from CC3000
    wlan_set_event_mask(HCI_EVNT_WLAN_KEEPALIVE|
                        HCI_EVNT_WLAN_UNSOL_INIT|
                        HCI_EVNT_WLAN_ASYNC_PING_REPORT);
       
    // CC3000 has been initialized
    setCC3000MachineState(CC3000_INIT);
    return(0);
}


char highestCC3000State()
{
    // We start at the highest state and go down, checking if the state
    // is set.
    char mask = 0x80;
    while(!(cc3000state & mask))
    {
        mask = mask >> 1;
    }
    return mask;
}


char currentCC3000State(void)
{
    return cc3000state;
}


void setCC3000MachineState(char stat)
{       
    cc3000state |= stat;
}


void unsetCC3000MachineState(char stat)
{
    char bitmask = stat;
    cc3000state &= ~bitmask;

    // Set all upper bits to 0 as well since state machine cannot have
    // those states.
    while(bitmask < 0x80)
    {
        cc3000state &= ~bitmask;
        bitmask = bitmask << 1;
    }
}


void resetCC3000StateMachine()
{
    cc3000state = CC3000_UNINIT;
}


#ifndef CC3000_TINY_DRIVER
tNetappIpconfigRetArgs * getCC3000Info()
{
    if(!(currentCC3000State() & CC3000_SERVER_INIT))
    {
        // If we're not blocked by accept or others, obtain the latest
        netapp_ipconfig(&ipinfo);
    }    
    return (&ipinfo);
}
#endif


void StartSmartConfig(void)
{
    server_running = 1;
    RED_OFF;
    GREEN_OFF;
    BLUE_ON;

    // Reset all the previous configuration
    wlan_ioctl_set_connection_policy(0, 0, 0);  
    wlan_ioctl_del_profile(255);

    //Wait until CC3000 is disconected
    while (ulCC3000Connected == 1)
    {
        wait_us(2);
        hci_unsolicited_event_handler();
    }

    // Trigger the Smart Config process
    // Start blinking RED/GREEN during Smart Configuration process
    wlan_smart_config_set_prefix(aucCC3000_prefix);
    // Start the Smart Config process with AES disabled
    wlan_smart_config_start(0);
    BLUE_OFF;
    RED_ON;
    // Wait for Smart config finished
    while (ulSmartConfigFinished == 0)
    {
        wait_ms(125);
        RED_ON;
        GREEN_OFF;
        wait_ms(125);
        GREEN_ON;     
        RED_OFF;                 
    }
    BLUE_ON;
#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
    // create new entry for AES encryption key
    nvmem_create_entry(NVMEM_AES128_KEY_FILEID,16);
    // write AES key to NVMEM
    aes_write_key((unsigned char *)(&smartconfigkey[0]));
    // Decrypt configuration information and add profile
    wlan_smart_config_process();
#endif
//    wlan_smart_config_process();

    // Configure to connect automatically to the AP retrieved in the 
    // Smart config process
    wlan_ioctl_set_connection_policy(0, 1, 1);
    
    // reset the CC3000
    wlan_stop();
    wait(2);
    wlan_start(0);
    wait(2);
    ConnectUsingSmartConfig = 1; 

    // Mask out all non-required events
    wlan_set_event_mask(HCI_EVNT_WLAN_KEEPALIVE|HCI_EVNT_WLAN_UNSOL_INIT|HCI_EVNT_WLAN_ASYNC_PING_REPORT);
    RED_OFF;
    BLUE_OFF;
    GREEN_OFF;
}