From 081396c18da58b8dd88cb25eb3fe186e5eb776b6 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 16 Oct 2013 07:30:54 -0600 Subject: [PATCH] Updated CC30000 example from David Sidrane --- ChangeLog.txt | 2 + examples/cc3000/board.c | 219 +++---- examples/cc3000/cc3000basic.c | 1036 +++++++++++++++++---------------- 3 files changed, 613 insertions(+), 644 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index a7446ca07..6e17e77af 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -684,4 +684,6 @@ * apps/Makefile: Need to include external/Make.defs if we want allow external applications to participate in the NuttX configuration. Suggested by gdi@embedders.org (2013-10-14). + * apps/examplex/cc3300: Updates as part of larger re-organizaion + of CC3000 logic by David Sidrane (2013-10-16). diff --git a/examples/cc3000/board.c b/examples/cc3000/board.c index 2794a7f0e..bca494b7f 100644 --- a/examples/cc3000/board.c +++ b/examples/cc3000/board.c @@ -10,9 +10,9 @@ * and the routines in the SPI files, will be different for an Arduino, * a TI MSP430, a PIC, etc. but the core library shouldn't have to be * changed. -* +* * Version 1.0.1b -* +* * Copyright (C) 2013 Chris Magagna - cmagagna@yahoo.com * * Redistribution and use in source and binary forms, with or without @@ -23,25 +23,20 @@ * ****************************************************************************/ - #include "board.h" #include #include #include -#include -#include - +#include volatile unsigned long ulSmartConfigFinished, - ulCC3000Connected, - ulCC3000DHCP, - OkToDoShutDown, - ulCC3000DHCP_configured; + ulCC3000Connected, + ulCC3000DHCP, + OkToDoShutDown, + ulCC3000DHCP_configured; volatile uint8_t ucStopSmartConfig; - - #define NETAPP_IPCONFIG_MAC_OFFSET (20) #define CC3000_APP_BUFFER_SIZE (5) #define CC3000_RX_BUFFER_OVERHEAD_SIZE (20) @@ -50,167 +45,137 @@ volatile uint8_t ucStopSmartConfig; uint8_t pucCC3000_Rx_Buffer[CC3000_APP_BUFFER_SIZE + CC3000_RX_BUFFER_OVERHEAD_SIZE]; */ - /* The original version of the function below had Serial.prints() to display an event, but since an async event can happen at any time, even in the middle of another Serial.print(), sometimes the sketch would lock up because we were trying to print in the middle of a print. - + So now we just set a flag and write to a string, and the master loop can deal with it when it wants. -*/ +*/ + uint8_t asyncNotificationWaiting = false; long lastAsyncEvent; uint8_t dhcpIPAddress[4]; - /*------------------------------------------------------------------- The TI library calls this routine when asynchronous events happen. - + For example you tell the CC3000 to turn itself on and connect to an access point then your code can go on to do its own thing. When the CC3000 is done configuring itself (e.g. it gets an IP address from the DHCP server) it will call this routine so you - can take appropriate action. + can take appropriate action. ---------------------------------------------------------------------*/ - void CC3000_AsyncCallback(long lEventType, char * data, uint8_t length) { + lastAsyncEvent = lEventType; - lastAsyncEvent = lEventType; - - switch (lEventType) { - - case HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE: - ulSmartConfigFinished = 1; - ucStopSmartConfig = 1; - asyncNotificationWaiting=true; - break; - - case HCI_EVNT_WLAN_UNSOL_CONNECT: - ulCC3000Connected = 1; - asyncNotificationWaiting=true; - break; - - case HCI_EVNT_WLAN_UNSOL_DISCONNECT: - ulCC3000Connected = 0; - ulCC3000DHCP = 0; - ulCC3000DHCP_configured = 0; - asyncNotificationWaiting=true; - break; - - case 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) { - ulCC3000DHCP = 1; - dhcpIPAddress[0] = data[3]; - dhcpIPAddress[1] = data[2]; - dhcpIPAddress[2] = data[1]; - dhcpIPAddress[3] = data[0]; - } - else { - ulCC3000DHCP = 0; - dhcpIPAddress[0] = 0; - dhcpIPAddress[1] = 0; - dhcpIPAddress[2] = 0; - dhcpIPAddress[3] = 0; - } - asyncNotificationWaiting=true; - break; - - case HCI_EVENT_CC3000_CAN_SHUT_DOWN: - OkToDoShutDown = 1; - asyncNotificationWaiting=true; - break; - - default: - asyncNotificationWaiting=true; - break; - } - } + switch (lEventType) + { + case HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE: + ulSmartConfigFinished = 1; + ucStopSmartConfig = 1; + asyncNotificationWaiting=true; + break; + + case HCI_EVNT_WLAN_UNSOL_CONNECT: + ulCC3000Connected = 1; + asyncNotificationWaiting=true; + break; + + case HCI_EVNT_WLAN_UNSOL_DISCONNECT: + ulCC3000Connected = 0; + ulCC3000DHCP = 0; + ulCC3000DHCP_configured = 0; + asyncNotificationWaiting=true; + break; + + case 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) + { + ulCC3000DHCP = 1; + dhcpIPAddress[0] = data[3]; + dhcpIPAddress[1] = data[2]; + dhcpIPAddress[2] = data[1]; + dhcpIPAddress[3] = data[0]; + } + else + { + ulCC3000DHCP = 0; + dhcpIPAddress[0] = 0; + dhcpIPAddress[1] = 0; + dhcpIPAddress[2] = 0; + dhcpIPAddress[3] = 0; + } + asyncNotificationWaiting=true; + break; + + case HCI_EVENT_CC3000_CAN_SHUT_DOWN: + OkToDoShutDown = 1; + asyncNotificationWaiting=true; + break; + + default: + asyncNotificationWaiting=true; + break; + } +} /*------------------------------------------------------------------- The TI library calls these routines on CC3000 startup. - + This library does not send firmware, driver, or bootloader patches so we do nothing and we return NULL. ---------------------------------------------------------------------*/ -char *SendFirmwarePatch(unsigned long *Length) { - *Length = 0; - return NULL; +char *SendFirmwarePatch(unsigned long *Length) +{ + *Length = 0; + return NULL; } - -char *SendDriverPatch(unsigned long *Length) { - *Length = 0; - return NULL; +char *SendDriverPatch(unsigned long *Length) +{ + *Length = 0; + return NULL; } - -char *SendBootloaderPatch(unsigned long *Length) { - *Length = 0; - return NULL; +char *SendBootloaderPatch(unsigned long *Length) +{ + *Length = 0; + return NULL; } -/*------------------------------------------------------------------- - - The TI library calls these routines to enable or disable interrupts - on the WLAN_IRQ pin. - - Originally WlanInterruptEnable() called attachInterrupt() and - WlanInterruptDisable() called detachInterrupt() but the library - was occationally locking up here, so now these routines just - set a flag. The interrupt routine will always fire but if the - flag isn't set it just returns immediately. - - --------------------------------------------------------------------*/ - -void WlanInterruptEnable(void) { - SPIInterruptsEnabled = 1; -} - - -void WlanInterruptDisable(void) { - SPIInterruptsEnabled = 0; -} - - /*------------------------------------------------------------------- This is my routine to simplify CC3000 startup. - + It sets the Arduino pins then calls the normal CC3000 routines wlan_init() with all the callbacks and wlan_start() with 0 to indicate we're not sending any patches. - + --------------------------------------------------------------------*/ -void CC3000_Init(void) { - - SPIInterruptsEnabled = 0; - - Wlan_Setup(); - - wlan_init( CC3000_AsyncCallback, - SendFirmwarePatch, - SendDriverPatch, - SendBootloaderPatch, - ReadWlanInterruptPin, - WlanInterruptEnable, - WlanInterruptDisable, - WriteWlanEnablePin); - - wlan_start(0); +void CC3000_Init(void) +{ + wireless_archinitialize(); + + CC3000_wlan_init( CC3000_AsyncCallback, + SendFirmwarePatch, + SendDriverPatch, + SendBootloaderPatch); + + wlan_start(0); } - diff --git a/examples/cc3000/cc3000basic.c b/examples/cc3000/cc3000basic.c index c50b9de86..3c53a873d 100644 --- a/examples/cc3000/cc3000basic.c +++ b/examples/cc3000/cc3000basic.c @@ -15,8 +15,6 @@ * **************************************************************************** - - To connect an Arduino to the CC3000 you'll need to make these 6 connections (in addition to the WiFi antenna, power etc). @@ -54,17 +52,14 @@ VBAT_SW_EN / 26 / J5-5 Module enable on. Any pin can be used. In this program it will be called WLAN_EN - WARNING #1: The CC3000 runs at 3.6V maximum so you can't run it from your regular 5V Arduino power pin. Run it from 3.3V! - WARNING #2: When transmitting the CC3000 will use up to 275mA current. Most Arduinos' 3.3V pins can only supply up to 50mA current, so you'll need a separate power supply for it (or a voltage regulator like the LD1117V33 connected to your Arduino's 5V power pin). - WARNING #3: The CC3000's IO pins are not 5V tolerant. If you're using a 5V Arduino you will need a level shifter to convert these signals to 3.3V so you don't blow up the module. @@ -86,7 +81,6 @@ Arduino pin -----> 560 Ohm --+--> 1K Ohm -----> GND ****************************************************************************/ - #include "board.h" #include #include @@ -95,7 +89,7 @@ Arduino pin -----> 560 Ohm --+--> 1K Ohm -----> GND #include #include #include -#include +#include #include #include #include @@ -118,151 +112,159 @@ void ShowInformation(void); // When operations that take a long time (like Smart Config) are running, the // function Blinker() flashes this LED. It's not required for actual use. -#define BLINKER_LED 6 +#define BLINKER_LED 6 uint8_t isInitialized = false; +void AsyncEventPrint(void) +{ + switch(lastAsyncEvent) + { + printf("CC3000 Async event: Simple config done\n"); + break; -void AsyncEventPrint(void) { - switch(lastAsyncEvent) { - printf("CC3000 Async event: Simple config done\n"); - break; + case HCI_EVNT_WLAN_UNSOL_CONNECT: + printf("CC3000 Async event: Unsolicited connect\n"); + break; - case HCI_EVNT_WLAN_UNSOL_CONNECT: - printf("CC3000 Async event: Unsolicited connect\n"); - break; + case HCI_EVNT_WLAN_UNSOL_DISCONNECT: + printf("CC3000 Async event: Unsolicted disconnect\n"); + break; - case HCI_EVNT_WLAN_UNSOL_DISCONNECT: - printf("CC3000 Async event: Unsolicted disconnect\n"); - break; + case HCI_EVNT_WLAN_UNSOL_DHCP: + printf("CC3000 Async event: Got IP address via DHCP: "); + printf("%d", dhcpIPAddress[0]); + printf("."); + printf("%d", dhcpIPAddress[1]); + printf("."); + printf("%d", dhcpIPAddress[2]); + printf("."); + printf("%d\n", dhcpIPAddress[3]); + break; - case HCI_EVNT_WLAN_UNSOL_DHCP: - printf("CC3000 Async event: Got IP address via DHCP: "); - printf("%d", dhcpIPAddress[0]); - printf("."); - printf("%d", dhcpIPAddress[1]); - printf("."); - printf("%d", dhcpIPAddress[2]); - printf("."); - printf("%d\n", dhcpIPAddress[3]); - break; + case HCI_EVENT_CC3000_CAN_SHUT_DOWN: + printf("CC3000 Async event: OK to shut down\n"); + break; - case HCI_EVENT_CC3000_CAN_SHUT_DOWN: - printf("CC3000 Async event: OK to shut down\n"); - break; + case HCI_EVNT_WLAN_KEEPALIVE: + // Once initialized, the CC3000 will send these keepalive events + // every 20 seconds. + printf("CC3000 Async event: Keepalive\n"); + return; + break; - case HCI_EVNT_WLAN_KEEPALIVE: - // Once initialized, the CC3000 will send these keepalive events - // every 20 seconds. - printf("CC3000 Async event: Keepalive\n"); - return; - break; - - default: - printf("AsyncCallback called with unhandled event! (0x%X)\n", lastAsyncEvent); - break; - } - - } - - -void helpme(void) { - - printf("\n+-------------------------------------------+\n"); - printf("| Arduino CC3000 Demo Program |\n"); - printf("+-------------------------------------------+\n\n"); - printf(" 1 - Initialize the CC3000\n"); - printf(" 2 - Show RX & TX buffer sizes, & free RAM\n"); - printf(" 3 - Start Smart Config\n"); - printf(" 4 - Manually connect to AP\n"); - printf(" 5 - Manually add connection profile\n"); - printf(" 6 - List access points\n"); - printf(" 7 - Show CC3000 information\n"); - printf("\n Type 1-7 to select above option or (q/Q) to quit: "); + default: + printf("AsyncCallback called with unhandled event! (0x%X)\n", lastAsyncEvent); + break; + } } +void helpme(void) +{ + printf("\n+-------------------------------------------+\n"); + printf("| Arduino CC3000 Demo Program |\n"); + printf("+-------------------------------------------+\n\n"); + printf(" 1 - Initialize the CC3000\n"); + printf(" 2 - Show RX & TX buffer sizes, & free RAM\n"); + printf(" 3 - Start Smart Config\n"); + printf(" 4 - Manually connect to AP\n"); + printf(" 5 - Manually add connection profile\n"); + printf(" 6 - List access points\n"); + printf(" 7 - Show CC3000 information\n"); + printf("\n Type 1-7 to select above option or (q/Q) to quit: "); +} void execute(int cmd) { - if (asyncNotificationWaiting) { - asyncNotificationWaiting = false; - AsyncEventPrint(); - } + if (asyncNotificationWaiting) + { + asyncNotificationWaiting = false; + AsyncEventPrint(); + } - switch(cmd) { - case '1': - Initialize(); - break; - case '2': - ShowBufferSize(); - ShowFreeRAM(); - break; - case '3': - StartSmartConfig(); - break; - case '4': - ManualConnect(); - break; - case '5': - ManualAddProfile(); - break; - case '6': - ListAccessPoints(); - break; - case '7': - ShowInformation(); - break; - default: - printf("**Unknown command \"%d\" **\n", cmd); - break; - } + switch(cmd) + { + case '1': + Initialize(); + break; + case '2': + ShowBufferSize(); + ShowFreeRAM(); + break; + case '3': + StartSmartConfig(); + break; + case '4': + ManualConnect(); + break; + case '5': + ManualAddProfile(); + break; + case '6': + ListAccessPoints(); + break; + case '7': + ShowInformation(); + break; + default: + printf("**Unknown command \"%d\" **\n", cmd); + break; + } - return; + return; } - void Initialize(void) { + uint8_t fancyBuffer[MAC_ADDR_LEN], i = 0; - uint8_t fancyBuffer[MAC_ADDR_LEN], i = 0; + if (isInitialized) + { + printf("CC3000 already initialized. Shutting down and restarting...\n"); + wlan_stop(); + usleep(1000000); //delay 1s + } - if (isInitialized) { - printf("CC3000 already initialized. Shutting down and restarting...\n"); - wlan_stop(); - usleep(1000000); //delay 1s - } + printf("Initializing CC3000...\n"); + CC3000_Init(); + printf(" CC3000 init complete.\n"); - printf("Initializing CC3000...\n"); - CC3000_Init(); - printf(" CC3000 init complete.\n"); + if (nvmem_read_sp_version(fancyBuffer) == 0) + { + printf(" Firmware version is: "); + printf("%d", fancyBuffer[0]); + printf("."); + printf("%d\n", fancyBuffer[1]); + } + else + { + printf("Unable to get firmware version. Can't continue.\n"); + return; + } - if (nvmem_read_sp_version(fancyBuffer)==0) { - printf(" Firmware version is: "); - printf("%d", fancyBuffer[0]); - printf("."); - printf("%d\n", fancyBuffer[1]); - } - else { - printf("Unable to get firmware version. Can't continue.\n"); - return; - } - - /*if (nvmem_get_mac_address(fancyBuffer)==0) { - printf(" MAC address: "); - for (i=0; i 3000000) //3s - { - printf(" Timed out waiting for Smart Config to finish. Hopefully it did anyway\n"); - break; - } - } + printf(" Starting smart config..."); + if ((rval = wlan_smart_config_start(0))!=0) { + printf(" Starting smart config failed, error: %X\n", rval); + return; + } - printf(" Smart Config packet seen!\n"); + // Wait for Smartconfig process complete, or 30 seconds, whichever + // comes first. The Uno isn't seeing the HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE + // event and I can't figure out why (it works fine on the Teensy) so my + // temporary workaround is I just stop waiting after a while + gettimeofday(&start, NULL); + while (ulSmartConfigFinished == 0) + { + Blinker(); + gettimeofday(&end, NULL); + t_us = ((end.tv_sec - start.tv_sec) * 1000*1000) + (end.tv_usec - start.tv_usec) ; + if (t_us > 3000000) //3s + { + printf(" Timed out waiting for Smart Config to finish. Hopefully it did anyway\n"); + break; + } + } - printf(" Enabling auto-connect policy...\n"); - if ((rval=wlan_ioctl_set_connection_policy(DISABLE, DISABLE, ENABLE))!=0) - { - printf(" Setting auto connection policy failed, error: %X\n", rval); - return; - } + printf(" Smart Config packet seen!\n"); - printf(" Stopping CC3000...\n"); - wlan_stop(); // no error returned here, so nothing to check + printf(" Enabling auto-connect policy...\n"); + if ((rval=wlan_ioctl_set_connection_policy(DISABLE, DISABLE, ENABLE))!=0) + { + printf(" Setting auto connection policy failed, error: %X\n", rval); + return; + } - printf(" Pausing for 2 seconds...\n"); - usleep(2000000); + printf(" Stopping CC3000...\n"); + wlan_stop(); // no error returned here, so nothing to check - printf(" Restarting CC3000... \n"); - wlan_start(0); // no error returned here, so nothing to check + printf(" Pausing for 2 seconds...\n"); + usleep(2000000); - printf(" Waiting for connection to AP...\n"); - while (ulCC3000Connected!=1) - { - Blinker(); - } - - printf(" Waiting for IP address from DHCP...\n"); - while (ulCC3000DHCP!=1) - { - Blinker(); - } - - printf(" Sending mDNS broadcast to signal we're done with Smart Config...\n"); - mdnsAdvertiser(1,device_name,strlen(device_name)); // The API documentation says mdnsAdvertiser() - // is supposed to return 0 on success and SOC_ERROR on failure, but it looks like - // what it actually returns is the socket number it used. So we ignore it. + printf(" Restarting CC3000... \n"); + wlan_start(0); // no error returned here, so nothing to check - printf(" Smart Config finished!\n"); + printf(" Waiting for connection to AP...\n"); + while (ulCC3000Connected!=1) + { + Blinker(); + } + + printf(" Waiting for IP address from DHCP...\n"); + while (ulCC3000DHCP!=1) + { + Blinker(); + } + + printf(" Sending mDNS broadcast to signal we're done with Smart Config...\n"); + mdnsAdvertiser(1,device_name,strlen(device_name)); // The API documentation says mdnsAdvertiser() + // is supposed to return 0 on success and SOC_ERROR on failure, but it looks like + // what it actually returns is the socket number it used. So we ignore it. + + printf(" Smart Config finished!\n"); } /* - This is an example of how you'd connect the CC3000 to an AP without using - Smart Config or a stored profile. - - All the code above wlan_connect() is just for this demo program; if you're - always going to connect to your network this way you wouldn't need it. + This is an example of how you'd connect the CC3000 to an AP without using + Smart Config or a stored profile. + + All the code above wlan_connect() is just for this demo program; if you're + always going to connect to your network this way you wouldn't need it. */ void ManualConnect(void) { - char ssidName[] = "YourAP"; - char AP_KEY[] = "yourpass"; - uint8_t rval; + char ssidName[] = "YourAP"; + char AP_KEY[] = "yourpass"; + uint8_t rval; - if (!isInitialized) - { - printf("CC3000 not initialized; can't run manual connect.\n"); - return; - } + if (!isInitialized) + { + printf("CC3000 not initialized; can't run manual connect.\n"); + return; + } - printf("Starting manual connect...\n"); - - printf(" Disabling auto-connect policy...\n"); - rval = wlan_ioctl_set_connection_policy(DISABLE, DISABLE, DISABLE); + printf("Starting manual connect...\n"); - printf(" Deleting all existing profiles...\n"); - rval = wlan_ioctl_del_profile(255); + printf(" Disabling auto-connect policy...\n"); + rval = wlan_ioctl_set_connection_policy(DISABLE, DISABLE, DISABLE); - printf(" Waiting until disconnected...\n"); - while (ulCC3000Connected == 1) - { - usleep(100000); //delay 100ms in busy wait - } - - printf(" Manually connecting...\n"); + printf(" Deleting all existing profiles...\n"); + rval = wlan_ioctl_del_profile(255); - // Parameter 1 is the security type: WLAN_SEC_UNSEC, WLAN_SEC_WEP, - // WLAN_SEC_WPA or WLAN_SEC_WPA2 - // Parameter 3 is the MAC adddress of the AP. All the TI examples - // use NULL. I suppose you would want to specify this - // if you were security paranoid. - rval = wlan_connect(WLAN_SEC_WPA2, - ssidName, - strlen(ssidName), - NULL, - (uint8_t *)AP_KEY, - strlen(AP_KEY)); + printf(" Waiting until disconnected...\n"); + while (ulCC3000Connected == 1) + { + usleep(100000); //delay 100ms in busy wait + } - if (rval==0) { - printf(" Manual connect success.\n"); - } - else { - printf(" Unusual return value: %d\n", rval); - } + printf(" Manually connecting...\n"); + + // Parameter 1 is the security type: WLAN_SEC_UNSEC, WLAN_SEC_WEP, + // WLAN_SEC_WPA or WLAN_SEC_WPA2 + // Parameter 3 is the MAC adddress of the AP. All the TI examples + // use NULL. I suppose you would want to specify this + // if you were security paranoid. + rval = wlan_connect(WLAN_SEC_WPA2, + ssidName, + strlen(ssidName), + NULL, + (uint8_t *)AP_KEY, + strlen(AP_KEY)); + + if (rval==0) { + printf(" Manual connect success.\n"); + } + else { + printf(" Unusual return value: %d\n", rval); + } } /* - This is an example of manually adding a WLAN profile to the CC3000. See - wlan_ioctl_set_connection_policy() for more details of how profiles are - used but basically there's 7 slots where you can store AP info and if - the connection policy is set to auto_start then the CC3000 will go - through its profile table and try to auto-connect to something it knows - about after it boots up. - - Note the API documentation for wlan_add_profile is wrong. It says it - returns 0 on success and -1 on failure. What it really returns is - the stored profile number (0-6, since the CC3000 can store 7) or - 255 on failure. - - Unfortunately the API doesn't give you any way to see how many profiles - are in use or which profile is stored in which slot, so if you want to - manage multiple profiles you'll need to do that yourself. + This is an example of manually adding a WLAN profile to the CC3000. See + wlan_ioctl_set_connection_policy() for more details of how profiles are + used but basically there's 7 slots where you can store AP info and if + the connection policy is set to auto_start then the CC3000 will go + through its profile table and try to auto-connect to something it knows + about after it boots up. + + Note the API documentation for wlan_add_profile is wrong. It says it + returns 0 on success and -1 on failure. What it really returns is + the stored profile number (0-6, since the CC3000 can store 7) or + 255 on failure. + + Unfortunately the API doesn't give you any way to see how many profiles + are in use or which profile is stored in which slot, so if you want to + manage multiple profiles you'll need to do that yourself. */ void ManualAddProfile(void) { - char ssidName[] = "YourAP"; - char AP_KEY[] = "yourpass"; - uint8_t rval; + char ssidName[] = "YourAP"; + char AP_KEY[] = "yourpass"; + uint8_t rval; - if (!isInitialized) - { - printf("CC3000 not initialized; can't run manual add profile."); - return; - } + if (!isInitialized) + { + printf("CC3000 not initialized; can't run manual add profile."); + return; + } - printf("Starting manual add profile...\n"); + printf("Starting manual add profile...\n"); - printf(" Disabling auto connection...\n"); - wlan_ioctl_set_connection_policy(DISABLE, DISABLE, DISABLE); + printf(" Disabling auto connection...\n"); + wlan_ioctl_set_connection_policy(DISABLE, DISABLE, DISABLE); - printf(" Adding profile...\n"); - rval = wlan_add_profile ( - WLAN_SEC_WPA2, // WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2 - (uint8_t *)ssidName, - strlen(ssidName), - NULL, // BSSID, TI always uses NULL - 0, // profile priority - 0x18, // key length for WEP security, undocumented why this needs to be 0x18 - 0x1e, // key index, undocumented why this needs to be 0x1e - 0x2, // key management, undocumented why this needs to be 2 - (uint8_t *)AP_KEY, // WPA security key - strlen(AP_KEY) // WPA security key length - ); + printf(" Adding profile...\n"); + rval = wlan_add_profile ( + WLAN_SEC_WPA2, // WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2 + (uint8_t *)ssidName, + strlen(ssidName), + NULL, // BSSID, TI always uses NULL + 0, // profile priority + 0x18, // key length for WEP security, undocumented why this needs to be 0x18 + 0x1e, // key index, undocumented why this needs to be 0x1e + 0x2, // key management, undocumented why this needs to be 2 + (uint8_t *)AP_KEY, // WPA security key + strlen(AP_KEY) // WPA security key length + ); - if (rval!=255) { + if (rval!=255) { - // This code is lifted from http://e2e.ti.com/support/low_power_rf/f/851/p/180859/672551.aspx; - // the actual API documentation on wlan_add_profile doesn't specify any of this.... + // This code is lifted from http://e2e.ti.com/support/low_power_rf/f/851/p/180859/672551.aspx; + // the actual API documentation on wlan_add_profile doesn't specify any of this.... - printf(" Manual add profile success, stored in profile: %d\n", rval); + printf(" Manual add profile success, stored in profile: %d\n", rval); - printf(" Enabling auto connection...\n"); - wlan_ioctl_set_connection_policy(DISABLE, DISABLE, ENABLE); + printf(" Enabling auto connection...\n"); + wlan_ioctl_set_connection_policy(DISABLE, DISABLE, ENABLE); - printf(" Stopping CC3000...\n"); - wlan_stop(); + printf(" Stopping CC3000...\n"); + wlan_stop(); - printf(" Stopping for 5 seconds...\n"); - usleep(5000000); + printf(" Stopping for 5 seconds...\n"); + usleep(5000000); - printf(" Restarting CC3000...\n"); - wlan_start(0); - - printf(" Manual add profile done!"); + printf(" Restarting CC3000...\n"); + wlan_start(0); - } - else { - printf(" Manual add profile failured (all profiles full?)."); - } + printf(" Manual add profile done!"); + + } + else { + printf(" Manual add profile failured (all profiles full?)."); + } } /* - The call wlan_ioctl_get_scan_results returns this structure. I couldn't - find it in the TI library so it's defined here. It's 50 bytes with - a semi weird arrangement but fortunately it's not as bad as it looks. - - numNetworksFound - 4 bytes - On the first call to wlan_ioctl_get_scan_results - this will be set to how many APs the CC3000 sees. Although - with 4 bytes the CC3000 could see 4 billion APs in my testing - this number was always 20 or less so there's probably an - internal memory limit. - - results - 4 bytes - 0=aged results, 1=results valid, 2=no results. Why TI - used 32 bits to store something that could be done in 2, - and how this field is different than isValid below, is - a mystery to me so I just igore this field completely. - - isValid & rssi - 1 byte - a packed structure. The top bit (isValid) - indicates whether or not this structure has valid data, - the bottom 7 bits (rssi) are the signal strength of this AP. - - securityMode & ssidLength - 1 byte - another packed structure. The top 2 - bits (securityMode) show how the AP is configured: - 0 - open / no security - 1 - WEP - 2 - WPA - 3 - WPA2 - ssidLength is the lower 6 bytes and shows how many characters - (up to 32) of the ssid_name field are valid - - frameTime - 2 bytes - how long, in seconds, since the CC3000 saw this AP - beacon - - ssid_name - 32 bytes - The ssid name for this AP. Note that this isn't a - regular null-terminated C string so you can't use it - directly with a strcpy() or Serial.println() etc. and you'll - need a 33-byte string to store it (32 valid characters + - null terminator) - - bssid - 6 bytes - the MAC address of this AP -*/ - -typedef struct scanResults { - unsigned long numNetworksFound; - unsigned long results; - unsigned isValid:1; - unsigned rssi:7; - unsigned securityMode:2; - unsigned ssidLength:6; - uint16_t frameTime; - uint8_t ssid_name[32]; - uint8_t bssid[6]; - } scanResults; + The call wlan_ioctl_get_scan_results returns this structure. I couldn't + find it in the TI library so it's defined here. It's 50 bytes with + a semi weird arrangement but fortunately it's not as bad as it looks. -#define NUM_CHANNELS 16 + numNetworksFound - 4 bytes - On the first call to wlan_ioctl_get_scan_results + this will be set to how many APs the CC3000 sees. Although + with 4 bytes the CC3000 could see 4 billion APs in my testing + this number was always 20 or less so there's probably an + internal memory limit. + + results - 4 bytes - 0=aged results, 1=results valid, 2=no results. Why TI + used 32 bits to store something that could be done in 2, + and how this field is different than isValid below, is + a mystery to me so I just igore this field completely. + + isValid & rssi - 1 byte - a packed structure. The top bit (isValid) + indicates whether or not this structure has valid data, + the bottom 7 bits (rssi) are the signal strength of this AP. + + securityMode & ssidLength - 1 byte - another packed structure. The top 2 + bits (securityMode) show how the AP is configured: + 0 - open / no security + 1 - WEP + 2 - WPA + 3 - WPA2 + ssidLength is the lower 6 bytes and shows how many characters + (up to 32) of the ssid_name field are valid + + frameTime - 2 bytes - how long, in seconds, since the CC3000 saw this AP + beacon + + ssid_name - 32 bytes - The ssid name for this AP. Note that this isn't a + regular null-terminated C string so you can't use it + directly with a strcpy() or Serial.println() etc. and you'll + need a 33-byte string to store it (32 valid characters + + null terminator) + + bssid - 6 bytes - the MAC address of this AP +*/ + +typedef struct scanResults { + unsigned long numNetworksFound; + unsigned long results; + unsigned isValid:1; + unsigned rssi:7; + unsigned securityMode:2; + unsigned ssidLength:6; + uint16_t frameTime; + uint8_t ssid_name[32]; + uint8_t bssid[6]; + } scanResults; + +#define NUM_CHANNELS 16 void ListAccessPoints(void) { - unsigned long aiIntervalList[NUM_CHANNELS]; - uint8_t rval; - scanResults sr; - int apCounter, i; - char localB[33]; - - if (!isInitialized) { - printf("CC3000 not initialized; can't list access points.\n"); - return; - } - - printf("List visible access points\n"); - - printf(" Setting scan paramters...\n"); - - for (i=0; i0) { - if ((rval=wlan_ioctl_get_scan_results(2000, (uint8_t *)&sr))!=0) { - printf(" Got back unusual result from wlan_ioctl_get scan, can't continue: %d\n", rval); - return; - } - } - } while (apCounter>0); - - printf(" Access Point list finished.\n"); + unsigned long aiIntervalList[NUM_CHANNELS]; + uint8_t rval; + scanResults sr; + int apCounter, i; + char localB[33]; + + if (!isInitialized) { + printf("CC3000 not initialized; can't list access points.\n"); + return; + } + + printf("List visible access points\n"); + + printf(" Setting scan paramters...\n"); + + for (i=0; i0) { + if ((rval=wlan_ioctl_get_scan_results(2000, (uint8_t *)&sr))!=0) { + printf(" Got back unusual result from wlan_ioctl_get scan, can't continue: %d\n", rval); + return; + } + } + } while (apCounter>0); + + printf(" Access Point list finished.\n"); } void PrintIPBytes(uint8_t *ipBytes) { - printf("%d.%d.%d.%d\n", ipBytes[3], ipBytes[2], ipBytes[1], ipBytes[0]); + printf("%d.%d.%d.%d\n", ipBytes[3], ipBytes[2], ipBytes[1], ipBytes[0]); } /* - All the data in all the fields from netapp_ipconfig() are reversed, - e.g. an IP address is read via bytes 3,2,1,0 instead of bytes - 0,1,2,3 and the MAC address is read via bytes 5,4,3,2,1,0 instead - of 0,1,2,3,4,5. - - N.B. TI is inconsistent here; nvmem_get_mac_address() returns them in - the right order etc. + All the data in all the fields from netapp_ipconfig() are reversed, + e.g. an IP address is read via bytes 3,2,1,0 instead of bytes + 0,1,2,3 and the MAC address is read via bytes 5,4,3,2,1,0 instead + of 0,1,2,3,4,5. + + N.B. TI is inconsistent here; nvmem_get_mac_address() returns them in + the right order etc. */ void ShowInformation(void) { - tNetappIpconfigRetArgs inf; - char localB[33]; - int i; + tNetappIpconfigRetArgs inf; + char localB[33]; + int i; - if (!isInitialized) { - printf("CC3000 not initialized; can't get information.\n"); - return; - } - - printf("CC3000 information:\n"); - - netapp_ipconfig(&inf); - - printf(" IP address: "); - PrintIPBytes(inf.aucIP); - - printf(" Subnet mask: "); - PrintIPBytes(inf.aucSubnetMask); - - printf(" Gateway: "); - PrintIPBytes(inf.aucDefaultGateway); - - printf(" DHCP server: "); - PrintIPBytes(inf.aucDHCPServer); - - printf(" DNS server: "); - PrintIPBytes(inf.aucDNSServer); - - printf(" MAC address: "); - for (i=(MAC_ADDR_LEN-1); i>=0; i--) { - if (i!=(MAC_ADDR_LEN-1)) { - printf(":"); - } - printf("%X", inf.uaMacAddr[i]); - } - printf("\n"); - - memset(localB, 0, 32); - memcpy(localB, inf.uaSSID, 32); + if (!isInitialized) { + printf("CC3000 not initialized; can't get information.\n"); + return; + } - printf(" Connected to SSID: %d\n", localB); + printf("CC3000 information:\n"); + + netapp_ipconfig(&inf); + + printf(" IP address: "); + PrintIPBytes(inf.aucIP); + + printf(" Subnet mask: "); + PrintIPBytes(inf.aucSubnetMask); + + printf(" Gateway: "); + PrintIPBytes(inf.aucDefaultGateway); + + printf(" DHCP server: "); + PrintIPBytes(inf.aucDHCPServer); + + printf(" DNS server: "); + PrintIPBytes(inf.aucDNSServer); + + printf(" MAC address: "); + for (i=(MAC_ADDR_LEN-1); i>=0; i--) { + if (i!=(MAC_ADDR_LEN-1)) { + printf(":"); + } + printf("%X", inf.uaMacAddr[i]); + } + printf("\n"); + + memset(localB, 0, 32); + memcpy(localB, inf.uaSSID, 32); + + printf(" Connected to SSID: %d\n", localB); } int c3b_main(int argc, char *argv[]) { - char ch='0'; + char ch='0'; - while(ch != 'q' && ch != 'Q') - { - helpme(); + while(ch != 'q' && ch != 'Q') + { + helpme(); - ch = getchar(); + ch = getchar(); - execute(ch); - } + execute(ch); + } - return 0; + return 0; }