A Port of TI's Webserver for the CC3000

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cc3000.cpp Source File

cc3000.cpp

00001 /*****************************************************************************
00002 *
00003 *  cc3000.c - CC3000 Functions Implementation
00004 *  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
00005 *
00006 *  Redistribution and use in source and binary forms, with or without
00007 *  modification, are permitted provided that the following conditions
00008 *  are met:
00009 *
00010 *    Redistributions of source code must retain the above copyright
00011 *    notice, this list of conditions and the following disclaimer.
00012 *
00013 *    Redistributions in binary form must reproduce the above copyright
00014 *    notice, this list of conditions and the following disclaimer in the
00015 *    documentation and/or other materials provided with the   
00016 *    distribution.
00017 *
00018 *    Neither the name of Texas Instruments Incorporated nor the names of
00019 *    its contributors may be used to endorse or promote products derived
00020 *    from this software without specific prior written permission.
00021 *
00022 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
00023 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
00024 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00025 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
00026 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
00027 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
00028 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00029 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00030 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
00031 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
00032 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 *
00034 *****************************************************************************/
00035 
00036 #include "mbed.h"
00037 #include "cc3000.h"
00038 //#include <msp430.h>
00039 #include "wlan.h" 
00040 #include "evnt_handler.h"    // callback function declaration
00041 #include "nvmem.h"
00042 #include "socket.h"
00043 #include "Common.h"
00044 #include "netapp.h"
00045 //#include "common.h"
00046 #include "demo_config.h"
00047 #include "spi.h"
00048 #include "Board.h"
00049 #include "dispatcher.h"
00050 #include "spi_version.h"
00051 #include "application_version.h"
00052 #include "host_driver_version.h"
00053 #include "security.h"
00054 
00055 #define PALTFORM_VERSION                        (6)
00056 
00057 
00058 // Variable to indicate whether the Smart Config Process has finished
00059 volatile unsigned long ulSmartConfigFinished = 0;
00060 
00061 unsigned char pucIP_Addr[4];
00062 unsigned char pucIP_DefaultGWAddr[4];
00063 unsigned char pucSubnetMask[4];
00064 unsigned char pucDNS[4];
00065 
00066 tNetappIpconfigRetArgs ipinfo;
00067 
00068 // Smart Config Prefix - Texas Instruments
00069 char aucCC3000_prefix[3] = {'T', 'T', 'T'};
00070 extern char digits[];
00071 
00072 const unsigned char smartconfigkey[] = {0x73,0x6d,0x61,0x72,0x74,0x63,0x6f,0x6e,0x66,0x69,0x67,0x41,0x45,0x53,0x31,0x36};
00073 
00074 const unsigned char pucUARTExampleAppString[] = {'\f', '\r','E', 'x', 'a', 'm', 'p', 'l', 'e', ' ', 'A', 'p', 'p', ':', 'd', 'r', 'i', 'v', 'e', 'r', ' ', 'v', 'e', 'r', 's', 'i', 'o', 'n', ' ' };
00075 
00076 char cc3000state = CC3000_UNINIT;
00077 
00078 extern unsigned char ConnectUsingSmartConfig; 
00079 extern volatile unsigned long ulCC3000Connected;
00080 char CheckSocket = 0;
00081 signed char sd[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0};
00082 
00083 //*****************************************************************************
00084 //
00085 //! ConnectUsingSSID
00086 //!
00087 //! \param  ssidName is a string of the AP's SSID
00088 //!
00089 //! \return none
00090 //!
00091 //! \brief  Connect to an Access Point using the specified SSID
00092 //
00093 //*****************************************************************************
00094 int ConnectUsingSSID(char * ssidName)
00095 {
00096                     
00097     unsetCC3000MachineState(CC3000_ASSOC);
00098     
00099     // Disable Profiles and Fast Connect
00100     wlan_ioctl_set_connection_policy(0, 0, 0);
00101     
00102     wlan_disconnect();
00103     wait_us(500);
00104     //__delay_cycles(10000);
00105     
00106     // This triggers the CC3000 to connect to specific AP with certain parameters
00107     //sends a request to connect (does not necessarily connect - callback checks that for me)
00108 #ifndef CC3000_TINY_DRIVER
00109     wlan_connect(0, ssidName, strlen(ssidName), NULL, NULL, 0);   
00110 #else
00111     wlan_connect(ssidName, strlen(ssidName));
00112 #endif
00113     // We don't wait for connection. This is handled somewhere else (in the main
00114     // loop for example).
00115     
00116     return 0;      
00117 }
00118 
00119 
00120 //*****************************************************************************
00121 //
00122 //! itoa
00123 //!
00124 //! @param[in]  integer number to convert
00125 //!
00126 //! @param[in/out]  output string
00127 //!
00128 //! @return number of ASCII parameters
00129 //!
00130 //! @brief  Convert integer to ASCII in decimal base
00131 //
00132 //*****************************************************************************
00133 unsigned short itoa(char cNum, char *cString)
00134 {
00135     char* ptr;
00136     char uTemp = cNum;
00137     unsigned short length;
00138     
00139     // value 0 is a special case
00140     if (cNum == 0)
00141     {
00142         length = 1;
00143         *cString = '0';
00144         
00145         return length;
00146     }
00147     
00148     // Find out the length of the number, in decimal base
00149     length = 0;
00150     while (uTemp > 0)
00151     {
00152         uTemp /= 10;
00153         length++;
00154     }
00155     
00156     // Do the actual formatting, right to left
00157     uTemp = cNum;
00158     ptr = cString + length;
00159     while (uTemp > 0)
00160     {
00161         --ptr;
00162         *ptr = digits[uTemp % 10];
00163         uTemp /= 10;
00164     }
00165     
00166     return length;
00167 }
00168 
00169 
00170 //*****************************************************************************
00171 //
00172 //! sendDriverPatch
00173 //!
00174 //! \param  pointer to the length
00175 //!
00176 //! \return none
00177 //!
00178 //! \brief  The function returns a pointer to the driver patch: since there is no patch yet - 
00179 //!             it returns 0
00180 //
00181 //*****************************************************************************
00182 char *sendDriverPatch(unsigned long *Length)
00183 {
00184     *Length = 0;
00185     return NULL;
00186 }
00187 
00188 
00189 //*****************************************************************************
00190 //
00191 //! sendBootLoaderPatch
00192 //!
00193 //! \param  pointer to the length
00194 //!
00195 //! \return none
00196 //!
00197 //! \brief  The function returns a pointer to the boot loader patch: since there is no patch yet -
00198 //!             it returns 0
00199 //
00200 //*****************************************************************************
00201 char *sendBootLoaderPatch(unsigned long *Length)
00202 {
00203     *Length = 0;
00204     return NULL;
00205 }
00206 
00207 //*****************************************************************************
00208 //
00209 //! sendWLFWPatch
00210 //!
00211 //! \param  pointer to the length
00212 //!
00213 //! \return none
00214 //!
00215 //! \brief  The function returns a pointer to the FW patch: since there is no patch yet - it returns 0
00216 //
00217 //*****************************************************************************
00218 
00219 char *sendWLFWPatch(unsigned long *Length)
00220 {
00221     *Length = 0;
00222     return NULL;
00223 }
00224 
00225 
00226 //*****************************************************************************
00227 //
00228 //! CC3000_UsynchCallback
00229 //!
00230 //! \param  Event type
00231 //!
00232 //! \return none
00233 //!
00234 //! \brief  The function handles asynchronous events that come from CC3000 device 
00235 //!       and operates a LED4 to have an on-board indication
00236 //
00237 //*****************************************************************************
00238 
00239 void CC3000_UsynchCallback(long lEventType, char * data, unsigned char length)
00240 {
00241     if (lEventType == HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE)
00242     {
00243         ulSmartConfigFinished = 1;      
00244     }
00245     
00246     if (lEventType == HCI_EVNT_WLAN_UNSOL_INIT)
00247     {
00248         setCC3000MachineState(CC3000_INIT);
00249     }
00250     if (lEventType == HCI_EVNT_WLAN_UNSOL_CONNECT)
00251     {
00252               ulCC3000Connected = 1;
00253         setCC3000MachineState(CC3000_ASSOC);
00254         
00255     }
00256     
00257     if (lEventType == HCI_EVNT_WLAN_UNSOL_DISCONNECT)
00258     {
00259         ulCC3000Connected = 0;
00260         //restartMSP430();
00261         unsetCC3000MachineState(CC3000_ASSOC);
00262         
00263     }
00264     if (lEventType == HCI_EVNT_WLAN_UNSOL_DHCP)
00265     {
00266         setCC3000MachineState(CC3000_IP_ALLOC);        
00267     }
00268     
00269     // This Event is gengerated when the TCP connection is Half closed
00270     if (lEventType == HCI_EVNT_BSD_TCP_CLOSE_WAIT)
00271     {
00272       sd[data[0]] = 1;
00273       CheckSocket = 1;
00274     }
00275     
00276     //if (lEventType == HCI_EVENT_CC3000_CAN_SHUT_DOWN){
00277             //OkToDoShutDown = 1;
00278     //        printf("CC3000 Usync event: OK to shut down\r\n");
00279     //        }
00280 }
00281 
00282 //*****************************************************************************
00283 //
00284 //! initDriver
00285 //!
00286 //!  \param  None
00287 //!
00288 //!  \return none
00289 //!
00290 //!  \brief  The function initializes a CC3000 device and triggers it to start operation
00291 //
00292 //*****************************************************************************
00293 int
00294   initDriver(void)
00295 {
00296         // Init GPIO's
00297     //pio_init();
00298     
00299     // Init SPI
00300     init_spi();
00301         
00302     DispatcherUARTConfigure();
00303         
00304     // Globally enable interrupts
00305     //__enable_interrupt();
00306         
00307     //
00308     // WLAN On API Implementation
00309     //
00310     wlan_init( CC3000_UsynchCallback, sendWLFWPatch, sendDriverPatch, sendBootLoaderPatch, ReadWlanInterruptPin, WlanInterruptEnable, WlanInterruptDisable, WriteWlanPin);
00311     
00312     //
00313     // Trigger a WLAN device
00314     //
00315     wlan_start(0);
00316     
00317     //
00318     // Mask out all non-required events from CC3000
00319     //
00320 
00321     wlan_set_event_mask(HCI_EVNT_WLAN_KEEPALIVE|HCI_EVNT_WLAN_ASYNC_PING_REPORT|HCI_EVNT_WLAN_UNSOL_INIT);
00322 
00323     // Generate event to CLI: send a version string
00324     char cc3000IP[50];
00325     char *ccPtr;
00326     unsigned short ccLen;
00327         
00328     DispatcherUartSendPacket((const char*)pucUARTExampleAppString, sizeof(pucUARTExampleAppString));
00329         
00330     ccPtr = &cc3000IP[0];
00331     ccLen = itoa(PALTFORM_VERSION, ccPtr);
00332     ccPtr += ccLen;
00333     *ccPtr++ = '.';
00334     ccLen = itoa(APPLICATION_VERSION, ccPtr);
00335     ccPtr += ccLen;
00336     *ccPtr++ = '.';
00337     ccLen = itoa(SPI_VERSION_NUMBER, ccPtr);
00338     ccPtr += ccLen;
00339     *ccPtr++ = '.';
00340     ccLen = itoa(DRIVER_VERSION_NUMBER, ccPtr);
00341     ccPtr += ccLen;
00342     *ccPtr++ = '\r';
00343         *ccPtr++ = '\n';
00344     *ccPtr++ = '\0';
00345         ccLen = strlen(cc3000IP);
00346         
00347     DispatcherUartSendPacket((const char*)cc3000IP, strlen(cc3000IP));
00348     
00349     // CC3000 has been initialized
00350     setCC3000MachineState(CC3000_INIT);
00351     
00352     unsigned long aucDHCP, aucARP, aucKeepalive, aucInactivity;
00353     
00354     aucDHCP = 14400;
00355     aucARP = 3600;      
00356     aucKeepalive = 10;
00357     aucInactivity = 100;
00358     
00359     if(netapp_timeout_values(&(aucDHCP), &(aucARP), &(aucKeepalive), &(aucInactivity)) != 0)
00360     {
00361       while(1);
00362     }
00363     
00364     return(0);
00365 }
00366 
00367 
00368 //*****************************************************************************
00369 //
00370 //!  \brief  Return the highest state which we're in
00371 //!
00372 //!  \param  None
00373 //!
00374 //!  \return none
00375 //!
00376 //
00377 //*****************************************************************************
00378 char highestCC3000State()
00379 {
00380     // We start at the highest state and go down, checking if the state
00381     // is set.
00382     char mask = 0x80;
00383     while(!(cc3000state & mask))
00384     {
00385         mask = mask >> 1;
00386     }
00387         
00388     return mask;
00389 }
00390 
00391 //*****************************************************************************
00392 //
00393 //!  \brief  Return the current state bits
00394 //!
00395 //!  \param  None
00396 //!
00397 //!  \return none
00398 //!
00399 //
00400 //*****************************************************************************
00401 char currentCC3000State()
00402 {
00403     return cc3000state;
00404 }
00405 
00406 void setCC3000MachineState(char stat)
00407 {       
00408     char bitmask = stat;
00409     cc3000state |= bitmask;
00410     
00411     int i = FIRST_STATE_LED_NUM;
00412     
00413     // Find LED number which needs to be set
00414     while(bitmask < 0x80)
00415     {      
00416         bitmask  = bitmask << 1;
00417         i++;
00418     }    
00419     turnLedOn(NUM_STATES-i+2);
00420 
00421 }
00422 
00423 
00424 //*****************************************************************************
00425 //
00426 //!  \brief  Unsets a state from the state machine
00427 //!  Also handles LEDs
00428 //!  
00429 //!  \param  None
00430 //!
00431 //!  \return none
00432 //!  
00433 //
00434 //*****************************************************************************
00435 void unsetCC3000MachineState(char stat)
00436 {
00437     char bitmask = stat;
00438     cc3000state &= ~bitmask;
00439     
00440     int i = FIRST_STATE_LED_NUM;
00441     int k = NUM_STATES; // Set to last element in state list
00442     
00443     // Set all upper bits to 0 as well since state machine cannot have
00444     // those states.
00445     while(bitmask < 0x80)
00446     {
00447         cc3000state &= ~bitmask;
00448         bitmask = bitmask << 1;
00449         i++;
00450     }
00451     
00452     // Turn off all upper state LEDs
00453     for(; i > FIRST_STATE_LED_NUM; i--)
00454     {
00455         turnLedOff(k);
00456         k--;
00457     }    
00458 }
00459 
00460 //*****************************************************************************
00461 //
00462 //!  \brief  Resets the State Machine
00463 //!  
00464 //!  \param  None
00465 //!
00466 //!  \return none
00467 //!  
00468 //
00469 //*****************************************************************************
00470 void resetCC3000StateMachine()
00471 {
00472     cc3000state = CC3000_UNINIT;
00473 
00474     // Turn off all Board LEDs
00475 
00476     turnLedOff(CC3000_ON_IND);
00477     turnLedOff(CC3000_ASSOCIATED_IND);
00478     turnLedOff(CC3000_IP_ALLOC_IND);
00479     turnLedOff(CC3000_SERVER_INIT_IND);
00480     turnLedOff(CC3000_CLIENT_CONNECTED_IND);
00481     turnLedOff(CC3000_SENDING_DATA_IND);
00482     turnLedOff(CC3000_UNUSED1_IND);
00483     turnLedOff(CC3000_FTC_IND);
00484 }
00485 
00486 //*****************************************************************************
00487 //
00488 //!  \brief  Obtains the CC3000 Connection Information from the CC3000
00489 //!  
00490 //!  \param  None
00491 //!
00492 //!  \return none
00493 //!  
00494 //
00495 //*****************************************************************************
00496 #ifndef CC3000_TINY_DRIVER
00497 tNetappIpconfigRetArgs * getCC3000Info()
00498 {
00499     netapp_ipconfig(&ipinfo);
00500     return (&ipinfo);
00501 }
00502 #endif
00503 
00504 //*****************************************************************************
00505 //
00506 //! StartSmartConfig
00507 //!
00508 //!  \param  None
00509 //!
00510 //!  \return none
00511 //!
00512 //!  \brief  The function triggers a smart configuration process on CC3000.
00513 //!         it exists upon completion of the process
00514 //
00515 //*****************************************************************************
00516 
00517 void StartSmartConfig(void)
00518 {
00519 
00520     // Reset all the previous configuration
00521     //
00522     wlan_ioctl_set_connection_policy(0, 0, 0);  
00523         wlan_ioctl_del_profile(255);
00524     
00525     //Wait until CC3000 is dissconected
00526     while (ulCC3000Connected == 1)
00527     {
00528       wait_us(5);
00529       //__delay_cycles(100);
00530     }
00531 
00532     // Start blinking LED6 during Smart Configuration process
00533     turnLedOn(LED6);
00534     wlan_smart_config_set_prefix(aucCC3000_prefix);
00535     //wlan_first_time_config_set_prefix(aucCC3000_prefix);
00536     turnLedOff(ind4);
00537     
00538     // Start the SmartConfig start process
00539     wlan_smart_config_start(1);
00540     turnLedOn(ind4);
00541     
00542     //
00543     // Wait for Smart config finished
00544     // 
00545     while (ulSmartConfigFinished == 0)
00546     {
00547         //__delay_cycles(6000000);
00548         wait_ms(250);                                                                     
00549         turnLedOn(ind4);
00550 
00551         //__delay_cycles(6000000);
00552         wait_ms(250);        
00553         turnLedOff(ind4);
00554     }
00555 
00556     turnLedOff(ind4);
00557 
00558     // create new entry for AES encryption key
00559     nvmem_create_entry(NVMEM_AES128_KEY_FILEID,16);
00560     
00561     // write AES key to NVMEM
00562     aes_write_key((unsigned char *)(&smartconfigkey[0]));
00563     
00564     // Decrypt configuration information and add profile
00565     wlan_smart_config_process();
00566         
00567     //
00568     // Configure to connect automatically to the AP retrieved in the 
00569     // Smart config process
00570     //
00571     wlan_ioctl_set_connection_policy(0, 0, 1);
00572     
00573     //
00574     // reset the CC3000
00575     // 
00576     wlan_stop();
00577     wait_ms(250);
00578     //__delay_cycles(600000);
00579     wlan_start(0);
00580 
00581     ConnectUsingSmartConfig = 1; 
00582         ulSmartConfigFinished = 0;
00583     //
00584     // Mask out all non-required events
00585     //
00586     wlan_set_event_mask(HCI_EVNT_WLAN_KEEPALIVE|HCI_EVNT_WLAN_UNSOL_INIT|HCI_EVNT_WLAN_ASYNC_PING_REPORT);
00587 }
00588