├── library.json ├── library.properties ├── README.md ├── .github ├── PULL_REQUEST_TEMPLATE.md └── ISSUE_TEMPLATE.md ├── license.txt ├── utility ├── debug.h ├── host_driver_version.h ├── debug.cpp ├── data_types.h ├── security.h ├── error_codes.h ├── evnt_handler.h ├── cc3000_common.cpp ├── hci.cpp └── nvmem.h ├── ccspi.h ├── Adafruit_CC3000_Server.h ├── examples ├── SmartConfigReconnect │ └── SmartConfigReconnect.ino ├── ChatServer │ └── ChatServer.ino ├── EchoServer │ └── EchoServer.ino ├── WebClient │ └── WebClient.ino ├── SmartConfigCreate │ └── SmartConfigCreate.ino ├── ntpTest │ └── ntpTest.ino ├── InternetTime │ └── InternetTime.ino ├── HTTPServer │ └── HTTPServer.ino ├── buildtest │ └── buildtest.ino ├── driverpatch_1_12 │ └── driverpatch_1_12.ino ├── driverpatch_1_14 │ └── driverpatch_1_14.ino ├── driverpatch_1_11 │ └── driverpatch_1_11.ino ├── driverpatch_1_13 │ └── driverpatch_1_13.ino └── GeoLocation │ └── GeoLocation.ino ├── Adafruit_CC3000.h └── Adafruit_CC3000_Server.cpp /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Adafruit-CC3000", 3 | "keywords": "wifi, wi-fi, http, web, server, json, rest, spi", 4 | "description": "Library code for Adafruit's CC3000 Wi-Fi/WiFi breakouts", 5 | "repository": 6 | { 7 | "type": "git", 8 | "url": "https://github.com/adafruit/Adafruit_CC3000_Library.git" 9 | }, 10 | "frameworks": "arduino", 11 | "platforms": "atmelavr" 12 | } 13 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=Adafruit CC3000 Library 2 | version=1.0.4 3 | author=Adafruit 4 | maintainer=Adafruit 5 | sentence=Library code for Adafruit's CC3000 WiFi breakouts. 6 | paragraph=The CC3000 allows an Arduino to connect to a WiFi network and access the internet. See more at: https://learn.adafruit.com/adafruit-cc3000-wifi/ 7 | category=Communication 8 | url=https://github.com/adafruit/Adafruit_CC3000_Library 9 | architectures=* 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Adafruit CC3000 Library 2 | 3 | This is a library for the Adafruit CC3000 WiFi Breakouts etc 4 | 5 | Designed specifically to work with the Adafruit CC3000 Breakout 6 | ----> https://www.adafruit.com/products/1469 7 | 8 | These modules use SPI to communicate, 6 pins are required to interface 9 | 10 | Adafruit invests time and resources providing this open source code, 11 | please support Adafruit and open-source hardware by purchasing 12 | products from Adafruit! 13 | 14 | Check out the links above for our tutorials and wiring diagrams 15 | 16 | Arduino library Written by Limor Fried & Kevin Townsend for Adafruit Industries. 17 | CC3000 host core written by TI 18 | 19 | To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder Adafruit_CC3000 20 | Check that the Adafruit_CC3000 folder contains Adafruit_CC3000.cpp and Adafruit_CC3000.h 21 | 22 | Place the Adafruit_CC3000 library folder your *arduinosketchfolder*/libraries/ folder. 23 | You may need to create the libraries subfolder if its your first library. Restart the IDE. 24 | 25 | NOTE: the 'SendTweet' example currently DOES NOT WORK due to Twitter API changes. The code is being kept for posterity in case a workaround can be developed. 26 | 27 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for creating a pull request to contribute to Adafruit's GitHub code! 2 | Before you open the request please review the following guidelines and tips to 3 | help it be more easily integrated: 4 | 5 | - **Describe the scope of your change--i.e. what the change does and what parts 6 | of the code were modified.** This will help us understand any risks of integrating 7 | the code. 8 | 9 | - **Describe any known limitations with your change.** For example if the change 10 | doesn't apply to a supported platform of the library please mention it. 11 | 12 | - **Please run any tests or examples that can exercise your modified code.** We 13 | strive to not break users of the code and running tests/examples helps with this 14 | process. 15 | 16 | Thank you again for contributing! We will try to test and integrate the change 17 | as soon as we can, but be aware we have many GitHub repositories to manage and 18 | can't immediately respond to every request. There is no need to bump or check in 19 | on a pull request (it will clutter the discussion of the request). 20 | 21 | Also don't be worried if the request is closed or not integrated--sometimes the 22 | priorities of Adafruit's GitHub code (education, ease of use) might not match the 23 | priorities of the pull request. Don't fret, the open source community thrives on 24 | forks and GitHub makes it easy to keep your changes in a forked repo. 25 | 26 | After reviewing the guidelines above you can delete this text from the pull request. 27 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | ===== 2 | 3 | Copyright (c) 2013-2014 4 | Limor Fried, Kevin Townsend for Adafruit Industries & Tony DiCola (tony@tonydicola.com) 5 | 6 | Adafruit invests time and resources providing this open source code, 7 | please support Adafruit and open-source hardware by purchasing 8 | products from Adafruit! 9 | 10 | All rights reserved. 11 | 12 | ===== 13 | 14 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 15 | 16 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 17 | 18 | 2. 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. 19 | 20 | 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 HOLDER 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. -------------------------------------------------------------------------------- /utility/debug.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************/ 2 | /*! 3 | @file Adafruit_CC3000.cpp 4 | @author KTOWN (Kevin Townsend for Adafruit Industries) 5 | @license BSD (see license.txt) 6 | 7 | This is a library for the Adafruit CC3000 WiFi breakout board 8 | This library works with the Adafruit CC3000 breakout 9 | ----> https://www.adafruit.com/products/1469 10 | 11 | Check out the links above for our tutorials and wiring diagrams 12 | These chips use SPI to communicate. 13 | 14 | Adafruit invests time and resources providing this open source code, 15 | please support Adafruit and open-source hardware by purchasing 16 | products from Adafruit! 17 | 18 | @section HISTORY 19 | 20 | v1.0 - Initial release 21 | */ 22 | /**************************************************************************/ 23 | 24 | #include 25 | 26 | #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) 27 | #if (GCC_VERSION >= 40702) || !defined(prog_char) 28 | typedef char PROGMEM prog_char; 29 | #endif 30 | 31 | #ifndef _CC3000_DEBUG 32 | #define _CC3000_DEBUG 33 | 34 | #define DEBUG_MODE (0) 35 | 36 | int getFreeRam(void); 37 | void displayFreeRam(void); 38 | void uart_putchar(char c); 39 | void printHex(uint8_t h); 40 | void printHex16(uint16_t h); 41 | void DEBUGPRINT(const prog_char *fstr); 42 | void printDec(uint8_t h); 43 | void printDec16(uint16_t h); 44 | 45 | #ifndef FLASHIFY 46 | #define FLASHIFY(s) ({static const char c[] __attribute__ ((progmem)) = s;c;}) 47 | #endif 48 | 49 | #define PRINT_F(__s) DEBUGPRINT(FLASHIFY(__s)) 50 | 51 | #if (DEBUG_MODE != 0) 52 | #define DEBUGPRINT_F(__s) DEBUGPRINT(FLASHIFY(__s)) 53 | #define DEBUGPRINT_DEC(x) printDec(x) 54 | #define DEBUGPRINT_DEC16(x) printDec16(x) 55 | #define DEBUGPRINT_HEX(x) printHex(x) 56 | #define DEBUGPRINT_HEX16(x) printHex16(x) 57 | #else 58 | #define DEBUGPRINT_F(__s) /* do nothing! */ 59 | #define DEBUGPRINT_DEC(x) 60 | #define DEBUGPRINT_DEC16(x) 61 | #define DEBUGPRINT_HEX(x) 62 | #define DEBUGPRINT_HEX16(x) 63 | #endif 64 | 65 | extern Print* CC3KPrinter; 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /utility/host_driver_version.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * host_driver_version.h - CC3000 Host Driver Implementation. 4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 5 | * 6 | * Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) 7 | * & Limor Fried for Adafruit Industries 8 | * This library works with the Adafruit CC3000 breakout 9 | * ----> https://www.adafruit.com/products/1469 10 | * Adafruit invests time and resources providing this open source code, 11 | * please support Adafruit and open-source hardware by purchasing 12 | * products from Adafruit! 13 | * 14 | * Redistribution and use in source and binary forms, with or without 15 | * modification, are permitted provided that the following conditions 16 | * are met: 17 | * 18 | * Redistributions of source code must retain the above copyright 19 | * notice, this list of conditions and the following disclaimer. 20 | * 21 | * Redistributions in binary form must reproduce the above copyright 22 | * notice, this list of conditions and the following disclaimer in the 23 | * documentation and/or other materials provided with the 24 | * distribution. 25 | * 26 | * Neither the name of Texas Instruments Incorporated nor the names of 27 | * its contributors may be used to endorse or promote products derived 28 | * from this software without specific prior written permission. 29 | * 30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 33 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 34 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 35 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 36 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 37 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 38 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 39 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 40 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 | * 42 | *****************************************************************************/ 43 | #ifndef __HOST_DRIVER_VERSION_H__ 44 | #define __HOST_DRIVER_VERSION_H__ 45 | 46 | #define DRIVER_VERSION_NUMBER 16 47 | 48 | 49 | 50 | #endif // __VERSION_H__ 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for opening an issue on an Adafruit Arduino library repository. To 2 | improve the speed of resolution please review the following guidelines and 3 | common troubleshooting steps below before creating the issue: 4 | 5 | - **Do not use GitHub issues for troubleshooting projects and issues.** Instead use 6 | the forums at http://forums.adafruit.com to ask questions and troubleshoot why 7 | something isn't working as expected. In many cases the problem is a common issue 8 | that you will more quickly receive help from the forum community. GitHub issues 9 | are meant for known defects in the code. If you don't know if there is a defect 10 | in the code then start with troubleshooting on the forum first. 11 | 12 | - **If following a tutorial or guide be sure you didn't miss a step.** Carefully 13 | check all of the steps and commands to run have been followed. Consult the 14 | forum if you're unsure or have questions about steps in a guide/tutorial. 15 | 16 | - **For Arduino projects check these very common issues to ensure they don't apply**: 17 | 18 | - For uploading sketches or communicating with the board make sure you're using 19 | a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes 20 | very hard to tell the difference between a data and charge cable! Try using the 21 | cable with other devices or swapping to another cable to confirm it is not 22 | the problem. 23 | 24 | - **Be sure you are supplying adequate power to the board.** Check the specs of 25 | your board and plug in an external power supply. In many cases just 26 | plugging a board into your computer is not enough to power it and other 27 | peripherals. 28 | 29 | - **Double check all soldering joints and connections.** Flakey connections 30 | cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints. 31 | 32 | - **Ensure you are using an official Arduino or Adafruit board.** We can't 33 | guarantee a clone board will have the same functionality and work as expected 34 | with this code and don't support them. 35 | 36 | If you're sure this issue is a defect in the code and checked the steps above 37 | please fill in the following fields to provide enough troubleshooting information. 38 | You may delete the guideline and text above to just leave the following details: 39 | 40 | - Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE** 41 | 42 | - Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO 43 | VERSION HERE** 44 | 45 | - List the steps to reproduce the problem below (if possible attach a sketch or 46 | copy the sketch code in too): **LIST REPRO STEPS BELOW** 47 | -------------------------------------------------------------------------------- /utility/debug.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************/ 2 | /*! 3 | @file Adafruit_CC3000.cpp 4 | @author KTOWN (Kevin Townsend Adafruit Industries) 5 | @license BSD (see license.txt) 6 | 7 | This is a library for the Adafruit CC3000 WiFi breakout board 8 | This library works with the Adafruit CC3000 breakout 9 | ----> https://www.adafruit.com/products/1469 10 | 11 | Check out the links above for our tutorials and wiring diagrams 12 | These chips use SPI to communicate. 13 | 14 | Adafruit invests time and resources providing this open source code, 15 | please support Adafruit and open-source hardware by purchasing 16 | products from Adafruit! 17 | 18 | @section HISTORY 19 | 20 | v1.0 - Initial release 21 | */ 22 | /**************************************************************************/ 23 | 24 | #include "debug.h" 25 | 26 | /**************************************************************************/ 27 | /*! 28 | @brief This function will display the number of bytes currently free 29 | in RAM ... useful for debugging! 30 | */ 31 | /**************************************************************************/ 32 | 33 | #if defined(ARDUINO_ARCH_SAMD) || defined (__arm__) || defined(ARDUINO_ARCH_SAM) 34 | // should use uinstd.h to define sbrk but on Arduino Due this causes a conflict 35 | extern "C" char* sbrk(int incr); 36 | int getFreeRam(void) { 37 | char top; 38 | return &top - reinterpret_cast(sbrk(0)); 39 | } 40 | #else // AVR 41 | int getFreeRam(void) 42 | { 43 | extern int __bss_end; 44 | extern int *__brkval; 45 | int free_memory; 46 | if((int)__brkval == 0) { 47 | free_memory = ((int)&free_memory) - ((int)&__bss_end); 48 | } 49 | else { 50 | free_memory = ((int)&free_memory) - ((int)__brkval); 51 | } 52 | 53 | return free_memory; 54 | } 55 | #endif 56 | 57 | void displayFreeRam(void) 58 | { 59 | if (CC3KPrinter == 0) { 60 | return; 61 | } 62 | CC3KPrinter->print(F("Free RAM: ")); 63 | CC3KPrinter->print(getFreeRam()); 64 | CC3KPrinter->println(F(" bytes")); 65 | } 66 | 67 | void uart_putchar(char c) { 68 | if (CC3KPrinter != 0) { 69 | CC3KPrinter->write(c); 70 | } 71 | } 72 | 73 | void printDec(uint8_t h) { 74 | uart_putchar((h / 100) + '0'); 75 | h %= 100; 76 | uart_putchar((h / 10) + '0'); 77 | h %= 10; 78 | uart_putchar(h + '0'); 79 | } 80 | 81 | 82 | void printHex(uint8_t h) { 83 | uint8_t d = h >> 4; 84 | if (d >= 10) { 85 | uart_putchar(d - 10 + 'A'); 86 | } else { 87 | uart_putchar(d + '0'); 88 | } 89 | h &= 0xF; 90 | if (h >= 10) { 91 | uart_putchar(h - 10 + 'A'); 92 | } else { 93 | uart_putchar(h + '0'); 94 | } 95 | } 96 | 97 | void printHex16(uint16_t h) { 98 | uart_putchar('0'); 99 | uart_putchar('x'); 100 | DEBUGPRINT_HEX(h >> 8); 101 | DEBUGPRINT_HEX(h); 102 | } 103 | 104 | 105 | void printDec16(uint16_t h) { 106 | uart_putchar((h / 10000) + '0'); 107 | h %= 10000; 108 | uart_putchar((h / 1000) + '0'); 109 | h %= 1000; 110 | uart_putchar((h / 100) + '0'); 111 | h %= 100; 112 | uart_putchar((h / 10) + '0'); 113 | h %= 10; 114 | uart_putchar(h + '0'); 115 | } 116 | 117 | 118 | void DEBUGPRINT(const prog_char *fstr) 119 | { 120 | char c; 121 | if(!fstr) return; 122 | while((c = pgm_read_byte(fstr++))) 123 | uart_putchar(c); 124 | } 125 | -------------------------------------------------------------------------------- /ccspi.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * spi.h - CC3000 Host Driver Implementation. 4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 5 | * 6 | * Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) 7 | * & Limor Fried for Adafruit Industries 8 | * This library works with the Adafruit CC3000 breakout 9 | * ----> https://www.adafruit.com/products/1469 10 | * Adafruit invests time and resources providing this open source code, 11 | * please support Adafruit and open-source hardware by purchasing 12 | * products from Adafruit! 13 | * 14 | * Redistribution and use in source and binary forms, with or without 15 | * modification, are permitted provided that the following conditions 16 | * are met: 17 | * 18 | * Redistributions of source code must retain the above copyright 19 | * notice, this list of conditions and the following disclaimer. 20 | * 21 | * Redistributions in binary form must reproduce the above copyright 22 | * notice, this list of conditions and the following disclaimer in the 23 | * documentation and/or other materials provided with the 24 | * distribution. 25 | * 26 | * Neither the name of Texas Instruments Incorporated nor the names of 27 | * its contributors may be used to endorse or promote products derived 28 | * from this software without specific prior written permission. 29 | * 30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 33 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 34 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 35 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 36 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 37 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 38 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 39 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 40 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 | * 42 | *****************************************************************************/ 43 | 44 | 45 | #ifndef __SPI_H__ 46 | #define __SPI_H__ 47 | 48 | // Adafruit CC3k Host Driver Difference 49 | // Include necessary Arduino headers. 50 | // Noted 12-12-2014 by tdicola 51 | #if ARDUINO >= 100 52 | #include "Arduino.h" 53 | #else 54 | #include "WProgram.h" 55 | #endif 56 | 57 | #include 58 | #include 59 | #include 60 | #include 61 | 62 | #include "utility/wlan.h" 63 | 64 | typedef void (*gcSpiHandleRx)(void *p); 65 | typedef void (*gcSpiHandleTx)(void); 66 | 67 | extern unsigned char wlan_tx_buffer[]; 68 | 69 | //***************************************************************************** 70 | // 71 | // Prototypes for the APIs. 72 | // 73 | //***************************************************************************** 74 | extern void SpiOpen(gcSpiHandleRx pfRxHandler); 75 | extern void SpiClose(void); 76 | extern long SpiWrite(unsigned char *pUserBuffer, unsigned short usLength); 77 | extern void SpiResumeSpi(void); 78 | extern void SpiCleanGPIOISR(void); 79 | extern int init_spi(void); 80 | extern long TXBufferIsEmpty(void); 81 | extern long RXBufferIsEmpty(void); 82 | extern void CC3000_UsynchCallback(long lEventType, char * data, unsigned char length); 83 | extern void WriteWlanPin( unsigned char val ); 84 | extern long ReadWlanInterruptPin(void); 85 | extern void WlanInterruptEnable(); 86 | extern void WlanInterruptDisable(); 87 | extern char *sendDriverPatch(unsigned long *Length); 88 | extern char *sendBootLoaderPatch(unsigned long *Length); 89 | extern char *sendWLFWPatch(unsigned long *Length); 90 | extern void SPI_IRQ(void); 91 | 92 | #endif 93 | 94 | -------------------------------------------------------------------------------- /utility/data_types.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * data_types.h - CC3000 Host Driver Implementation. 4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 5 | * 6 | * Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) 7 | * & Limor Fried for Adafruit Industries 8 | * This library works with the Adafruit CC3000 breakout 9 | * ----> https://www.adafruit.com/products/1469 10 | * Adafruit invests time and resources providing this open source code, 11 | * please support Adafruit and open-source hardware by purchasing 12 | * products from Adafruit! 13 | * 14 | * Redistribution and use in source and binary forms, with or without 15 | * modification, are permitted provided that the following conditions 16 | * are met: 17 | * 18 | * Redistributions of source code must retain the above copyright 19 | * notice, this list of conditions and the following disclaimer. 20 | * 21 | * Redistributions in binary form must reproduce the above copyright 22 | * notice, this list of conditions and the following disclaimer in the 23 | * documentation and/or other materials provided with the 24 | * distribution. 25 | * 26 | * Neither the name of Texas Instruments Incorporated nor the names of 27 | * its contributors may be used to endorse or promote products derived 28 | * from this software without specific prior written permission. 29 | * 30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 33 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 34 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 35 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 36 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 37 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 38 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 39 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 40 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 | * 42 | *****************************************************************************/ 43 | #ifndef __DATA_TYPES__ 44 | #define __DATA_TYPES__ 45 | 46 | //***************************************************************************** 47 | // 48 | // If building with a C++ compiler, make all of the definitions in this header 49 | // have a C binding. 50 | // 51 | //***************************************************************************** 52 | #ifdef __cplusplus 53 | extern "C" { 54 | #endif 55 | 56 | 57 | #ifndef NULL 58 | #define NULL (0) 59 | #endif 60 | 61 | #ifndef FALSE 62 | #define FALSE (0) 63 | #endif 64 | 65 | #ifndef TRUE 66 | #define TRUE (!FALSE) 67 | #endif 68 | 69 | #ifndef OK 70 | #define OK (0) 71 | #endif 72 | 73 | #ifndef _INT8 74 | #define _INT8 75 | typedef signed char INT8; 76 | #endif 77 | 78 | #ifndef _UINT8 79 | #define _UINT8 80 | typedef unsigned char UINT8; 81 | #endif 82 | 83 | #ifndef _INT16 84 | #define _INT16 85 | typedef signed short INT16; 86 | #endif 87 | 88 | #ifndef _UINT16 89 | #define _UINT16 90 | typedef unsigned short UINT16; 91 | #endif 92 | 93 | #ifndef _BOOLEAN 94 | #define _BOOLEAN 95 | typedef unsigned char BOOLEAN; 96 | #endif 97 | 98 | #ifndef _INT32 99 | #define _INT32 100 | typedef signed long INT32; 101 | #endif 102 | 103 | #ifndef _UINT32 104 | #define _UINT32 105 | typedef unsigned long UINT32; 106 | #endif 107 | 108 | typedef int INT; 109 | typedef char CHAR; 110 | 111 | #ifdef __cplusplus 112 | } 113 | #endif /* __cplusplus */ 114 | 115 | #endif /* __DATA_TYPE__ */ 116 | -------------------------------------------------------------------------------- /Adafruit_CC3000_Server.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************/ 2 | /*! 3 | @file Adafruit_CC3000_Server.h 4 | @author Tony DiCola (tony@tonydicola.com) 5 | @license BSD (see license.txt) 6 | 7 | Adafruit CC3000 TCP server implementation based on the same interface as 8 | the Arduino Ethernet library server class. 9 | 10 | See http://arduino.cc/en/Reference/Ethernet for documentation on the 11 | Arduino Ethernet library and its server interface. 12 | 13 | The only difference between this implementation and the Ethernet library 14 | is that a special client reference facade is returned by the available() 15 | function, instead of a copy of a client like in the Ethernet library. This 16 | is necessary to ensure the buffers that client instances contain aren't 17 | copied and get out of sync. 18 | 19 | */ 20 | /**************************************************************************/ 21 | 22 | #ifndef ADAFRUIT_CC3000_SERVER_H 23 | #define ADAFRUIT_CC3000_SERVER_H 24 | 25 | #include "Adafruit_CC3000.h" 26 | 27 | #include "Client.h" 28 | #include "Server.h" 29 | 30 | // Assume 4 sockets available, 1 of which is used for listening, so at most 3 31 | // clients can be connected at once. 32 | #define MAX_SERVER_CLIENTS 3 33 | 34 | // Facade that wraps a reference to a client instance into something that looks 35 | // and acts like a client instance value. This is done to mimic the semantics 36 | // of the Ethernet library, without running into problems allowing client buffers 37 | // to be copied and get out of sync. 38 | class Adafruit_CC3000_ClientRef : public Client { 39 | public: 40 | Adafruit_CC3000_ClientRef(Adafruit_CC3000_Client* client); 41 | // Return true if the referenced client is connected. This is provided for 42 | // compatibility with Ethernet library code. 43 | operator bool(); 44 | // Below are all the public methods of the client class: 45 | int connect(IPAddress ip, uint16_t port); 46 | int connect(const char *host, uint16_t port); 47 | 48 | uint8_t connected(void); 49 | size_t write(uint8_t c); 50 | 51 | size_t fastrprint(const char *str); 52 | size_t fastrprintln(const char *str); 53 | size_t fastrprint(char *str); 54 | size_t fastrprintln(char *str); 55 | size_t fastrprint(const __FlashStringHelper *ifsh); 56 | size_t fastrprintln(const __FlashStringHelper *ifsh); 57 | 58 | size_t write(const void *buf, uint16_t len, uint32_t flags = 0); 59 | int read(void *buf, uint16_t len, uint32_t flags = 0); 60 | int read(void); 61 | int32_t close(void); 62 | int available(void); 63 | 64 | int read(uint8_t *buf, size_t size); 65 | size_t write(const uint8_t *buf, size_t size); 66 | int peek(); 67 | void flush(); 68 | void stop(); 69 | 70 | private: 71 | // Hide the fact that users are really dealing with a pointer to a client 72 | // instance. Note: this class does not own the contents of the client 73 | // pointer and should NEVER attempt to free/delete this pointer. 74 | Adafruit_CC3000_Client* _client; 75 | 76 | }; 77 | 78 | 79 | class Adafruit_CC3000_Server : public Server { 80 | public: 81 | // Construct a TCP server to listen on the specified port. 82 | Adafruit_CC3000_Server(uint16_t port); 83 | // Return the index of a client instance with data available to read. 84 | // This is useful if you need to keep track of your own client state, you can 85 | // index into an array of client state based on the available index returned 86 | // from this function. Optional boolean parameter returns by reference true 87 | // if the available client is connecting for the first time. 88 | int8_t availableIndex(bool *newClient = NULL); 89 | // Get a client instance from a given index. 90 | Adafruit_CC3000_ClientRef getClientRef(int8_t clientIndex); 91 | // Return a reference to a client instance which has data available to read. 92 | Adafruit_CC3000_ClientRef available(); 93 | // Initialize the server and start listening for connections. 94 | virtual void begin(); 95 | // Write data to all connected clients. Buffer is a pointer to an array 96 | // of bytes, and size specifies how many bytes to write from the buffer. 97 | // Return the sum of bytes written to all clients. 98 | virtual size_t write(const uint8_t *buffer, size_t size); 99 | // Write a byte value to all connected clients. 100 | // Return the sum of bytes written to all clients. 101 | virtual size_t write(uint8_t value); 102 | // Make the overloads of write from the Print base class available. 103 | using Print::write; 104 | 105 | private: 106 | // Store the clients in a simple array. 107 | Adafruit_CC3000_Client _clients[MAX_SERVER_CLIENTS]; 108 | // The port this server will listen for connections on. 109 | uint16_t _port; 110 | // The id of the listening socket. 111 | uint32_t _listenSocket; 112 | 113 | // Accept new connections and update the connected clients. 114 | bool acceptNewConnections(); 115 | }; 116 | 117 | #endif 118 | -------------------------------------------------------------------------------- /utility/security.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * security.h - CC3000 Host Driver Implementation. 4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 5 | * 6 | * Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) 7 | * & Limor Fried for Adafruit Industries 8 | * This library works with the Adafruit CC3000 breakout 9 | * ----> https://www.adafruit.com/products/1469 10 | * Adafruit invests time and resources providing this open source code, 11 | * please support Adafruit and open-source hardware by purchasing 12 | * products from Adafruit! 13 | * 14 | * Redistribution and use in source and binary forms, with or without 15 | * modification, are permitted provided that the following conditions 16 | * are met: 17 | * 18 | * Redistributions of source code must retain the above copyright 19 | * notice, this list of conditions and the following disclaimer. 20 | * 21 | * Redistributions in binary form must reproduce the above copyright 22 | * notice, this list of conditions and the following disclaimer in the 23 | * documentation and/or other materials provided with the 24 | * distribution. 25 | * 26 | * Neither the name of Texas Instruments Incorporated nor the names of 27 | * its contributors may be used to endorse or promote products derived 28 | * from this software without specific prior written permission. 29 | * 30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 33 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 34 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 35 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 36 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 37 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 38 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 39 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 40 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 | * 42 | *****************************************************************************/ 43 | #ifndef __SECURITY__ 44 | #define __SECURITY__ 45 | 46 | #include "nvmem.h" 47 | 48 | //***************************************************************************** 49 | // 50 | // If building with a C++ compiler, make all of the definitions in this header 51 | // have a C binding. 52 | // 53 | //***************************************************************************** 54 | #ifdef __cplusplus 55 | extern "C" { 56 | #endif 57 | 58 | 59 | #define AES128_KEY_SIZE 16 60 | 61 | #ifndef CC3000_UNENCRYPTED_SMART_CONFIG 62 | 63 | 64 | //***************************************************************************** 65 | // 66 | //! aes_encrypt 67 | //! 68 | //! @param[in] key AES128 key of size 16 bytes 69 | //! @param[in\out] state 16 bytes of plain text and cipher text 70 | //! 71 | //! @return none 72 | //! 73 | //! @brief AES128 encryption: 74 | //! Given AES128 key and 16 bytes plain text, cipher text of 16 bytes 75 | //! is computed. The AES implementation is in mode ECB (Electronic 76 | //! Code Book). 77 | //! 78 | //! 79 | //***************************************************************************** 80 | extern void aes_encrypt(UINT8 *state, UINT8 *key); 81 | 82 | //***************************************************************************** 83 | // 84 | //! aes_decrypt 85 | //! 86 | //! @param[in] key AES128 key of size 16 bytes 87 | //! @param[in\out] state 16 bytes of cipher text and plain text 88 | //! 89 | //! @return none 90 | //! 91 | //! @brief AES128 decryption: 92 | //! Given AES128 key and 16 bytes cipher text, plain text of 16 bytes 93 | //! is computed The AES implementation is in mode ECB 94 | //! (Electronic Code Book). 95 | //! 96 | //! 97 | //***************************************************************************** 98 | extern void aes_decrypt(UINT8 *state, UINT8 *key); 99 | 100 | 101 | //***************************************************************************** 102 | // 103 | //! aes_read_key 104 | //! 105 | //! @param[out] key AES128 key of size 16 bytes 106 | //! 107 | //! @return on success 0, error otherwise. 108 | //! 109 | //! @brief Reads AES128 key from EEPROM 110 | //! Reads the AES128 key from fileID #12 in EEPROM 111 | //! returns an error if the key does not exist. 112 | //! 113 | //! 114 | //***************************************************************************** 115 | extern INT32 aes_read_key(UINT8 *key); 116 | 117 | //***************************************************************************** 118 | // 119 | //! aes_write_key 120 | //! 121 | //! @param[out] key AES128 key of size 16 bytes 122 | //! 123 | //! @return on success 0, error otherwise. 124 | //! 125 | //! @brief writes AES128 key from EEPROM 126 | //! Writes the AES128 key to fileID #12 in EEPROM 127 | //! 128 | //! 129 | //***************************************************************************** 130 | extern INT32 aes_write_key(UINT8 *key); 131 | 132 | #endif //CC3000_UNENCRYPTED_SMART_CONFIG 133 | 134 | #ifdef __cplusplus 135 | } 136 | #endif // __cplusplus 137 | 138 | #endif 139 | -------------------------------------------------------------------------------- /utility/error_codes.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * error_codes.h - CC3000 Host Driver Implementation. 4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 5 | * 6 | * Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) 7 | * & Limor Fried for Adafruit Industries 8 | * This library works with the Adafruit CC3000 breakout 9 | * ----> https://www.adafruit.com/products/1469 10 | * Adafruit invests time and resources providing this open source code, 11 | * please support Adafruit and open-source hardware by purchasing 12 | * products from Adafruit! 13 | * 14 | * Redistribution and use in source and binary forms, with or without 15 | * modification, are permitted provided that the following conditions 16 | * are met: 17 | * 18 | * Redistributions of source code must retain the above copyright 19 | * notice, this list of conditions and the following disclaimer. 20 | * 21 | * Redistributions in binary form must reproduce the above copyright 22 | * notice, this list of conditions and the following disclaimer in the 23 | * documentation and/or other materials provided with the 24 | * distribution. 25 | * 26 | * Neither the name of Texas Instruments Incorporated nor the names of 27 | * its contributors may be used to endorse or promote products derived 28 | * from this software without specific prior written permission. 29 | * 30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 33 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 34 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 35 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 36 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 37 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 38 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 39 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 40 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 | * 42 | *****************************************************************************/ 43 | #ifndef __ERROR_CODES__ 44 | #define __ERROR_CODES__ 45 | 46 | //***************************************************************************** 47 | // 48 | // If building with a C++ compiler, make all of the definitions in this header 49 | // have a C binding. 50 | // 51 | //***************************************************************************** 52 | #ifdef __cplusplus 53 | extern "C" { 54 | #endif 55 | 56 | // 57 | // Error numbers 58 | // 59 | #define ERROR_WIFI_ALREADY_DISCONNECTED -129 60 | #define NOT_ENOUGH_SOCKETS -128 61 | #define SOCKET_ALREADY_EXISTS -127 62 | #define NOT_SUPPORTED -126 63 | #define TCP_OPEN_FAILED -124 64 | #define BAD_SOCKET_DATA -123 65 | #define SOCKET_NOT_FOUND -122 66 | #define SOCKET_TIMED_OUT -121 67 | #define BAD_IP_HEADER -120 68 | #define NEED_TO_LISTEN -119 69 | #define RECV_TIMED_OUT -118 70 | #define NEED_TO_SEND -114 71 | #define UNABLE_TO_SEND -113 72 | #define DHCP_ERROR -100 73 | #define DHCP_LEASE_EXPIRED -99 74 | #define ARP_REQUEST_FAILED -95 75 | #define DHCP_LEASE_RENEWING -92 76 | #define IGMP_ERROR -91 77 | #define INVALID_VALUE -85 78 | #define DNS_ID_ERROR -75 79 | #define DNS_OPCODE_ERROR -74 80 | #define DNS_RCODE_ERROR -73 81 | #define DNS_COUNT_ERROR -72 82 | #define DNS_TYPE_ERROR -71 83 | #define DNS_CLASS_ERROR -70 84 | #define DNS_NOT_FOUND -69 85 | #define SOCKET_BUFFER_TOO_SMALL -68 86 | #define REASSEMBLY_ERROR -64 87 | #define REASSEMBLY_TIMED_OUT -63 88 | #define BAD_REASSEMBLY_DATA -62 89 | #define UNABLE_TO_TCP_SEND -60 90 | #define ERROR_WIFI_NOT_CONNECTED -59 91 | #define SEND_FAILED_ARP_IN_PROCESS -58 92 | #define RECV_FAILED_SOCKET_INACTIVE -57 93 | 94 | // 95 | // Return the same error code to all socket 96 | // calls which fail due to socket's inactivity 97 | // 98 | #define ERROR_SOCKET_INACTIVE RECV_FAILED_SOCKET_INACTIVE 99 | 100 | // 101 | // TCP function error codes 102 | // 103 | #define TCP_ERROR -1 104 | #define TCP_TOO_LONG -2 105 | #define TCP_BAD_HEADER -3 106 | #define TCP_BAD_CSUM -4 107 | #define TCP_BAD_FCS -5 108 | #define TCP_NO_CONNECT -6 109 | 110 | // 111 | // UDP function error codes 112 | // 113 | #define UDP_ERROR -1 114 | #define UDP_TOO_LONG -2 115 | #define UDP_BAD_CSUM -4 116 | #define UDP_BAD_FCS -5 117 | 118 | // 119 | // Raw error codes 120 | // 121 | #define RAW_ERROR -1 122 | #define RAW_TOO_LONG -2 123 | 124 | // 125 | // SimpleLink error codes 126 | // 127 | #define SL_INVALID_INTERFACE -1 128 | #define SL_NO_MORE_DATA_TO_READ -2 129 | #define SL_OUT_OF_RESOURCES (-150) 130 | #define SL_NOT_ENOUGH_SPACE (-151) 131 | #define SL_INCORRECT_IF (-152) 132 | #define SL_NOTHING_TO_SEND (-153) 133 | #define SL_WILL_SEND_LATER (100) // This is not an error - just an indication that we can't send data now 134 | #define SL_TX_ALLOC_FAILED (-161) 135 | 136 | #define SL_INVALID_COMMAND_ARGUMENTS (-170) 137 | 138 | #ifdef __cplusplus 139 | } 140 | #endif /* __cplusplus */ 141 | 142 | #endif /* __ERROR_CODES__ */ 143 | -------------------------------------------------------------------------------- /examples/SmartConfigReconnect/SmartConfigReconnect.ino: -------------------------------------------------------------------------------- 1 | /*************************************************** 2 | This is an example for the Adafruit CC3000 Wifi Breakout & Shield 3 | 4 | Designed specifically to work with the Adafruit WiFi products: 5 | ----> https://www.adafruit.com/products/1469 6 | 7 | Adafruit invests time and resources providing this open source code, 8 | please support Adafruit and open-source hardware by purchasing 9 | products from Adafruit! 10 | 11 | Written by Limor Fried & Kevin Townsend for Adafruit Industries. 12 | BSD license, all text above must be included in any redistribution 13 | ****************************************************/ 14 | 15 | /* This sketch attempts to re-connect to an AP using 16 | data from a previous SmartConfig session (i.e. from 17 | the SmartConfigCreate sketch!). 18 | 19 | It will attempt to do the following: 20 | 21 | * Initialization the CC3000 22 | * Re-connect using previous SmartConfig data (see SmartConfigCreate) 23 | * DHCP printout 24 | * Disconnect 25 | 26 | If the connection fails, there are two likely 27 | explanations: 28 | 29 | 1.) You haven't run the SmartConfigCreate sketch and 30 | successfully connected to a network, since this 31 | is the process that 'saves' the AP details to the 32 | device 33 | 2.) You've used one of the other non SmartConfig 34 | sketches, which erase all stored profiles from 35 | the CC3000 memory in order to manually establish 36 | a connection using hard coded values. (This sketch 37 | uses an optional flag in the Adafruit_CC3000.begin 38 | function to avoid this erasure process!). 39 | 40 | SmartConfig is still beta and kind of works but is not fully 41 | vetted! It might not work on all networks! 42 | */ 43 | 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include "utility/debug.h" 49 | 50 | // These are the interrupt and control pins 51 | #define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin! 52 | // These can be any two pins 53 | #define ADAFRUIT_CC3000_VBAT 5 54 | #define ADAFRUIT_CC3000_CS 10 55 | 56 | #define DEVICE_NAME "CC3000" 57 | 58 | // Use hardware SPI for the remaining pins 59 | // On an UNO, SCK = 13, MISO = 12, and MOSI = 11 60 | Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, 61 | ADAFRUIT_CC3000_IRQ, 62 | ADAFRUIT_CC3000_VBAT, 63 | SPI_CLOCK_DIVIDER); 64 | 65 | // We get the SSID & Password from memory thanks to SmartConfigCreate! 66 | 67 | /**************************************************************************/ 68 | /*! 69 | @brief Sets up the HW and the CC3000 module (called automatically 70 | on startup) 71 | */ 72 | /**************************************************************************/ 73 | void setup(void) 74 | { 75 | Serial.begin(115200); 76 | Serial.println(F("Hello, CC3000!\n")); 77 | 78 | /* Try to reconnect using the details from SmartConfig */ 79 | /* This basically just resets the CC3000, and the auto connect */ 80 | /* tries to do it's magic if connections details are found */ 81 | Serial.println(F("Trying to reconnect using SmartConfig values ...")); 82 | 83 | /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ 84 | /* !!! Note the additional arguments in .begin that tell the !!! */ 85 | /* !!! app NOT to deleted previously stored connection details !!! */ 86 | /* !!! and reconnected using the connection details in memory! !!! */ 87 | /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ 88 | if (!cc3000.begin(false, true, DEVICE_NAME)) 89 | { 90 | Serial.println(F("Unable to re-connect!? Did you run the SmartConfigCreate")); 91 | Serial.println(F("sketch to store your connection details?")); 92 | while(1); 93 | } 94 | 95 | /* Round of applause! */ 96 | Serial.println(F("Reconnected!")); 97 | 98 | /* Wait for DHCP to complete */ 99 | Serial.println(F("\nRequesting DHCP")); 100 | while (!cc3000.checkDHCP()) { 101 | delay(100); // ToDo: Insert a DHCP timeout! 102 | } 103 | 104 | /* Display the IP address DNS, Gateway, etc. */ 105 | while (! displayConnectionDetails()) { 106 | delay(1000); 107 | } 108 | 109 | /* This is where you'd do your own thing! */ 110 | 111 | /* You need to make sure to clean up after yourself or the CC3000 can freak out */ 112 | /* the next time your try to connect ... */ 113 | Serial.println(F("\nClosing the connection")); 114 | cc3000.disconnect(); 115 | } 116 | 117 | void loop(void) 118 | { 119 | delay(1000); 120 | } 121 | 122 | /**************************************************************************/ 123 | /*! 124 | @brief Tries to read the IP address and other connection details 125 | */ 126 | /**************************************************************************/ 127 | bool displayConnectionDetails(void) 128 | { 129 | uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv; 130 | 131 | if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv)) 132 | { 133 | Serial.println(F("Unable to retrieve the IP Address!\r\n")); 134 | return false; 135 | } 136 | else 137 | { 138 | Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress); 139 | Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask); 140 | Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway); 141 | Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv); 142 | Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv); 143 | Serial.println(); 144 | return true; 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /utility/evnt_handler.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * evnt_handler.h - CC3000 Host Driver Implementation. 4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 5 | * 6 | * Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) 7 | * & Limor Fried for Adafruit Industries 8 | * This library works with the Adafruit CC3000 breakout 9 | * ----> https://www.adafruit.com/products/1469 10 | * Adafruit invests time and resources providing this open source code, 11 | * please support Adafruit and open-source hardware by purchasing 12 | * products from Adafruit! 13 | * 14 | * Redistribution and use in source and binary forms, with or without 15 | * modification, are permitted provided that the following conditions 16 | * are met: 17 | * 18 | * Redistributions of source code must retain the above copyright 19 | * notice, this list of conditions and the following disclaimer. 20 | * 21 | * Redistributions in binary form must reproduce the above copyright 22 | * notice, this list of conditions and the following disclaimer in the 23 | * documentation and/or other materials provided with the 24 | * distribution. 25 | * 26 | * Neither the name of Texas Instruments Incorporated nor the names of 27 | * its contributors may be used to endorse or promote products derived 28 | * from this software without specific prior written permission. 29 | * 30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 33 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 34 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 35 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 36 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 37 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 38 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 39 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 40 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 | * 42 | *****************************************************************************/ 43 | #ifndef __EVENT_HANDLER_H__ 44 | #define __EVENT_HANDLER_H__ 45 | #include "hci.h" 46 | #include "socket.h" 47 | 48 | //***************************************************************************** 49 | // 50 | // If building with a C++ compiler, make all of the definitions in this header 51 | // have a C binding. 52 | // 53 | //***************************************************************************** 54 | #ifdef __cplusplus 55 | extern "C" { 56 | #endif 57 | 58 | //***************************************************************************** 59 | // 60 | // Prototypes for the APIs. 61 | // 62 | //***************************************************************************** 63 | 64 | //***************************************************************************** 65 | // 66 | //! hci_event_handler 67 | //! 68 | //! @param pRetParams incoming data buffer 69 | //! @param from from information (in case of data received) 70 | //! @param fromlen from information length (in case of data received) 71 | //! 72 | //! @return none 73 | //! 74 | //! @brief Parse the incoming events packets and issues corresponding 75 | //! event handler from global array of handlers pointers 76 | // 77 | //***************************************************************************** 78 | extern UINT8 *hci_event_handler(void *pRetParams, UINT8 *from, UINT8 *fromlen); 79 | 80 | //***************************************************************************** 81 | // 82 | //! hci_unsol_event_handler 83 | //! 84 | //! @param event_hdr event header 85 | //! 86 | //! @return 1 if event supported and handled 87 | //! 0 if event is not supported 88 | //! 89 | //! @brief Handle unsolicited events 90 | // 91 | //***************************************************************************** 92 | extern INT32 hci_unsol_event_handler(CHAR *event_hdr); 93 | 94 | //***************************************************************************** 95 | // 96 | //! hci_unsolicited_event_handler 97 | //! 98 | //! @param None 99 | //! 100 | //! @return ESUCCESS if successful, EFAIL if an error occurred 101 | //! 102 | //! @brief Parse the incoming unsolicited event packets and issues 103 | //! corresponding event handler. 104 | // 105 | //***************************************************************************** 106 | extern INT32 hci_unsolicited_event_handler(void); 107 | 108 | #define M_BSD_RESP_PARAMS_OFFSET(hci_event_hdr)((CHAR *)(hci_event_hdr) + HCI_EVENT_HEADER_SIZE) 109 | 110 | #define SOCKET_STATUS_ACTIVE 0 111 | #define SOCKET_STATUS_INACTIVE 1 112 | /* Init socket_active_status = 'all ones': init all sockets with SOCKET_STATUS_INACTIVE. 113 | Will be changed by 'set_socket_active_status' upon 'connect' and 'accept' calls */ 114 | #define SOCKET_STATUS_INIT_VAL 0xFFFF 115 | #define M_IS_VALID_SD(sd) ((0 <= (sd)) && ((sd) <= 7)) 116 | #define M_IS_VALID_STATUS(status) (((status) == SOCKET_STATUS_ACTIVE)||((status) == SOCKET_STATUS_INACTIVE)) 117 | 118 | extern UINT32 socket_active_status; 119 | 120 | extern void set_socket_active_status(INT32 Sd, INT32 Status); 121 | extern INT32 get_socket_active_status(INT32 Sd); 122 | 123 | typedef struct _bsd_accept_return_t 124 | { 125 | INT32 iSocketDescriptor; 126 | INT32 iStatus; 127 | sockaddr tSocketAddress; 128 | 129 | } tBsdReturnParams; 130 | 131 | 132 | typedef struct _bsd_read_return_t 133 | { 134 | INT32 iSocketDescriptor; 135 | INT32 iNumberOfBytes; 136 | UINT32 uiFlags; 137 | } tBsdReadReturnParams; 138 | 139 | #define BSD_RECV_FROM_FROMLEN_OFFSET (4) 140 | #define BSD_RECV_FROM_FROM_OFFSET (16) 141 | 142 | 143 | typedef struct _bsd_select_return_t 144 | { 145 | INT32 iStatus; 146 | UINT32 uiRdfd; 147 | UINT32 uiWrfd; 148 | UINT32 uiExfd; 149 | } tBsdSelectRecvParams; 150 | 151 | 152 | typedef struct _bsd_getsockopt_return_t 153 | { 154 | UINT8 ucOptValue[4]; 155 | CHAR iStatus; 156 | } tBsdGetSockOptReturnParams; 157 | 158 | typedef struct _bsd_gethostbyname_return_t 159 | { 160 | INT32 retVal; 161 | INT32 outputAddress; 162 | } tBsdGethostbynameParams; 163 | 164 | //***************************************************************************** 165 | // 166 | // Mark the end of the C bindings section for C++ compilers. 167 | // 168 | //***************************************************************************** 169 | #ifdef __cplusplus 170 | } 171 | #endif // __cplusplus 172 | 173 | #endif // __EVENT_HANDLER_H__ 174 | 175 | -------------------------------------------------------------------------------- /examples/ChatServer/ChatServer.ino: -------------------------------------------------------------------------------- 1 | 2 | /*************************************************** 3 | Adafruit CC3000 Breakout/Shield TCP Chat Server 4 | 5 | This is a simple chat server which allows clients to connect 6 | with telnet and exchange messages. Anything sent by one 7 | client will be written out to all connected clients. 8 | 9 | See the CC3000 tutorial on Adafruit's learning system 10 | for more information on setting up and using the 11 | CC3000: 12 | http://learn.adafruit.com/adafruit-cc3000-wifi 13 | 14 | Requirements: 15 | 16 | This sketch requires the Adafruit CC3000 library. You can 17 | download the library from: 18 | https://github.com/adafruit/Adafruit_CC3000_Library 19 | 20 | For information on installing libraries in the Arduino IDE 21 | see this page: 22 | http://arduino.cc/en/Guide/Libraries 23 | 24 | Usage: 25 | 26 | Update the SSID and, if necessary, the CC3000 hardware pin 27 | information below, then run the sketch and check the 28 | output of the serial port. After connecting to the 29 | wireless network successfully the sketch will output 30 | the IP address of the server and start listening for 31 | connections. Once listening for connections, connect 32 | to the server from your computer using a telnet client 33 | on port 23. 34 | 35 | For example on Linux or Mac OSX, if your CC3000 has an 36 | IP address 192.168.1.100 you would execute in a command 37 | window: 38 | 39 | telnet 192.168.1.100 23 40 | 41 | Connect multiple clients and notice that whatever one client 42 | sends will be echoed to all other clients. Press ctrl-] and 43 | type quit at the prompt to close the telnet session. 44 | 45 | On Windows you'll need to download a telnet client. PuTTY 46 | is a good, free GUI client: 47 | http://www.chiark.greenend.org.uk/~sgtatham/putty/ 48 | 49 | License: 50 | 51 | This example is copyright (c) 2013 Tony DiCola (tony@tonydicola.com) 52 | and is released under an open source MIT license. See details at: 53 | http://opensource.org/licenses/MIT 54 | 55 | This code was adapted from Adafruit CC3000 library example 56 | code which has the following license: 57 | 58 | Designed specifically to work with the Adafruit WiFi products: 59 | ----> https://www.adafruit.com/products/1469 60 | 61 | Adafruit invests time and resources providing this open source code, 62 | please support Adafruit and open-source hardware by purchasing 63 | products from Adafruit! 64 | 65 | Written by Limor Fried & Kevin Townsend for Adafruit Industries. 66 | BSD license, all text above must be included in any redistribution 67 | ****************************************************/ 68 | #include 69 | #include 70 | #include "utility/debug.h" 71 | #include "utility/socket.h" 72 | 73 | // These are the interrupt and control pins 74 | #define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin! 75 | // These can be any two pins 76 | #define ADAFRUIT_CC3000_VBAT 5 77 | #define ADAFRUIT_CC3000_CS 10 78 | // Use hardware SPI for the remaining pins 79 | // On an UNO, SCK = 13, MISO = 12, and MOSI = 11 80 | Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, 81 | SPI_CLOCK_DIVIDER); // you can change this clock speed 82 | 83 | #define WLAN_SSID "myNetwork" // cannot be longer than 32 characters! 84 | #define WLAN_PASS "myPassword" 85 | // Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2 86 | #define WLAN_SECURITY WLAN_SEC_WPA2 87 | 88 | #define LISTEN_PORT 23 // What TCP port to listen on for connections. 89 | 90 | Adafruit_CC3000_Server chatServer(LISTEN_PORT); 91 | 92 | void setup(void) 93 | { 94 | Serial.begin(115200); 95 | Serial.println(F("Hello, CC3000!\n")); 96 | 97 | Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC); 98 | 99 | /* Initialise the module */ 100 | Serial.println(F("\nInitializing...")); 101 | if (!cc3000.begin()) 102 | { 103 | Serial.println(F("Couldn't begin()! Check your wiring?")); 104 | while(1); 105 | } 106 | 107 | Serial.print(F("\nAttempting to connect to ")); Serial.println(WLAN_SSID); 108 | if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) { 109 | Serial.println(F("Failed!")); 110 | while(1); 111 | } 112 | 113 | Serial.println(F("Connected!")); 114 | 115 | Serial.println(F("Request DHCP")); 116 | while (!cc3000.checkDHCP()) 117 | { 118 | delay(100); // ToDo: Insert a DHCP timeout! 119 | } 120 | 121 | /* Display the IP address DNS, Gateway, etc. */ 122 | while (! displayConnectionDetails()) { 123 | delay(1000); 124 | } 125 | 126 | /*********************************************************/ 127 | /* You can safely remove this to save some flash memory! */ 128 | /*********************************************************/ 129 | Serial.println(F("\r\nNOTE: This sketch may cause problems with other sketches")); 130 | Serial.println(F("since the .disconnect() function is never called, so the")); 131 | Serial.println(F("AP may refuse connection requests from the CC3000 until a")); 132 | Serial.println(F("timeout period passes. This is normal behaviour since")); 133 | Serial.println(F("there isn't an obvious moment to disconnect with a server.\r\n")); 134 | 135 | // Start listening for connections 136 | chatServer.begin(); 137 | 138 | Serial.println(F("Listening for connections...")); 139 | } 140 | 141 | void loop(void) 142 | { 143 | // Try to get a client which is connected. 144 | Adafruit_CC3000_ClientRef client = chatServer.available(); 145 | if (client) { 146 | // Check if there is data available to read. 147 | if (client.available() > 0) { 148 | // Read a byte and write it to all clients. 149 | uint8_t ch = client.read(); 150 | chatServer.write(ch); 151 | } 152 | } 153 | } 154 | 155 | /**************************************************************************/ 156 | /*! 157 | @brief Tries to read the IP address and other connection details 158 | */ 159 | /**************************************************************************/ 160 | bool displayConnectionDetails(void) 161 | { 162 | uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv; 163 | 164 | if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv)) 165 | { 166 | Serial.println(F("Unable to retrieve the IP Address!\r\n")); 167 | return false; 168 | } 169 | else 170 | { 171 | Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress); 172 | Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask); 173 | Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway); 174 | Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv); 175 | Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv); 176 | Serial.println(); 177 | return true; 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /examples/EchoServer/EchoServer.ino: -------------------------------------------------------------------------------- 1 | 2 | /*************************************************** 3 | Adafruit CC3000 Breakout/Shield TCP Echo Server 4 | 5 | This is a simple implementation of the echo 6 | protocol, RFC 862 http://tools.ietf.org/html/rfc862 , 7 | for the Arduino platform and Adafruit CC3000 breakout 8 | or shield. This sketch will create a TCP server that 9 | listens by default on port 7 and echos back any data 10 | received. Up to 3 clients can be connected concurrently 11 | to the server. This sketch is meant as an example of how 12 | to write a simple server with the Arduino and CC3000. 13 | 14 | See the CC3000 tutorial on Adafruit's learning system 15 | for more information on setting up and using the 16 | CC3000: 17 | http://learn.adafruit.com/adafruit-cc3000-wifi 18 | 19 | Requirements: 20 | 21 | This sketch requires the Adafruit CC3000 library. You can 22 | download the library from: 23 | https://github.com/adafruit/Adafruit_CC3000_Library 24 | 25 | For information on installing libraries in the Arduino IDE 26 | see this page: 27 | http://arduino.cc/en/Guide/Libraries 28 | 29 | Usage: 30 | 31 | Update the SSID and, if necessary, the CC3000 hardware pin 32 | information below, then run the sketch and check the 33 | output of the serial port. After connecting to the 34 | wireless network successfully the sketch will output 35 | the IP address of the server and start listening for 36 | connections. Once listening for connections, connect 37 | to the server from your computer using a telnet client 38 | on port 7. 39 | 40 | For example on Linux or Mac OSX, if your CC3000 has an 41 | IP address 192.168.1.100 you would execute in a command 42 | window: 43 | 44 | telnet 192.168.1.100 7 45 | 46 | After connecting, notice that as you type input and 47 | press enter to send it the CC3000 will echo back exactly 48 | what you typed. Press ctrl-] and type quit at the prompt 49 | to close the telnet session. 50 | 51 | On Windows you'll need to download a telnet client. PuTTY 52 | is a good, free GUI client: 53 | http://www.chiark.greenend.org.uk/~sgtatham/putty/ 54 | 55 | License: 56 | 57 | This example is copyright (c) 2013 Tony DiCola (tony@tonydicola.com) 58 | and is released under an open source MIT license. See details at: 59 | http://opensource.org/licenses/MIT 60 | 61 | This code was adapted from Adafruit CC3000 library example 62 | code which has the following license: 63 | 64 | Designed specifically to work with the Adafruit WiFi products: 65 | ----> https://www.adafruit.com/products/1469 66 | 67 | Adafruit invests time and resources providing this open source code, 68 | please support Adafruit and open-source hardware by purchasing 69 | products from Adafruit! 70 | 71 | Written by Limor Fried & Kevin Townsend for Adafruit Industries. 72 | BSD license, all text above must be included in any redistribution 73 | ****************************************************/ 74 | #include 75 | #include 76 | #include "utility/debug.h" 77 | #include "utility/socket.h" 78 | 79 | // These are the interrupt and control pins 80 | #define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin! 81 | // These can be any two pins 82 | #define ADAFRUIT_CC3000_VBAT 5 83 | #define ADAFRUIT_CC3000_CS 10 84 | // Use hardware SPI for the remaining pins 85 | // On an UNO, SCK = 13, MISO = 12, and MOSI = 11 86 | Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, 87 | SPI_CLOCK_DIVIDER); // you can change this clock speed 88 | 89 | #define WLAN_SSID "myNetwork" // cannot be longer than 32 characters! 90 | #define WLAN_PASS "myPassword" 91 | // Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2 92 | #define WLAN_SECURITY WLAN_SEC_WPA2 93 | 94 | #define LISTEN_PORT 7 // What TCP port to listen on for connections. The echo protocol uses port 7. 95 | 96 | Adafruit_CC3000_Server echoServer(LISTEN_PORT); 97 | 98 | void setup(void) 99 | { 100 | Serial.begin(115200); 101 | Serial.println(F("Hello, CC3000!\n")); 102 | 103 | Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC); 104 | 105 | /* Initialise the module */ 106 | Serial.println(F("\nInitializing...")); 107 | if (!cc3000.begin()) 108 | { 109 | Serial.println(F("Couldn't begin()! Check your wiring?")); 110 | while(1); 111 | } 112 | 113 | Serial.print(F("\nAttempting to connect to ")); Serial.println(WLAN_SSID); 114 | if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) { 115 | Serial.println(F("Failed!")); 116 | while(1); 117 | } 118 | 119 | Serial.println(F("Connected!")); 120 | 121 | Serial.println(F("Request DHCP")); 122 | while (!cc3000.checkDHCP()) 123 | { 124 | delay(100); // ToDo: Insert a DHCP timeout! 125 | } 126 | 127 | /* Display the IP address DNS, Gateway, etc. */ 128 | while (! displayConnectionDetails()) { 129 | delay(1000); 130 | } 131 | 132 | /*********************************************************/ 133 | /* You can safely remove this to save some flash memory! */ 134 | /*********************************************************/ 135 | Serial.println(F("\r\nNOTE: This sketch may cause problems with other sketches")); 136 | Serial.println(F("since the .disconnect() function is never called, so the")); 137 | Serial.println(F("AP may refuse connection requests from the CC3000 until a")); 138 | Serial.println(F("timeout period passes. This is normal behaviour since")); 139 | Serial.println(F("there isn't an obvious moment to disconnect with a server.\r\n")); 140 | 141 | // Start listening for connections 142 | echoServer.begin(); 143 | 144 | Serial.println(F("Listening for connections...")); 145 | } 146 | 147 | void loop(void) 148 | { 149 | // Try to get a client which is connected. 150 | Adafruit_CC3000_ClientRef client = echoServer.available(); 151 | if (client) { 152 | // Check if there is data available to read. 153 | if (client.available() > 0) { 154 | // Read a byte and write it to all clients. 155 | uint8_t ch = client.read(); 156 | client.write(ch); 157 | } 158 | } 159 | } 160 | 161 | /**************************************************************************/ 162 | /*! 163 | @brief Tries to read the IP address and other connection details 164 | */ 165 | /**************************************************************************/ 166 | bool displayConnectionDetails(void) 167 | { 168 | uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv; 169 | 170 | if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv)) 171 | { 172 | Serial.println(F("Unable to retrieve the IP Address!\r\n")); 173 | return false; 174 | } 175 | else 176 | { 177 | Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress); 178 | Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask); 179 | Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway); 180 | Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv); 181 | Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv); 182 | Serial.println(); 183 | return true; 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /Adafruit_CC3000.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************/ 2 | /*! 3 | @file Adafruit_CC3000.h 4 | @author KTOWN (Kevin Townsend for Adafruit Industries) 5 | @license BSD (see license.txt) 6 | 7 | This is a library for the Adafruit CC3000 WiFi breakout board 8 | This library works with the Adafruit CC3000 breakout 9 | ----> https://www.adafruit.com/products/1469 10 | 11 | Check out the links above for our tutorials and wiring diagrams 12 | These chips use SPI to communicate. 13 | 14 | Adafruit invests time and resources providing this open source code, 15 | please support Adafruit and open-source hardware by purchasing 16 | products from Adafruit! 17 | */ 18 | /**************************************************************************/ 19 | 20 | #ifndef ADAFRUIT_CC3000_H 21 | #define ADAFRUIT_CC3000_H 22 | 23 | #if ARDUINO >= 100 24 | #include "Arduino.h" 25 | #else 26 | #include "WProgram.h" 27 | #endif 28 | #include "utility/cc3000_common.h" 29 | #include "utility/wlan.h" 30 | #include "utility/netapp.h" 31 | #include "ccspi.h" 32 | #include "Client.h" 33 | 34 | #if defined(__arm__) && defined(__SAM3X8E__) // Arduino Due 35 | #define SPI_CLOCK_DIVIDER 6 // used to set the speed for the SPI bus; 6 == 14 Mhz on the Arduino Due 36 | #else 37 | #define SPI_CLOCK_DIVIDER SPI_CLOCK_DIV2 // Don't set this to a slower speed (i.e. larger div value) 38 | // or communication will be flakey on 16mhz chips! 39 | #endif 40 | 41 | //#define ENABLE_CC3K_PRINTER 42 | 43 | #ifdef ENABLE_CC3K_PRINTER 44 | #define CHECK_PRINTER if(CC3KPrinter != 0) 45 | #else 46 | #define CHECK_PRINTER if(false) 47 | #endif 48 | 49 | #if defined(UDR0) || defined(UDR1) || defined(CORE_TEENSY) || ( defined (__arm__) && defined (__SAM3X8E__) ) 50 | #define CC3K_DEFAULT_PRINTER &Serial 51 | #else 52 | #define CC3K_DEFAULT_PRINTER 0 53 | #endif 54 | 55 | #define SMART_CONFIG_TIMEOUT 60000 // how long to wait for smart config to complete 56 | #define WLAN_CONNECT_TIMEOUT 10000 // how long to wait, in milliseconds 57 | #define RXBUFFERSIZE 64 // how much to buffer on the incoming side 58 | #define TXBUFFERSIZE 32 // how much to buffer on the outgoing side 59 | 60 | #define WIFI_ENABLE 1 61 | #define WIFI_DISABLE 0 62 | #define WIFI_STATUS_CONNECTED 1 63 | 64 | typedef struct Result_Struct 65 | { 66 | uint32_t num_networks; 67 | uint32_t scan_status; 68 | uint8_t rssiByte; 69 | uint8_t Sec_ssidLen; 70 | uint16_t time; 71 | uint8_t ssid_name[32]; 72 | uint8_t bssid[6]; 73 | } ResultStruct_t; /**!ResultStruct_t : data struct to store SSID scan results */ 74 | 75 | /* Enum for wlan_ioctl_statusget results */ 76 | typedef enum 77 | { 78 | STATUS_DISCONNECTED = 0, 79 | STATUS_SCANNING = 1, 80 | STATUS_CONNECTING = 2, 81 | STATUS_CONNECTED = 3 82 | } status_t; 83 | 84 | class Adafruit_CC3000; 85 | 86 | class Adafruit_CC3000_Client : public Client { 87 | public: 88 | Adafruit_CC3000_Client(int32_t s); 89 | Adafruit_CC3000_Client(void); 90 | Adafruit_CC3000_Client(const Adafruit_CC3000_Client& copy); 91 | void operator=(const Adafruit_CC3000_Client& other); 92 | 93 | // NOTE: If public functions below are added/modified/removed please make sure to update the 94 | // Adafruit_CC3000_ClientRef class to match! 95 | 96 | int connect(IPAddress ip, uint16_t port); 97 | int connect(const char *host, uint16_t port); 98 | 99 | uint8_t connected(void); 100 | size_t write(uint8_t c); 101 | 102 | size_t fastrprint(const char *str); 103 | size_t fastrprintln(const char *str); 104 | size_t fastrprint(char *str); 105 | size_t fastrprintln(char *str); 106 | size_t fastrprint(const __FlashStringHelper *ifsh); 107 | size_t fastrprintln(const __FlashStringHelper *ifsh); 108 | 109 | size_t write(const void *buf, uint16_t len, uint32_t flags = 0); 110 | int read(void *buf, uint16_t len, uint32_t flags = 0); 111 | int read(void); 112 | int32_t close(void); 113 | int available(void); 114 | 115 | int read(uint8_t *buf, size_t size); 116 | size_t write(const uint8_t *buf, size_t size); 117 | int peek(); 118 | void flush(); 119 | void stop(); 120 | operator bool(); 121 | 122 | uint8_t _rx_buf[RXBUFFERSIZE], _rx_buf_idx; 123 | int16_t bufsiz; 124 | 125 | private: 126 | int32_t _socket; 127 | 128 | }; 129 | 130 | // Ugly but necessary to include the server header after the client is fully defined. 131 | // A forward reference in the server header won't cut it because the server needs to contain 132 | // instances of the client. The client definition above can be pulled into a separate 133 | // header in a later change to make this cleaner. 134 | #include "Adafruit_CC3000_Server.h" 135 | 136 | class Adafruit_CC3000 { 137 | public: 138 | Adafruit_CC3000(uint8_t csPin, uint8_t irqPin, uint8_t vbatPin, uint8_t spispeed = SPI_CLOCK_DIVIDER, Print* cc3kPrinter = CC3K_DEFAULT_PRINTER); 139 | bool begin(uint8_t patchReq = 0, bool useSmartConfigData = false, const char *_deviceName = NULL); 140 | void reboot(uint8_t patchReq = 0); 141 | void stop(void); 142 | bool disconnect(void); 143 | bool deleteProfiles(void); 144 | void printHex(const byte * data, const uint32_t numBytes); 145 | void printHexChar(const byte * data, const uint32_t numBytes); 146 | void printIPdots(uint32_t ip); 147 | void printIPdotsRev(uint32_t ip); 148 | uint32_t IP2U32(uint8_t a, uint8_t b, uint8_t c, uint8_t d); 149 | bool getMacAddress(uint8_t address[6]); 150 | bool setMacAddress(uint8_t address[6]); 151 | bool setStaticIPAddress(uint32_t ip, uint32_t subnetMask, uint32_t defaultGateway, uint32_t dnsServer); 152 | bool setDHCP(); 153 | 154 | bool connectToAP(const char *ssid, const char *key, uint8_t secmode, uint8_t attempts = 0); 155 | bool connectSecure(const char *ssid, const char *key, int32_t secMode); 156 | bool connectOpen(const char *ssid); 157 | bool checkConnected(void); 158 | bool checkDHCP(void); 159 | bool getIPAddress(uint32_t *retip, uint32_t *netmask, uint32_t *gateway, uint32_t *dhcpserv, uint32_t *dnsserv); 160 | 161 | bool checkSmartConfigFinished(void); 162 | 163 | Adafruit_CC3000_Client connectTCP(uint32_t destIP, uint16_t destPort); 164 | Adafruit_CC3000_Client connectUDP(uint32_t destIP, uint16_t destPort); 165 | 166 | #ifndef CC3000_TINY_DRIVER 167 | bool getFirmwareVersion(uint8_t *major, uint8_t *minor); 168 | status_t getStatus(void); 169 | bool startSSIDscan(uint32_t *index); 170 | void stopSSIDscan(); 171 | uint8_t getNextSSID(uint8_t *rssi, uint8_t *secMode, char *ssidname); 172 | 173 | bool listSSIDResults(void); 174 | bool startSmartConfig(const char *_deviceName = NULL, const char *smartConfigKey = NULL, uint32_t = SMART_CONFIG_TIMEOUT); 175 | bool getIPConfig(tNetappIpconfigRetArgs *ipConfig); 176 | 177 | 178 | uint16_t ping(uint32_t ip, uint8_t attempts=3, uint16_t timeout=500, uint8_t size=32); 179 | uint16_t getHostByName(const char *hostname, uint32_t *ip); 180 | #endif 181 | 182 | /* Functions that aren't available with the tiny driver */ 183 | #ifndef CC3000_TINY_DRIVER 184 | bool scanSSIDs(uint32_t time); 185 | #endif 186 | 187 | void setPrinter(Print*); 188 | 189 | private: 190 | bool _initialised; 191 | 192 | }; 193 | 194 | extern Print* CC3KPrinter; 195 | 196 | #endif 197 | -------------------------------------------------------------------------------- /utility/cc3000_common.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * cc3000_common.c.c - CC3000 Host Driver Implementation. 4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 5 | * 6 | * Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) 7 | * & Limor Fried for Adafruit Industries 8 | * This library works with the Adafruit CC3000 breakout 9 | * ----> https://www.adafruit.com/products/1469 10 | * Adafruit invests time and resources providing this open source code, 11 | * please support Adafruit and open-source hardware by purchasing 12 | * products from Adafruit! 13 | * 14 | * Redistribution and use in source and binary forms, with or without 15 | * modification, are permitted provided that the following conditions 16 | * are met: 17 | * 18 | * Redistributions of source code must retain the above copyright 19 | * notice, this list of conditions and the following disclaimer. 20 | * 21 | * Redistributions in binary form must reproduce the above copyright 22 | * notice, this list of conditions and the following disclaimer in the 23 | * documentation and/or other materials provided with the 24 | * distribution. 25 | * 26 | * Neither the name of Texas Instruments Incorporated nor the names of 27 | * its contributors may be used to endorse or promote products derived 28 | * from this software without specific prior written permission. 29 | * 30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 33 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 34 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 35 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 36 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 37 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 38 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 39 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 40 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 | * 42 | *****************************************************************************/ 43 | //***************************************************************************** 44 | // 45 | //! \addtogroup common_api 46 | //! @{ 47 | // 48 | //***************************************************************************** 49 | /****************************************************************************** 50 | * 51 | * Include files 52 | * 53 | *****************************************************************************/ 54 | #include "cc3000_common.h" 55 | #include "socket.h" 56 | #include "wlan.h" 57 | #include "evnt_handler.h" 58 | // Adafruit CC3k Host Driver Difference 59 | // Include our own debug header & root Arduino header. 60 | // Noted 12-12-2014 by tdicola 61 | #include "debug.h" 62 | #include 63 | 64 | //***************************************************************************** 65 | // 66 | //! __error__ 67 | //! 68 | //! @param pcFilename - file name, where error occurred 69 | //! @param ulLine - line number, where error occurred 70 | //! 71 | //! @return none 72 | //! 73 | //! @brief stub function for ASSERT macro 74 | // 75 | //***************************************************************************** 76 | void __error__(CHAR *pcFilename, UINT32 ulLine) 77 | { 78 | //TODO full up function 79 | } 80 | 81 | 82 | 83 | //***************************************************************************** 84 | // 85 | //! UINT32_TO_STREAM_f 86 | //! 87 | //! @param p pointer to the new stream 88 | //! @param u32 pointer to the 32 bit 89 | //! 90 | //! @return pointer to the new stream 91 | //! 92 | //! @brief This function is used for copying 32 bit to stream 93 | //! while converting to little endian format. 94 | // 95 | //***************************************************************************** 96 | 97 | UINT8* UINT32_TO_STREAM_f (UINT8 *p, UINT32 u32) 98 | { 99 | *(p)++ = (UINT8)(u32); 100 | *(p)++ = (UINT8)((u32) >> 8); 101 | *(p)++ = (UINT8)((u32) >> 16); 102 | *(p)++ = (UINT8)((u32) >> 24); 103 | return p; 104 | } 105 | 106 | //***************************************************************************** 107 | // 108 | //! UINT16_TO_STREAM_f 109 | //! 110 | //! @param p pointer to the new stream 111 | //! @param u32 pointer to the 16 bit 112 | //! 113 | //! @return pointer to the new stream 114 | //! 115 | //! @brief This function is used for copying 16 bit to stream 116 | //! while converting to little endian format. 117 | // 118 | //***************************************************************************** 119 | 120 | UINT8* UINT16_TO_STREAM_f (UINT8 *p, UINT16 u16) 121 | { 122 | *(p)++ = (UINT8)(u16); 123 | *(p)++ = (UINT8)((u16) >> 8); 124 | return p; 125 | } 126 | 127 | //***************************************************************************** 128 | // 129 | //! STREAM_TO_UINT16_f 130 | //! 131 | //! @param p pointer to the stream 132 | //! @param offset offset in the stream 133 | //! 134 | //! @return pointer to the new 16 bit 135 | //! 136 | //! @brief This function is used for copying received stream to 137 | //! 16 bit in little endian format. 138 | // 139 | //***************************************************************************** 140 | 141 | UINT16 STREAM_TO_UINT16_f(CHAR* cp, UINT16 offset) 142 | { 143 | // Adafruit CC3k Host Driver Difference 144 | // Explicit cast to UINT8 pointer is required or decoding parameters breaks on Arduino. 145 | // Noted 12-12-2014 by tdicola 146 | UINT8 *p = (UINT8 *)cp; 147 | /* 148 | DEBUGPRINT_F("Stream2u16: "); 149 | DEBUGPRINT_HEX(cp[offset+1]); 150 | DEBUGPRINT_F(" + "); 151 | DEBUGPRINT_HEX(cp[offset]); 152 | DEBUGPRINT_F("\n\r"); 153 | */ 154 | 155 | return (UINT16)((UINT16)((UINT16) 156 | (*(p + offset + 1)) << 8) + (UINT16)(*(p + offset))); 157 | } 158 | 159 | //***************************************************************************** 160 | // 161 | //! STREAM_TO_UINT32_f 162 | //! 163 | //! @param p pointer to the stream 164 | //! @param offset offset in the stream 165 | //! 166 | //! @return pointer to the new 32 bit 167 | //! 168 | //! @brief This function is used for copying received stream to 169 | //! 32 bit in little endian format. 170 | // 171 | //***************************************************************************** 172 | 173 | UINT32 STREAM_TO_UINT32_f(CHAR* cp, UINT16 offset) 174 | { 175 | // Adafruit CC3k Host Driver Difference 176 | // Explicit cast to UINT8 pointer is required or decoding parameters breaks on Arduino. 177 | // Noted 12-12-2014 by tdicola 178 | UINT8 *p = (UINT8 *)cp; 179 | 180 | /* 181 | DEBUGPRINT_F("\tStream2u32: "); 182 | DEBUGPRINT_HEX(cp[offset+3]); DEBUGPRINT_F(" + "); 183 | DEBUGPRINT_HEX(cp[offset+2]); DEBUGPRINT_F(" + "); 184 | DEBUGPRINT_HEX(cp[offset+1]); DEBUGPRINT_F(" + "); 185 | DEBUGPRINT_HEX(cp[offset]); 186 | DEBUGPRINT_F("\n\r"); 187 | */ 188 | 189 | return (UINT32)((UINT32)((UINT32) 190 | (*(p + offset + 3)) << 24) + (UINT32)((UINT32) 191 | (*(p + offset + 2)) << 16) + (UINT32)((UINT32) 192 | (*(p + offset + 1)) << 8) + (UINT32)(*(p + offset))); 193 | } 194 | 195 | 196 | 197 | //***************************************************************************** 198 | // 199 | // Close the Doxygen group. 200 | //! @} 201 | // 202 | //***************************************************************************** 203 | -------------------------------------------------------------------------------- /examples/WebClient/WebClient.ino: -------------------------------------------------------------------------------- 1 | /*************************************************** 2 | This is an example for the Adafruit CC3000 Wifi Breakout & Shield 3 | 4 | Designed specifically to work with the Adafruit WiFi products: 5 | ----> https://www.adafruit.com/products/1469 6 | 7 | Adafruit invests time and resources providing this open source code, 8 | please support Adafruit and open-source hardware by purchasing 9 | products from Adafruit! 10 | 11 | Written by Limor Fried & Kevin Townsend for Adafruit Industries. 12 | BSD license, all text above must be included in any redistribution 13 | ****************************************************/ 14 | 15 | /* 16 | This example does a test of the TCP client capability: 17 | * Initialization 18 | * Optional: SSID scan 19 | * AP connection 20 | * DHCP printout 21 | * DNS lookup 22 | * Optional: Ping 23 | * Connect to website and print out webpage contents 24 | * Disconnect 25 | SmartConfig is still beta and kind of works but is not fully vetted! 26 | It might not work on all networks! 27 | */ 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include "utility/debug.h" 33 | 34 | // These are the interrupt and control pins 35 | #define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin! 36 | // These can be any two pins 37 | #define ADAFRUIT_CC3000_VBAT 5 38 | #define ADAFRUIT_CC3000_CS 10 39 | // Use hardware SPI for the remaining pins 40 | // On an UNO, SCK = 13, MISO = 12, and MOSI = 11 41 | Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, 42 | SPI_CLOCK_DIVIDER); // you can change this clock speed 43 | 44 | #define WLAN_SSID "myNetwork" // cannot be longer than 32 characters! 45 | #define WLAN_PASS "myPassword" 46 | // Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2 47 | #define WLAN_SECURITY WLAN_SEC_WPA2 48 | 49 | #define IDLE_TIMEOUT_MS 3000 // Amount of time to wait (in milliseconds) with no data 50 | // received before closing the connection. If you know the server 51 | // you're accessing is quick to respond, you can reduce this value. 52 | 53 | // What page to grab! 54 | #define WEBSITE "wifitest.adafruit.com" 55 | #define WEBPAGE "/testwifi/index.html" 56 | 57 | 58 | /**************************************************************************/ 59 | /*! 60 | @brief Sets up the HW and the CC3000 module (called automatically 61 | on startup) 62 | */ 63 | /**************************************************************************/ 64 | 65 | uint32_t ip; 66 | 67 | void setup(void) 68 | { 69 | Serial.begin(115200); 70 | Serial.println(F("Hello, CC3000!\n")); 71 | 72 | Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC); 73 | 74 | /* Initialise the module */ 75 | Serial.println(F("\nInitializing...")); 76 | if (!cc3000.begin()) 77 | { 78 | Serial.println(F("Couldn't begin()! Check your wiring?")); 79 | while(1); 80 | } 81 | 82 | // Optional SSID scan 83 | // listSSIDResults(); 84 | 85 | Serial.print(F("\nAttempting to connect to ")); Serial.println(WLAN_SSID); 86 | if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) { 87 | Serial.println(F("Failed!")); 88 | while(1); 89 | } 90 | 91 | Serial.println(F("Connected!")); 92 | 93 | /* Wait for DHCP to complete */ 94 | Serial.println(F("Request DHCP")); 95 | while (!cc3000.checkDHCP()) 96 | { 97 | delay(100); // ToDo: Insert a DHCP timeout! 98 | } 99 | 100 | /* Display the IP address DNS, Gateway, etc. */ 101 | while (! displayConnectionDetails()) { 102 | delay(1000); 103 | } 104 | 105 | ip = 0; 106 | // Try looking up the website's IP address 107 | Serial.print(WEBSITE); Serial.print(F(" -> ")); 108 | while (ip == 0) { 109 | if (! cc3000.getHostByName(WEBSITE, &ip)) { 110 | Serial.println(F("Couldn't resolve!")); 111 | } 112 | delay(500); 113 | } 114 | 115 | cc3000.printIPdotsRev(ip); 116 | 117 | // Optional: Do a ping test on the website 118 | /* 119 | Serial.print(F("\n\rPinging ")); cc3000.printIPdotsRev(ip); Serial.print("..."); 120 | replies = cc3000.ping(ip, 5); 121 | Serial.print(replies); Serial.println(F(" replies")); 122 | */ 123 | 124 | /* Try connecting to the website. 125 | Note: HTTP/1.1 protocol is used to keep the server from closing the connection before all data is read. 126 | */ 127 | Adafruit_CC3000_Client www = cc3000.connectTCP(ip, 80); 128 | if (www.connected()) { 129 | www.fastrprint(F("GET ")); 130 | www.fastrprint(WEBPAGE); 131 | www.fastrprint(F(" HTTP/1.1\r\n")); 132 | www.fastrprint(F("Host: ")); www.fastrprint(WEBSITE); www.fastrprint(F("\r\n")); 133 | www.fastrprint(F("\r\n")); 134 | www.println(); 135 | } else { 136 | Serial.println(F("Connection failed")); 137 | return; 138 | } 139 | 140 | Serial.println(F("-------------------------------------")); 141 | 142 | /* Read data until either the connection is closed, or the idle timeout is reached. */ 143 | unsigned long lastRead = millis(); 144 | while (www.connected() && (millis() - lastRead < IDLE_TIMEOUT_MS)) { 145 | while (www.available()) { 146 | char c = www.read(); 147 | Serial.print(c); 148 | lastRead = millis(); 149 | } 150 | } 151 | www.close(); 152 | Serial.println(F("-------------------------------------")); 153 | 154 | /* You need to make sure to clean up after yourself or the CC3000 can freak out */ 155 | /* the next time your try to connect ... */ 156 | Serial.println(F("\n\nDisconnecting")); 157 | cc3000.disconnect(); 158 | 159 | } 160 | 161 | void loop(void) 162 | { 163 | delay(1000); 164 | } 165 | 166 | /**************************************************************************/ 167 | /*! 168 | @brief Begins an SSID scan and prints out all the visible networks 169 | */ 170 | /**************************************************************************/ 171 | 172 | void listSSIDResults(void) 173 | { 174 | uint32_t index; 175 | uint8_t valid, rssi, sec; 176 | char ssidname[33]; 177 | 178 | if (!cc3000.startSSIDscan(&index)) { 179 | Serial.println(F("SSID scan failed!")); 180 | return; 181 | } 182 | 183 | Serial.print(F("Networks found: ")); Serial.println(index); 184 | Serial.println(F("================================================")); 185 | 186 | while (index) { 187 | index--; 188 | 189 | valid = cc3000.getNextSSID(&rssi, &sec, ssidname); 190 | 191 | Serial.print(F("SSID Name : ")); Serial.print(ssidname); 192 | Serial.println(); 193 | Serial.print(F("RSSI : ")); 194 | Serial.println(rssi); 195 | Serial.print(F("Security Mode: ")); 196 | Serial.println(sec); 197 | Serial.println(); 198 | } 199 | Serial.println(F("================================================")); 200 | 201 | cc3000.stopSSIDscan(); 202 | } 203 | 204 | /**************************************************************************/ 205 | /*! 206 | @brief Tries to read the IP address and other connection details 207 | */ 208 | /**************************************************************************/ 209 | bool displayConnectionDetails(void) 210 | { 211 | uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv; 212 | 213 | if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv)) 214 | { 215 | Serial.println(F("Unable to retrieve the IP Address!\r\n")); 216 | return false; 217 | } 218 | else 219 | { 220 | Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress); 221 | Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask); 222 | Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway); 223 | Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv); 224 | Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv); 225 | Serial.println(); 226 | return true; 227 | } 228 | } 229 | -------------------------------------------------------------------------------- /examples/SmartConfigCreate/SmartConfigCreate.ino: -------------------------------------------------------------------------------- 1 | /*************************************************** 2 | This is an example for the Adafruit CC3000 Wifi Breakout & Shield 3 | 4 | Designed specifically to work with the Adafruit WiFi products: 5 | ----> https://www.adafruit.com/products/1469 6 | 7 | Adafruit invests time and resources providing this open source code, 8 | please support Adafruit and open-source hardware by purchasing 9 | products from Adafruit! 10 | 11 | Written by Limor Fried & Kevin Townsend for Adafruit Industries. 12 | BSD license, all text above must be included in any redistribution 13 | ****************************************************/ 14 | 15 | /* This sketch will attempt to establish an AP connection 16 | using the SmartConfig tool, and save the connection 17 | details for later use (with SmartConfigReconnect, etc.). 18 | 19 | If a connection is successfully established, the data 20 | will be stored as a connection profile in non-volatile 21 | memory on the CC3000, and the device will be configured 22 | to automatically connect to this profile on startup. 23 | 24 | To see how to safely use the CC3000 without erasing 25 | this SmartConfig data please consult the 26 | SmartConfigReconnect sketch, which uses an optional flag 27 | in Adafruit_CC3000.begin() to avoid erasing the 28 | connection profiles from memory, as well as a new 29 | .reconnect function. 30 | 31 | Using other non SmartConfig example sketches will 32 | erase the connection profile data on startup, but 33 | this sketch combined with SmartConfigReconnect hopefully 34 | illustrate how to use SmartConfig when hard-coded 35 | connection details aren't appropriate. 36 | 37 | SmartConfig is still beta and kind of works but is not fully 38 | vetted! It might not work on all networks! 39 | */ 40 | 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include "utility/debug.h" 46 | 47 | // These are the interrupt and control pins 48 | #define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin! 49 | // These can be any two pins 50 | #define ADAFRUIT_CC3000_VBAT 5 51 | #define ADAFRUIT_CC3000_CS 10 52 | 53 | #define DEVICE_NAME "CC3000" 54 | 55 | // Use hardware SPI for the remaining pins 56 | // On an UNO, SCK = 13, MISO = 12, and MOSI = 11 57 | Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, 58 | ADAFRUIT_CC3000_IRQ, 59 | ADAFRUIT_CC3000_VBAT, 60 | SPI_CLOCK_DIVIDER); 61 | 62 | // The SSID & Password are retrieved via the Smartconfig app 63 | 64 | /**************************************************************************/ 65 | /*! 66 | @brief Sets up the HW and the CC3000 module (called automatically 67 | on startup) 68 | */ 69 | /**************************************************************************/ 70 | void setup(void) 71 | { 72 | Serial.begin(115200); 73 | Serial.println(F("Hello, CC3000!\n")); 74 | 75 | displayDriverMode(); 76 | Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC); 77 | 78 | /* Initialise the module, deleting any existing profile data (which */ 79 | /* is the default behaviour) */ 80 | Serial.println(F("\nInitialising the CC3000 ...")); 81 | if (!cc3000.begin(false)) 82 | { 83 | Serial.println(F("Unable to initialise the CC3000! Check your wiring?")); 84 | while(1); 85 | } 86 | 87 | uint16_t firmware = checkFirmwareVersion(); 88 | if (firmware < 0x113) { 89 | Serial.println(F("Wrong firmware version!")); 90 | for(;;); 91 | } 92 | displayMACAddress(); 93 | 94 | /* Try to use the smart config app (no AES encryption), saving */ 95 | /* the connection details if we succeed */ 96 | Serial.println(F("Waiting for a SmartConfig connection (~60s) ...")); 97 | if (!cc3000.startSmartConfig(DEVICE_NAME)) 98 | { 99 | Serial.println(F("SmartConfig failed")); 100 | while(1); 101 | } 102 | 103 | Serial.println(F("Saved connection details and connected to AP!")); 104 | 105 | /* Wait for DHCP to complete */ 106 | Serial.println(F("Request DHCP")); 107 | while (!cc3000.checkDHCP()) 108 | { 109 | delay(100); // ToDo: Insert a DHCP timeout! 110 | } 111 | 112 | /* Display the IP address DNS, Gateway, etc. */ 113 | while (! displayConnectionDetails()) { 114 | delay(1000); 115 | } 116 | 117 | Serial.println(F("\nTo use these connection details be sure to use")); 118 | Serial.println(F("'.begin(false, true, DEVICE_NAME)' with your Adafruit_CC3000")); 119 | Serial.println(F("code instead of the default '.begin()' values!")); 120 | 121 | /* You need to make sure to clean up after yourself or the CC3000 can freak out */ 122 | /* the next time your try to connect ... */ 123 | Serial.println(F("\nClosing the connection")); 124 | cc3000.disconnect(); 125 | } 126 | 127 | void loop(void) 128 | { 129 | delay(1000); 130 | } 131 | 132 | 133 | /**************************************************************************/ 134 | /*! 135 | @brief Displays the driver mode (tiny of normal), and the buffer 136 | size if tiny mode is not being used 137 | 138 | @note The buffer size and driver mode are defined in cc3000_common.h 139 | */ 140 | /**************************************************************************/ 141 | void displayDriverMode(void) 142 | { 143 | #ifdef CC3000_TINY_DRIVER 144 | Serial.println(F("CC3000 is configure in 'Tiny' mode")); 145 | #else 146 | Serial.print(F("RX Buffer : ")); 147 | Serial.print(CC3000_RX_BUFFER_SIZE); 148 | Serial.println(F(" bytes")); 149 | Serial.print(F("TX Buffer : ")); 150 | Serial.print(CC3000_TX_BUFFER_SIZE); 151 | Serial.println(F(" bytes")); 152 | #endif 153 | } 154 | 155 | /**************************************************************************/ 156 | /*! 157 | @brief Tries to read the CC3000's internal firmware patch ID 158 | */ 159 | /**************************************************************************/ 160 | uint16_t checkFirmwareVersion(void) 161 | { 162 | uint8_t major, minor; 163 | uint16_t version; 164 | 165 | #ifndef CC3000_TINY_DRIVER 166 | if(!cc3000.getFirmwareVersion(&major, &minor)) 167 | { 168 | Serial.println(F("Unable to retrieve the firmware version!\r\n")); 169 | version = 0; 170 | } 171 | else 172 | { 173 | Serial.print(F("Firmware V. : ")); 174 | Serial.print(major); Serial.print(F(".")); Serial.println(minor); 175 | version = major; version <<= 8; version |= minor; 176 | } 177 | #endif 178 | return version; 179 | } 180 | 181 | /**************************************************************************/ 182 | /*! 183 | @brief Tries to read the 6-byte MAC address of the CC3000 module 184 | */ 185 | /**************************************************************************/ 186 | void displayMACAddress(void) 187 | { 188 | uint8_t macAddress[6]; 189 | 190 | if(!cc3000.getMacAddress(macAddress)) 191 | { 192 | Serial.println(F("Unable to retrieve MAC Address!\r\n")); 193 | } 194 | else 195 | { 196 | Serial.print(F("MAC Address : ")); 197 | cc3000.printHex((byte*)&macAddress, 6); 198 | } 199 | } 200 | 201 | /**************************************************************************/ 202 | /*! 203 | @brief Tries to read the IP address and other connection details 204 | */ 205 | /**************************************************************************/ 206 | bool displayConnectionDetails(void) 207 | { 208 | uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv; 209 | 210 | if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv)) 211 | { 212 | Serial.println(F("Unable to retrieve the IP Address!\r\n")); 213 | return false; 214 | } 215 | else 216 | { 217 | Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress); 218 | Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask); 219 | Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway); 220 | Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv); 221 | Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv); 222 | Serial.println(); 223 | return true; 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /examples/ntpTest/ntpTest.ino: -------------------------------------------------------------------------------- 1 | /*************************************************** 2 | This is an example for the Adafruit CC3000 Wifi Breakout & Shield 3 | 4 | Designed specifically to work with the Adafruit WiFi products: 5 | ----> https://www.adafruit.com/products/1469 6 | 7 | Adafruit invests time and resources providing this open source code, 8 | please support Adafruit and open-source hardware by purchasing 9 | products from Adafruit! 10 | 11 | Written by Kevin Townsend & Limor Fried & Rick Lesniak for Adafruit Industries. 12 | BSD license, all text above must be included in any redistribution 13 | ****************************************************/ 14 | 15 | /* 16 | 17 | This example does a test of the SNTP (Simple Network Time Protocol) client: 18 | * Initialization 19 | * SSID Scan 20 | * AP connection 21 | * DHCP printout 22 | * SNTP time synchronization 23 | * Extract and print current time and date information 24 | 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | //#include "utility/NetTime.h" 31 | #include 32 | #include "utility/debug.h" 33 | #include "sntp.h" 34 | 35 | // These are the interrupt and control pins 36 | #define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin! 37 | // These can be any two pins 38 | #define ADAFRUIT_CC3000_VBAT 5 39 | #define ADAFRUIT_CC3000_CS 10 40 | // Use hardware SPI for the remaining pins 41 | // On an UNO, SCK = 13, MISO = 12, and MOSI = 11 42 | Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, 43 | SPI_CLOCK_DIVIDER); // you can change this clock speed but DI 44 | 45 | #define WLAN_SSID "myNetwork" // cannot be longer than 32 characters! 46 | #define WLAN_PASS "myPassword" 47 | // Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2 48 | #define WLAN_SECURITY WLAN_SEC_WPA2 49 | 50 | //Arguments to SNTP client constructor: 51 | // 1 - Primary Network Time Server URL (can be NULL) 52 | // 2 - Secondary Network Time Server URL (also can be NULL) 53 | // 3 - Local UTC offset in minutes (US Eastern Time is UTC - 5:00 54 | // 4 - Local UTC offset in minutes for Daylight Savings Time (US Eastern DST is UTC - 4:00 55 | // 5 - Enable Daylight Savings Time adjustment (not implemented yet) 56 | // 57 | sntp mysntp = sntp(NULL, "time.nist.gov", (short)(-5 * 60), (short)(-4 * 60), true); 58 | 59 | // Type SNTP_Timestamp is 64-bit NTP time. High-order 32-bits is seconds since 1/1/1900 60 | // Low order 32-bits is fractional seconds 61 | SNTP_Timestamp_t now; 62 | 63 | // Type NetTime_t contains NTP time broken out to human-oriented values: 64 | // uint16_t millis; ///< Milliseconds after the second (0..999) 65 | // uint8_t sec; ///< Seconds after the minute (0..59) 66 | // uint8_t min; ///< Minutes after the hour (0..59) 67 | // uint8_t hour; ///< Hours since midnight (0..23) 68 | // uint8_t mday; ///< Day of the month (1..31) 69 | // uint8_t mon; ///< Months since January (0..11) 70 | // uint16_t year; ///< Year. 71 | // uint8_t wday; ///< Days since Sunday (0..6) 72 | // uint8_t yday; ///< Days since January 1 (0..365) 73 | // bool isdst; ///< Daylight savings time flag, currently not supported 74 | NetTime_t timeExtract; 75 | 76 | #define pF(string_pointer) (reinterpret_cast(pgm_read_word(string_pointer))) 77 | 78 | const prog_char janStr[] PROGMEM = "January"; 79 | const prog_char febStr[] PROGMEM = "February"; 80 | const prog_char marStr[] PROGMEM = "March"; 81 | const prog_char aprStr[] PROGMEM = "April"; 82 | const prog_char mayStr[] PROGMEM = "May"; 83 | const prog_char junStr[] PROGMEM = "June"; 84 | const prog_char julStr[] PROGMEM = "July"; 85 | const prog_char augStr[] PROGMEM = "August"; 86 | const prog_char sepStr[] PROGMEM = "September"; 87 | const prog_char octStr[] PROGMEM = "October"; 88 | const prog_char novStr[] PROGMEM = "November"; 89 | const prog_char decStr[] PROGMEM = "December"; 90 | 91 | PROGMEM const char* const monthStrs[] = { janStr, febStr, marStr, aprStr, mayStr, junStr, 92 | julStr, augStr, sepStr, octStr, novStr, decStr}; 93 | 94 | const prog_char sunStr[] PROGMEM = "Sunday"; 95 | const prog_char monStr[] PROGMEM = "Monday"; 96 | const prog_char tueStr[] PROGMEM = "Tuesday"; 97 | const prog_char wedStr[] PROGMEM = "Wednesday"; 98 | const prog_char thuStr[] PROGMEM = "Thursday"; 99 | const prog_char friStr[] PROGMEM = "Friday"; 100 | const prog_char satStr[] PROGMEM = "Saturday"; 101 | 102 | PROGMEM const char* const dayStrs[] = { sunStr, monStr, tueStr, wedStr, 103 | thuStr, friStr, satStr}; 104 | 105 | 106 | /**************************************************************************/ 107 | /*! 108 | @brief Sets up the HW and the CC3000 module (called automatically 109 | on startup) 110 | */ 111 | /**************************************************************************/ 112 | void setup(void) 113 | { 114 | Serial.begin(115200); 115 | Serial.println(F("Hello, CC3000!\n")); 116 | 117 | Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC); 118 | 119 | 120 | /* Initialise the module */ 121 | Serial.println(F("\nInitialising the CC3000 ...")); 122 | if (!cc3000.begin()) 123 | { 124 | Serial.println(F("Unable to initialise the CC3000! Check your wiring?")); 125 | while(1); 126 | } 127 | 128 | /* Optional: Update the Mac Address to a known value */ 129 | /* 130 | uint8_t macAddress[6] = { 0x08, 0x00, 0x28, 0x01, 0x79, 0xB7 }; 131 | if (!cc3000.setMacAddress(macAddress)) 132 | { 133 | Serial.println(F("Failed trying to update the MAC address")); 134 | while(1); 135 | } 136 | */ 137 | 138 | uint16_t firmware = checkFirmwareVersion(); 139 | if (firmware < 0x113) { 140 | Serial.println(F("Wrong firmware version!")); 141 | for(;;); 142 | } 143 | 144 | /* Delete any old connection data on the module */ 145 | Serial.println(F("\nDeleting old connection profiles")); 146 | if (!cc3000.deleteProfiles()) { 147 | Serial.println(F("Failed!")); 148 | while(1); 149 | } 150 | 151 | /* Attempt to connect to an access point */ 152 | char *ssid = WLAN_SSID; /* Max 32 chars */ 153 | Serial.print(F("\nAttempting to connect to ")); Serial.println(ssid); 154 | 155 | /* NOTE: Secure connections are not available in 'Tiny' mode! */ 156 | if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) { 157 | Serial.println(F("Failed!")); 158 | while(1); 159 | } 160 | 161 | Serial.println(F("Connected!")); 162 | 163 | /* Wait for DHCP to complete */ 164 | Serial.println(F("Request DHCP")); 165 | while (!cc3000.checkDHCP()) 166 | { 167 | delay(100); // ToDo: Insert a DHCP timeout! 168 | } 169 | 170 | Serial.println(F("UpdateNTPTime")); 171 | if (mysntp.UpdateNTPTime()) 172 | { 173 | Serial.println(F("Current local time is:")); 174 | mysntp.ExtractNTPTime(mysntp.NTPGetTime(&now, true), &timeExtract); 175 | 176 | Serial.print(timeExtract.hour); Serial.print(F(":")); Serial.print(timeExtract.min); Serial.print(F(":"));Serial.print(timeExtract.sec); Serial.print(F("."));Serial.println(timeExtract.millis); 177 | Serial.print(pF(&dayStrs[timeExtract.wday])); Serial.print(F(", ")); Serial.print(pF(&monthStrs[timeExtract.mon])); Serial.print(F(" ")); Serial.print(timeExtract.mday); Serial.print(F(", "));Serial.println(timeExtract.year); 178 | Serial.print(F("Day of year: ")); Serial.println(timeExtract.yday + 1); 179 | } 180 | 181 | /* You need to make sure to clean up after yourself or the CC3000 can freak out */ 182 | /* the next time you try to connect ... */ 183 | Serial.println(F("\n\nClosing the connection")); 184 | cc3000.disconnect(); 185 | } 186 | 187 | void loop(void) 188 | { 189 | delay(1000); 190 | } 191 | 192 | 193 | /**************************************************************************/ 194 | /*! 195 | @brief Tries to read the CC3000's internal firmware patch ID 196 | */ 197 | /**************************************************************************/ 198 | uint16_t checkFirmwareVersion(void) 199 | { 200 | uint8_t major, minor; 201 | uint16_t version; 202 | 203 | #ifndef CC3000_TINY_DRIVER 204 | if(!cc3000.getFirmwareVersion(&major, &minor)) 205 | { 206 | Serial.println(F("Unable to retrieve the firmware version!\r\n")); 207 | version = 0; 208 | } 209 | else 210 | { 211 | Serial.print(F("Firmware V. : ")); 212 | Serial.print(major); Serial.print(F(".")); Serial.println(minor); 213 | version = major; version <<= 8; version |= minor; 214 | } 215 | #endif 216 | return version; 217 | } 218 | 219 | -------------------------------------------------------------------------------- /utility/hci.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * hci.c - CC3000 Host Driver Implementation. 4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 5 | * 6 | * Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) 7 | * & Limor Fried for Adafruit Industries 8 | * This library works with the Adafruit CC3000 breakout 9 | * ----> https://www.adafruit.com/products/1469 10 | * Adafruit invests time and resources providing this open source code, 11 | * please support Adafruit and open-source hardware by purchasing 12 | * products from Adafruit! 13 | * 14 | * Redistribution and use in source and binary forms, with or without 15 | * modification, are permitted provided that the following conditions 16 | * are met: 17 | * 18 | * Redistributions of source code must retain the above copyright 19 | * notice, this list of conditions and the following disclaimer. 20 | * 21 | * Redistributions in binary form must reproduce the above copyright 22 | * notice, this list of conditions and the following disclaimer in the 23 | * documentation and/or other materials provided with the 24 | * distribution. 25 | * 26 | * Neither the name of Texas Instruments Incorporated nor the names of 27 | * its contributors may be used to endorse or promote products derived 28 | * from this software without specific prior written permission. 29 | * 30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 33 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 34 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 35 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 36 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 37 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 38 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 39 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 40 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 | * 42 | *****************************************************************************/ 43 | 44 | //***************************************************************************** 45 | // 46 | //! \addtogroup hci_app 47 | //! @{ 48 | // 49 | //***************************************************************************** 50 | 51 | #include "cc3000_common.h" 52 | #include "hci.h" 53 | // Adafruit CC3k Host Driver Difference 54 | // Reference our SPI driver in the parent folder. 55 | // Noted 12-12-2014 by tdicola 56 | #include "../ccspi.h" 57 | #include "evnt_handler.h" 58 | #include "wlan.h" 59 | 60 | #define SL_PATCH_PORTION_SIZE (1000) 61 | 62 | 63 | //***************************************************************************** 64 | // 65 | //! hci_command_send 66 | //! 67 | //! @param usOpcode command operation code 68 | //! @param pucBuff pointer to the command's arguments buffer 69 | //! @param ucArgsLength length of the arguments 70 | //! 71 | //! @return none 72 | //! 73 | //! @brief Initiate an HCI command. 74 | // 75 | //***************************************************************************** 76 | UINT16 hci_command_send(UINT16 usOpcode, UINT8 *pucBuff, UINT8 ucArgsLength) 77 | { 78 | UINT8 *stream; 79 | 80 | stream = (pucBuff + SPI_HEADER_SIZE); 81 | 82 | UINT8_TO_STREAM(stream, HCI_TYPE_CMND); 83 | stream = UINT16_TO_STREAM(stream, usOpcode); 84 | UINT8_TO_STREAM(stream, ucArgsLength); 85 | 86 | //Update the opcode of the event we will be waiting for 87 | SpiWrite(pucBuff, ucArgsLength + SIMPLE_LINK_HCI_CMND_HEADER_SIZE); 88 | 89 | return(0); 90 | } 91 | 92 | //***************************************************************************** 93 | // 94 | //! hci_data_send 95 | //! 96 | //! @param usOpcode command operation code 97 | //! @param ucArgs pointer to the command's arguments buffer 98 | //! @param usArgsLength length of the arguments 99 | //! @param ucTail pointer to the data buffer 100 | //! @param usTailLength buffer length 101 | //! 102 | //! @return none 103 | //! 104 | //! @brief Initiate an HCI data write operation 105 | // 106 | //***************************************************************************** 107 | INT32 hci_data_send(UINT8 ucOpcode, 108 | UINT8 *ucArgs, 109 | UINT16 usArgsLength, 110 | UINT16 usDataLength, 111 | const UINT8 *ucTail, 112 | UINT16 usTailLength) 113 | { 114 | UINT8 *stream; 115 | 116 | stream = ((ucArgs) + SPI_HEADER_SIZE); 117 | 118 | UINT8_TO_STREAM(stream, HCI_TYPE_DATA); 119 | UINT8_TO_STREAM(stream, ucOpcode); 120 | UINT8_TO_STREAM(stream, usArgsLength); 121 | stream = UINT16_TO_STREAM(stream, usArgsLength + usDataLength + usTailLength); 122 | 123 | // Send the packet over the SPI 124 | SpiWrite(ucArgs, SIMPLE_LINK_HCI_DATA_HEADER_SIZE + usArgsLength + usDataLength + usTailLength); 125 | 126 | return(ESUCCESS); 127 | } 128 | 129 | 130 | //***************************************************************************** 131 | // 132 | //! hci_data_command_send 133 | //! 134 | //! @param usOpcode command operation code 135 | //! @param pucBuff pointer to the data buffer 136 | //! @param ucArgsLength arguments length 137 | //! @param ucDataLength data length 138 | //! 139 | //! @return none 140 | //! 141 | //! @brief Prepeare HCI header and initiate an HCI data write operation 142 | // 143 | //***************************************************************************** 144 | void hci_data_command_send(UINT16 usOpcode, UINT8 *pucBuff, UINT8 ucArgsLength,UINT16 ucDataLength) 145 | { 146 | UINT8 *stream = (pucBuff + SPI_HEADER_SIZE); 147 | 148 | UINT8_TO_STREAM(stream, HCI_TYPE_DATA); 149 | UINT8_TO_STREAM(stream, usOpcode); 150 | UINT8_TO_STREAM(stream, ucArgsLength); 151 | stream = UINT16_TO_STREAM(stream, ucArgsLength + ucDataLength); 152 | 153 | // Send the command over SPI on data channel 154 | SpiWrite(pucBuff, ucArgsLength + ucDataLength + SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE); 155 | 156 | return; 157 | } 158 | 159 | //***************************************************************************** 160 | // 161 | //! hci_patch_send 162 | //! 163 | //! @param usOpcode command operation code 164 | //! @param pucBuff pointer to the command's arguments buffer 165 | //! @param patch pointer to patch content buffer 166 | //! @param usDataLength data length 167 | //! 168 | //! @return none 169 | //! 170 | //! @brief Prepeare HCI header and initiate an HCI patch write operation 171 | // 172 | //***************************************************************************** 173 | void hci_patch_send(UINT8 ucOpcode, UINT8 *pucBuff, CHAR *patch, UINT16 usDataLength) 174 | { 175 | UINT8 *data_ptr = (pucBuff + SPI_HEADER_SIZE); 176 | UINT16 usTransLength; 177 | UINT8 *stream = (pucBuff + SPI_HEADER_SIZE); 178 | 179 | UINT8_TO_STREAM(stream, HCI_TYPE_PATCH); 180 | UINT8_TO_STREAM(stream, ucOpcode); 181 | stream = UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE); 182 | 183 | if (usDataLength <= SL_PATCH_PORTION_SIZE) 184 | { 185 | UINT16_TO_STREAM(stream, usDataLength); 186 | stream = UINT16_TO_STREAM(stream, usDataLength); 187 | memcpy((pucBuff + SPI_HEADER_SIZE) + HCI_PATCH_HEADER_SIZE, patch, usDataLength); 188 | 189 | // Update the opcode of the event we will be waiting for 190 | SpiWrite(pucBuff, usDataLength + HCI_PATCH_HEADER_SIZE); 191 | } 192 | else 193 | { 194 | 195 | usTransLength = (usDataLength/SL_PATCH_PORTION_SIZE); 196 | UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE + usTransLength*SIMPLE_LINK_HCI_PATCH_HEADER_SIZE); 197 | stream = UINT16_TO_STREAM(stream, SL_PATCH_PORTION_SIZE); 198 | memcpy(pucBuff + SPI_HEADER_SIZE + HCI_PATCH_HEADER_SIZE, patch, SL_PATCH_PORTION_SIZE); 199 | usDataLength -= SL_PATCH_PORTION_SIZE; 200 | patch += SL_PATCH_PORTION_SIZE; 201 | 202 | // Update the opcode of the event we will be waiting for 203 | SpiWrite(pucBuff, SL_PATCH_PORTION_SIZE + HCI_PATCH_HEADER_SIZE); 204 | 205 | while (usDataLength) 206 | { 207 | // Adafruit CC3k Host Driver Difference 208 | // Check for missed interrupt to try to make code more reliable. 209 | // Noted 12-12-2014 by tdicola 210 | cc3k_int_poll(); 211 | 212 | if (usDataLength <= SL_PATCH_PORTION_SIZE) 213 | { 214 | usTransLength = usDataLength; 215 | usDataLength = 0; 216 | 217 | } 218 | else 219 | { 220 | usTransLength = SL_PATCH_PORTION_SIZE; 221 | usDataLength -= usTransLength; 222 | } 223 | 224 | *(UINT16 *)data_ptr = usTransLength; 225 | memcpy(data_ptr + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE, patch, usTransLength); 226 | patch += usTransLength; 227 | 228 | // Update the opcode of the event we will be waiting for 229 | SpiWrite((UINT8 *)data_ptr, usTransLength + sizeof(usTransLength)); 230 | } 231 | } 232 | } 233 | 234 | //***************************************************************************** 235 | // 236 | // Close the Doxygen group. 237 | //! @} 238 | // 239 | // 240 | //***************************************************************************** 241 | -------------------------------------------------------------------------------- /examples/InternetTime/InternetTime.ino: -------------------------------------------------------------------------------- 1 | /*************************************************** 2 | This is an example for the Adafruit CC3000 Wifi Breakout & Shield 3 | 4 | Designed specifically to work with the Adafruit WiFi products: 5 | ----> https://www.adafruit.com/products/1469 6 | 7 | Adafruit invests time and resources providing this open source code, 8 | please support Adafruit and open-source hardware by purchasing 9 | products from Adafruit! 10 | 11 | Written by Limor Fried, Kevin Townsend and Phil Burgess for 12 | Adafruit Industries. BSD license, all text above must be included 13 | in any redistribution 14 | ****************************************************/ 15 | 16 | /* 17 | This example queries an NTP time server to get the current "UNIX time" 18 | (seconds since 1/1/1970, UTC (GMT)), then uses the Arduino's internal 19 | timer to keep relative time. The clock is re-synchronized roughly 20 | once per day. This minimizes NTP server misuse/abuse. 21 | 22 | The RTClib library (a separate download, and not used here) contains 23 | functions to convert UNIX time to other formats if needed. 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | // These are the interrupt and control pins 31 | #define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin! 32 | // These can be any two pins 33 | #define ADAFRUIT_CC3000_VBAT 5 34 | #define ADAFRUIT_CC3000_CS 10 35 | // Use hardware SPI for the remaining pins 36 | // On an UNO, SCK = 13, MISO = 12, and MOSI = 11 37 | Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, 38 | SPI_CLOCK_DIVIDER); // you can change this clock speed but DI 39 | 40 | #define WLAN_SSID "myNetwork" // cannot be longer than 32 characters! 41 | #define WLAN_PASS "myPassword" 42 | // Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2 43 | #define WLAN_SECURITY WLAN_SEC_WPA2 44 | 45 | Adafruit_CC3000_Client client; 46 | 47 | const unsigned long 48 | connectTimeout = 15L * 1000L, // Max time to wait for server connection 49 | responseTimeout = 15L * 1000L; // Max time to wait for data from server 50 | int 51 | countdown = 0; // loop() iterations until next time server query 52 | unsigned long 53 | lastPolledTime = 0L, // Last value retrieved from time server 54 | sketchTime = 0L; // CPU milliseconds since last server query 55 | 56 | 57 | void setup(void) 58 | { 59 | Serial.begin(115200); 60 | Serial.println(F("Hello, CC3000!\n")); 61 | 62 | displayDriverMode(); 63 | 64 | Serial.println(F("\nInitialising the CC3000 ...")); 65 | if (!cc3000.begin()) { 66 | Serial.println(F("Unable to initialise the CC3000! Check your wiring?")); 67 | for(;;); 68 | } 69 | 70 | uint16_t firmware = checkFirmwareVersion(); 71 | if (firmware < 0x113) { 72 | Serial.println(F("Wrong firmware version!")); 73 | for(;;); 74 | } 75 | 76 | displayMACAddress(); 77 | 78 | Serial.println(F("\nDeleting old connection profiles")); 79 | if (!cc3000.deleteProfiles()) { 80 | Serial.println(F("Failed!")); 81 | while(1); 82 | } 83 | 84 | /* Attempt to connect to an access point */ 85 | char *ssid = WLAN_SSID; /* Max 32 chars */ 86 | Serial.print(F("\nAttempting to connect to ")); Serial.println(ssid); 87 | 88 | /* NOTE: Secure connections are not available in 'Tiny' mode! */ 89 | if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) { 90 | Serial.println(F("Failed!")); 91 | while(1); 92 | } 93 | 94 | Serial.println(F("Connected!")); 95 | 96 | /* Wait for DHCP to complete */ 97 | Serial.println(F("Request DHCP")); 98 | while (!cc3000.checkDHCP()) { 99 | delay(100); // ToDo: Insert a DHCP timeout! 100 | } 101 | 102 | /* Display the IP address DNS, Gateway, etc. */ 103 | while (!displayConnectionDetails()) { 104 | delay(1000); 105 | } 106 | } 107 | 108 | 109 | // To reduce load on NTP servers, time is polled once per roughly 24 hour period. 110 | // Otherwise use millis() to estimate time since last query. Plenty accurate. 111 | void loop(void) { 112 | 113 | if(countdown == 0) { // Time's up? 114 | unsigned long t = getTime(); // Query time server 115 | if(t) { // Success? 116 | lastPolledTime = t; // Save time 117 | sketchTime = millis(); // Save sketch time of last valid time query 118 | countdown = 24*60*4-1; // Reset counter: 24 hours * 15-second intervals 119 | } 120 | } else { 121 | countdown--; // Don't poll; use math to figure current time 122 | } 123 | 124 | unsigned long currentTime = lastPolledTime + (millis() - sketchTime) / 1000; 125 | 126 | Serial.print(F("Current UNIX time: ")); 127 | Serial.print(currentTime); 128 | Serial.println(F(" (seconds since 1/1/1970 UTC)")); 129 | 130 | delay(15000L); // Pause 15 seconds 131 | } 132 | 133 | 134 | /**************************************************************************/ 135 | /*! 136 | @brief Displays the driver mode (tiny of normal), and the buffer 137 | size if tiny mode is not being used 138 | 139 | @note The buffer size and driver mode are defined in cc3000_common.h 140 | */ 141 | /**************************************************************************/ 142 | void displayDriverMode(void) 143 | { 144 | #ifdef CC3000_TINY_DRIVER 145 | Serial.println(F("CC3000 is configure in 'Tiny' mode")); 146 | #else 147 | Serial.print(F("RX Buffer : ")); 148 | Serial.print(CC3000_RX_BUFFER_SIZE); 149 | Serial.println(F(" bytes")); 150 | Serial.print(F("TX Buffer : ")); 151 | Serial.print(CC3000_TX_BUFFER_SIZE); 152 | Serial.println(F(" bytes")); 153 | #endif 154 | } 155 | 156 | /**************************************************************************/ 157 | /*! 158 | @brief Tries to read the CC3000's internal firmware patch ID 159 | */ 160 | /**************************************************************************/ 161 | uint16_t checkFirmwareVersion(void) 162 | { 163 | uint8_t major, minor; 164 | uint16_t version; 165 | 166 | #ifndef CC3000_TINY_DRIVER 167 | if(!cc3000.getFirmwareVersion(&major, &minor)) 168 | { 169 | Serial.println(F("Unable to retrieve the firmware version!\r\n")); 170 | version = 0; 171 | } 172 | else 173 | { 174 | Serial.print(F("Firmware V. : ")); 175 | Serial.print(major); Serial.print(F(".")); Serial.println(minor); 176 | version = major; version <<= 8; version |= minor; 177 | } 178 | #endif 179 | return version; 180 | } 181 | 182 | /**************************************************************************/ 183 | /*! 184 | @brief Tries to read the 6-byte MAC address of the CC3000 module 185 | */ 186 | /**************************************************************************/ 187 | void displayMACAddress(void) 188 | { 189 | uint8_t macAddress[6]; 190 | 191 | if(!cc3000.getMacAddress(macAddress)) 192 | { 193 | Serial.println(F("Unable to retrieve MAC Address!\r\n")); 194 | } 195 | else 196 | { 197 | Serial.print(F("MAC Address : ")); 198 | cc3000.printHex((byte*)&macAddress, 6); 199 | } 200 | } 201 | 202 | 203 | /**************************************************************************/ 204 | /*! 205 | @brief Tries to read the IP address and other connection details 206 | */ 207 | /**************************************************************************/ 208 | bool displayConnectionDetails(void) 209 | { 210 | uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv; 211 | 212 | if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv)) 213 | { 214 | Serial.println(F("Unable to retrieve the IP Address!\r\n")); 215 | return false; 216 | } 217 | else 218 | { 219 | Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress); 220 | Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask); 221 | Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway); 222 | Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv); 223 | Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv); 224 | Serial.println(); 225 | return true; 226 | } 227 | } 228 | 229 | // Minimalist time server query; adapted from Adafruit Gutenbird sketch, 230 | // which in turn has roots in Arduino UdpNTPClient tutorial. 231 | unsigned long getTime(void) { 232 | 233 | uint8_t buf[48]; 234 | unsigned long ip, startTime, t = 0L; 235 | 236 | Serial.print(F("Locating time server...")); 237 | 238 | // Hostname to IP lookup; use NTP pool (rotates through servers) 239 | if(cc3000.getHostByName("0.adafruit.pool.ntp.org", &ip)) { 240 | static const char PROGMEM 241 | timeReqA[] = { 227, 0, 6, 236 }, 242 | timeReqB[] = { 49, 78, 49, 52 }; 243 | 244 | Serial.println(F("\r\nAttempting connection...")); 245 | startTime = millis(); 246 | do { 247 | client = cc3000.connectUDP(ip, 123); 248 | } while((!client.connected()) && 249 | ((millis() - startTime) < connectTimeout)); 250 | 251 | if(client.connected()) { 252 | Serial.print(F("connected!\r\nIssuing request...")); 253 | 254 | // Assemble and issue request packet 255 | memset(buf, 0, sizeof(buf)); 256 | memcpy_P( buf , timeReqA, sizeof(timeReqA)); 257 | memcpy_P(&buf[12], timeReqB, sizeof(timeReqB)); 258 | client.write(buf, sizeof(buf)); 259 | 260 | Serial.print(F("\r\nAwaiting response...")); 261 | memset(buf, 0, sizeof(buf)); 262 | startTime = millis(); 263 | while((!client.available()) && 264 | ((millis() - startTime) < responseTimeout)); 265 | if(client.available()) { 266 | client.read(buf, sizeof(buf)); 267 | t = (((unsigned long)buf[40] << 24) | 268 | ((unsigned long)buf[41] << 16) | 269 | ((unsigned long)buf[42] << 8) | 270 | (unsigned long)buf[43]) - 2208988800UL; 271 | Serial.print(F("OK\r\n")); 272 | } 273 | client.close(); 274 | } 275 | } 276 | if(!t) Serial.println(F("error")); 277 | return t; 278 | } 279 | -------------------------------------------------------------------------------- /Adafruit_CC3000_Server.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************/ 2 | /*! 3 | @file Adafruit_CC3000_Server.cpp 4 | @author Tony DiCola (tony@tonydicola.com) 5 | @license BSD (see license.txt) 6 | 7 | Adafruit CC3000 TCP server implementation based on the same interface as 8 | the Arduino Ethernet library server class. 9 | 10 | See http://arduino.cc/en/Reference/Ethernet for documentation on the 11 | Arduino Ethernet library and its server interface. 12 | 13 | */ 14 | /**************************************************************************/ 15 | #include "Adafruit_CC3000_Server.h" 16 | 17 | #include "utility/socket.h" 18 | 19 | #define CC3K_PRINTLN_F(text) CHECK_PRINTER { if(CC3KPrinter != NULL) { CC3KPrinter->println(F(text)); } } 20 | 21 | #define HANDLE_NULL(client, value) { if (client == NULL) return value; } 22 | 23 | 24 | /**************************************************************************/ 25 | /* 26 | Adafruit_CC3000_ClientRef implementation 27 | */ 28 | /**************************************************************************/ 29 | 30 | Adafruit_CC3000_ClientRef::Adafruit_CC3000_ClientRef(Adafruit_CC3000_Client* client) 31 | : _client(client) 32 | { } 33 | 34 | // Return true if the referenced client is connected. This is provided for 35 | // compatibility with Ethernet library code. 36 | Adafruit_CC3000_ClientRef::operator bool() { 37 | return connected(); 38 | } 39 | // Below are wrappers around the public client functions. These hide the fact that users 40 | // are dealing with a reference to a client instance and allow code to be written using 41 | // value semantics like in the Ethernet library. 42 | int Adafruit_CC3000_ClientRef::connect(IPAddress ip, uint16_t port) { 43 | HANDLE_NULL(_client, false); 44 | return _client->connect(ip, port); 45 | } 46 | 47 | int Adafruit_CC3000_ClientRef::connect(const char *host, uint16_t port) { 48 | HANDLE_NULL(_client, false); 49 | return _client->connect(host, port); 50 | } 51 | 52 | uint8_t Adafruit_CC3000_ClientRef::connected(void) { 53 | HANDLE_NULL(_client, false); 54 | return _client->connected(); 55 | } 56 | 57 | size_t Adafruit_CC3000_ClientRef::write(uint8_t c) { 58 | HANDLE_NULL(_client, 0); 59 | return _client->write(c); 60 | } 61 | 62 | size_t Adafruit_CC3000_ClientRef::fastrprint(const char *str) { 63 | HANDLE_NULL(_client, 0); 64 | return _client->fastrprint(str); 65 | } 66 | 67 | size_t Adafruit_CC3000_ClientRef::fastrprintln(const char *str) { 68 | HANDLE_NULL(_client, 0); 69 | return _client->fastrprintln(str); 70 | } 71 | 72 | size_t Adafruit_CC3000_ClientRef::fastrprint(char *str) { 73 | HANDLE_NULL(_client, 0); 74 | return _client->fastrprint(str); 75 | } 76 | 77 | size_t Adafruit_CC3000_ClientRef::fastrprintln(char *str) { 78 | HANDLE_NULL(_client, 0); 79 | return _client->fastrprintln(str); 80 | } 81 | 82 | size_t Adafruit_CC3000_ClientRef::fastrprint(const __FlashStringHelper *ifsh) { 83 | HANDLE_NULL(_client, 0); 84 | return _client->fastrprint(ifsh); 85 | } 86 | 87 | size_t Adafruit_CC3000_ClientRef::fastrprintln(const __FlashStringHelper *ifsh) { 88 | HANDLE_NULL(_client, 0); 89 | return _client->fastrprintln(ifsh); 90 | } 91 | 92 | size_t Adafruit_CC3000_ClientRef::write(const void *buf, uint16_t len, uint32_t flags) { 93 | HANDLE_NULL(_client, 0); 94 | return _client->write(buf, len, flags); 95 | } 96 | 97 | int Adafruit_CC3000_ClientRef::read(void *buf, uint16_t len, uint32_t flags) { 98 | HANDLE_NULL(_client, 0); 99 | return _client->read(buf, len, flags); 100 | } 101 | 102 | int Adafruit_CC3000_ClientRef::read(void) { 103 | HANDLE_NULL(_client, 0); 104 | return _client->read(); 105 | } 106 | 107 | int32_t Adafruit_CC3000_ClientRef::close(void) { 108 | HANDLE_NULL(_client, 0); 109 | return _client->close(); 110 | } 111 | 112 | int Adafruit_CC3000_ClientRef::available(void) { 113 | HANDLE_NULL(_client, 0); 114 | return _client->available(); 115 | } 116 | 117 | int Adafruit_CC3000_ClientRef::read(uint8_t *buf, size_t size) { 118 | HANDLE_NULL(_client, 0); 119 | return _client->read(buf, size); 120 | } 121 | 122 | size_t Adafruit_CC3000_ClientRef::write(const uint8_t *buf, size_t size) { 123 | HANDLE_NULL(_client, 0); 124 | return _client->write(buf, size); 125 | } 126 | 127 | int Adafruit_CC3000_ClientRef::peek() { 128 | HANDLE_NULL(_client, 0); 129 | return _client->peek(); 130 | } 131 | 132 | void Adafruit_CC3000_ClientRef::flush() { 133 | if (_client != NULL) _client->flush(); 134 | } 135 | 136 | void Adafruit_CC3000_ClientRef::stop() { 137 | if (_client != NULL) _client->stop(); 138 | } 139 | 140 | 141 | /**************************************************************************/ 142 | /* 143 | Adafruit_CC3000_Server implementation 144 | */ 145 | /**************************************************************************/ 146 | 147 | // Construct a TCP server to listen on the specified port. 148 | Adafruit_CC3000_Server::Adafruit_CC3000_Server(uint16_t port) 149 | : _port(port) 150 | , _listenSocket(-1) 151 | { } 152 | 153 | // Return index of a client with data available for reading. Can be turned 154 | // into a client instance with getClientRef(). Accepts an optional parameter 155 | // to return a boolean (by reference) indicating if available client is connecting 156 | // for the first time. 157 | int8_t Adafruit_CC3000_Server::availableIndex(bool *newClient) { 158 | bool newClientCreated = acceptNewConnections(); 159 | 160 | if (newClient) 161 | *newClient = newClientCreated; 162 | 163 | // Find the first client which is ready to read and return it. 164 | for (int i = 0; i < MAX_SERVER_CLIENTS; ++i) { 165 | if (_clients[i].connected() && _clients[i].available() > 0) { 166 | return i; 167 | } 168 | } 169 | 170 | return -1; 171 | } 172 | 173 | // Given the index of client, returns the instance of that client for reading/writing 174 | Adafruit_CC3000_ClientRef Adafruit_CC3000_Server::getClientRef(int8_t clientIndex) { 175 | if (clientIndex != -1) { 176 | return Adafruit_CC3000_ClientRef(&_clients[clientIndex]); 177 | } 178 | 179 | // Couldn't find a client ready to read, so return a client that is not 180 | // connected to signal no clients are available for reading (convention 181 | // used by the Ethernet library). 182 | return Adafruit_CC3000_ClientRef(NULL); 183 | } 184 | 185 | // Return a reference to a client instance which has data available to read. 186 | Adafruit_CC3000_ClientRef Adafruit_CC3000_Server::available() { 187 | return getClientRef(availableIndex(NULL)); 188 | } 189 | 190 | // Initialize the server and start listening for connections. 191 | void Adafruit_CC3000_Server::begin() { 192 | // Set the CC3000 inactivity timeout to 0 (never timeout). This will ensure 193 | // the CC3000 does not close the listening socket when it's idle for more than 194 | // 60 seconds (the default timeout). See more information from: 195 | // http://e2e.ti.com/support/low_power_rf/f/851/t/292664.aspx 196 | unsigned long aucDHCP = 14400; 197 | unsigned long aucARP = 3600; 198 | unsigned long aucKeepalive = 30; 199 | unsigned long aucInactivity = 0; 200 | cc3k_int_poll(); 201 | if (netapp_timeout_values(&aucDHCP, &aucARP, &aucKeepalive, &aucInactivity) != 0) { 202 | CC3K_PRINTLN_F("Error setting inactivity timeout!"); 203 | return; 204 | } 205 | // Create a TCP socket 206 | cc3k_int_poll(); 207 | int16_t soc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 208 | if (soc < 0) { 209 | CC3K_PRINTLN_F("Couldn't create listening socket!"); 210 | return; 211 | } 212 | // Set the socket's accept call as non-blocking. 213 | cc3k_int_poll(); 214 | char arg = SOCK_ON; // nsd: looked in TI example code and they pass this as a 'short' in one example, and 'char' in two others. 'char' seems as likely work, and has no endianess issue 215 | if (setsockopt(soc, SOL_SOCKET, SOCKOPT_ACCEPT_NONBLOCK, &arg, sizeof(arg)) < 0) { 216 | CC3K_PRINTLN_F("Couldn't set socket as non-blocking!"); 217 | return; 218 | } 219 | // Bind the socket to a TCP address. 220 | sockaddr_in address; 221 | address.sin_family = AF_INET; 222 | address.sin_addr.s_addr = htonl(0); // Listen on any network interface, equivalent to INADDR_ANY in sockets programming. 223 | address.sin_port = htons(_port); // Listen on the specified port. 224 | cc3k_int_poll(); 225 | if (bind(soc, (sockaddr*) &address, sizeof(address)) < 0) { 226 | CC3K_PRINTLN_F("Error binding listen socket to address!"); 227 | return; 228 | } 229 | // Start listening for connections. 230 | // The backlog parameter is 0 as it is not supported on TI's CC3000 firmware. 231 | cc3k_int_poll(); 232 | if (listen(soc, 0) < 0) { 233 | CC3K_PRINTLN_F("Error opening socket for listening!"); 234 | return; 235 | } 236 | _listenSocket = soc; 237 | } 238 | 239 | // Write data to all connected clients. Buffer is a pointer to an array 240 | // of bytes, and size specifies how many bytes to write from the buffer. 241 | // Return the sum of bytes written to all clients. 242 | size_t Adafruit_CC3000_Server::write(const uint8_t *buffer, size_t size) { 243 | size_t written = 0; 244 | for (int i = 0; i < MAX_SERVER_CLIENTS; ++i) { 245 | if (_clients[i].connected()) { 246 | written += _clients[i].write(buffer, size); 247 | } 248 | } 249 | return written; 250 | } 251 | 252 | // Write a byte value to all connected clients. 253 | // Return the sum of bytes written to all clients. 254 | size_t Adafruit_CC3000_Server::write(uint8_t value) { 255 | return write(&value, 1); 256 | } 257 | 258 | // Accept new connections and update the connected clients. 259 | bool Adafruit_CC3000_Server::acceptNewConnections() { 260 | bool newClientCreated = false; 261 | // For any unconnected client, see if new connections are pending and accept 262 | // them as a new client. 263 | for (int i = 0; i < MAX_SERVER_CLIENTS; ++i) { 264 | if (!_clients[i].connected()) { 265 | // Note: Because the non-blocking option was set for the listening 266 | // socket this call will not block and instead return SOC_IN_PROGRESS (-2) 267 | // if there are no pending client connections. Also, the address of the 268 | // connected client is not needed, so those parameters are set to NULL. 269 | cc3k_int_poll(); 270 | int soc = accept(_listenSocket, NULL, NULL); 271 | if (soc > -1) { 272 | _clients[i] = Adafruit_CC3000_Client(soc); 273 | newClientCreated = true; 274 | } 275 | // else either there were no sockets to accept or an error occured. 276 | } 277 | } 278 | return newClientCreated; 279 | } 280 | -------------------------------------------------------------------------------- /utility/nvmem.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * nvmem.h - CC3000 Host Driver Implementation. 4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 5 | * 6 | * Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend) 7 | * & Limor Fried for Adafruit Industries 8 | * This library works with the Adafruit CC3000 breakout 9 | * ----> https://www.adafruit.com/products/1469 10 | * Adafruit invests time and resources providing this open source code, 11 | * please support Adafruit and open-source hardware by purchasing 12 | * products from Adafruit! 13 | * 14 | * Redistribution and use in source and binary forms, with or without 15 | * modification, are permitted provided that the following conditions 16 | * are met: 17 | * 18 | * Redistributions of source code must retain the above copyright 19 | * notice, this list of conditions and the following disclaimer. 20 | * 21 | * Redistributions in binary form must reproduce the above copyright 22 | * notice, this list of conditions and the following disclaimer in the 23 | * documentation and/or other materials provided with the 24 | * distribution. 25 | * 26 | * Neither the name of Texas Instruments Incorporated nor the names of 27 | * its contributors may be used to endorse or promote products derived 28 | * from this software without specific prior written permission. 29 | * 30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 33 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 34 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 35 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 36 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 37 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 38 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 39 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 40 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 | * 42 | *****************************************************************************/ 43 | #ifndef __NVRAM_H__ 44 | #define __NVRAM_H__ 45 | 46 | #include "cc3000_common.h" 47 | 48 | 49 | //***************************************************************************** 50 | // 51 | // If building with a C++ compiler, make all of the definitions in this header 52 | // have a C binding. 53 | // 54 | //***************************************************************************** 55 | #ifdef __cplusplus 56 | extern "C" { 57 | #endif 58 | 59 | 60 | //***************************************************************************** 61 | // 62 | //! \addtogroup nvmem_api 63 | //! @{ 64 | // 65 | //***************************************************************************** 66 | 67 | /**************************************************************************** 68 | ** 69 | ** Definitions for File IDs 70 | ** 71 | ****************************************************************************/ 72 | /* NVMEM file ID - system files*/ 73 | #define NVMEM_NVS_FILEID (0) 74 | #define NVMEM_NVS_SHADOW_FILEID (1) 75 | #define NVMEM_WLAN_CONFIG_FILEID (2) 76 | #define NVMEM_WLAN_CONFIG_SHADOW_FILEID (3) 77 | #define NVMEM_WLAN_DRIVER_SP_FILEID (4) 78 | #define NVMEM_WLAN_FW_SP_FILEID (5) 79 | #define NVMEM_MAC_FILEID (6) 80 | #define NVMEM_FRONTEND_VARS_FILEID (7) 81 | #define NVMEM_IP_CONFIG_FILEID (8) 82 | #define NVMEM_IP_CONFIG_SHADOW_FILEID (9) 83 | #define NVMEM_BOOTLOADER_SP_FILEID (10) 84 | #define NVMEM_RM_FILEID (11) 85 | 86 | /* NVMEM file ID - user files*/ 87 | #define NVMEM_AES128_KEY_FILEID (12) 88 | #define NVMEM_SHARED_MEM_FILEID (13) 89 | 90 | /* max entry in order to invalid nvmem */ 91 | #define NVMEM_MAX_ENTRY (16) 92 | 93 | 94 | //***************************************************************************** 95 | // 96 | //! nvmem_read 97 | //! 98 | //! @param ulFileId nvmem file id:\n 99 | //! NVMEM_NVS_FILEID, NVMEM_NVS_SHADOW_FILEID, 100 | //! NVMEM_WLAN_CONFIG_FILEID, NVMEM_WLAN_CONFIG_SHADOW_FILEID, 101 | //! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, 102 | //! NVMEM_MAC_FILEID, NVMEM_FRONTEND_VARS_FILEID, 103 | //! NVMEM_IP_CONFIG_FILEID, NVMEM_IP_CONFIG_SHADOW_FILEID, 104 | //! NVMEM_BOOTLOADER_SP_FILEID, NVMEM_RM_FILEID, 105 | //! and user files 12-15. 106 | //! @param ulLength number of bytes to read 107 | //! @param ulOffset ulOffset in file from where to read 108 | //! @param buff output buffer pointer 109 | //! 110 | //! @return on success 0, error otherwise. 111 | //! 112 | //! @brief Reads data from the file referred by the ulFileId parameter. 113 | //! Reads data from file ulOffset till length. Err if the file can't 114 | //! be used, is invalid, or if the read is out of bounds. 115 | //! 116 | //***************************************************************************** 117 | 118 | extern INT32 nvmem_read(UINT32 file_id, UINT32 length, UINT32 offset, UINT8 *buff); 119 | 120 | //***************************************************************************** 121 | // 122 | //! nvmem_write 123 | //! 124 | //! @param ulFileId nvmem file id:\n 125 | //! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, 126 | //! NVMEM_MAC_FILEID, NVMEM_BOOTLOADER_SP_FILEID, 127 | //! and user files 12-15. 128 | //! @param ulLength number of bytes to write 129 | //! @param ulEntryOffset offset in file to start write operation from 130 | //! @param buff data to write 131 | //! 132 | //! @return on success 0, error otherwise. 133 | //! 134 | //! @brief Write data to nvmem. 135 | //! writes data to file referred by the ulFileId parameter. 136 | //! Writes data to file ulOffset till ulLength.The file id will be 137 | //! marked invalid till the write is done. The file entry doesn't 138 | //! need to be valid - only allocated. 139 | //! 140 | //***************************************************************************** 141 | 142 | extern INT32 nvmem_write(UINT32 ulFileId, UINT32 ulLength, UINT32 ulEntryOffset, UINT8 *buff); 143 | 144 | 145 | //***************************************************************************** 146 | // 147 | //! nvmem_set_mac_address 148 | //! 149 | //! @param mac mac address to be set 150 | //! 151 | //! @return on success 0, error otherwise. 152 | //! 153 | //! @brief Write MAC address to EEPROM. 154 | //! mac address as appears over the air (OUI first) 155 | //! 156 | //***************************************************************************** 157 | extern UINT8 nvmem_set_mac_address(UINT8 *mac); 158 | 159 | 160 | //***************************************************************************** 161 | // 162 | //! nvmem_get_mac_address 163 | //! 164 | //! @param[out] mac mac address 165 | //! 166 | //! @return on success 0, error otherwise. 167 | //! 168 | //! @brief Read MAC address from EEPROM. 169 | //! mac address as appears over the air (OUI first) 170 | //! 171 | //***************************************************************************** 172 | extern UINT8 nvmem_get_mac_address(UINT8 *mac); 173 | 174 | 175 | //***************************************************************************** 176 | // 177 | //! nvmem_write_patch 178 | //! 179 | //! @param ulFileId nvmem file id:\n 180 | //! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, 181 | //! @param spLength number of bytes to write 182 | //! @param spData SP data to write 183 | //! 184 | //! @return on success 0, error otherwise. 185 | //! 186 | //! @brief program a patch to a specific file ID. 187 | //! The SP data is assumed to be organized in 2-dimensional. 188 | //! Each line is SP_PORTION_SIZE bytes long. Actual programming is 189 | //! applied in SP_PORTION_SIZE bytes portions. 190 | //! 191 | //***************************************************************************** 192 | extern UINT8 nvmem_write_patch(UINT32 ulFileId, UINT32 spLength, const UINT8 *spData); 193 | 194 | 195 | //***************************************************************************** 196 | // 197 | //! nvmem_read_sp_version 198 | //! 199 | //! @param[out] patchVer first number indicates package ID and the second 200 | //! number indicates package build number 201 | //! 202 | //! @return on success 0, error otherwise. 203 | //! 204 | //! @brief Read patch version. read package version (WiFi FW patch, 205 | //! driver-supplicant-NS patch, bootloader patch) 206 | //! 207 | //***************************************************************************** 208 | #ifndef CC3000_TINY_DRIVER 209 | extern UINT8 nvmem_read_sp_version(UINT8* patchVer); 210 | #endif 211 | 212 | //***************************************************************************** 213 | // 214 | //! nvmem_create_entry 215 | //! 216 | //! @param ulFileId nvmem file Id:\n 217 | //! * NVMEM_AES128_KEY_FILEID: 12 218 | //! * NVMEM_SHARED_MEM_FILEID: 13 219 | //! * and fileIDs 14 and 15 220 | //! @param ulNewLen entry ulLength 221 | //! 222 | //! @return on success 0, error otherwise. 223 | //! 224 | //! @brief Create new file entry and allocate space on the NVMEM. 225 | //! Applies only to user files. 226 | //! Modify the size of file. 227 | //! If the entry is unallocated - allocate it to size 228 | //! ulNewLen (marked invalid). 229 | //! If it is allocated then deallocate it first. 230 | //! To just mark the file as invalid without resizing - 231 | //! set ulNewLen=0. 232 | //! 233 | //***************************************************************************** 234 | extern INT32 nvmem_create_entry(UINT32 file_id, UINT32 newlen); 235 | 236 | 237 | //***************************************************************************** 238 | // 239 | // Mark the end of the C bindings section for C++ compilers. 240 | // 241 | //***************************************************************************** 242 | 243 | 244 | //***************************************************************************** 245 | // 246 | // Close the Doxygen group. 247 | //! @} 248 | // 249 | //***************************************************************************** 250 | 251 | 252 | #ifdef __cplusplus 253 | } 254 | #endif // __cplusplus 255 | 256 | #endif // __NVRAM_H__ 257 | -------------------------------------------------------------------------------- /examples/HTTPServer/HTTPServer.ino: -------------------------------------------------------------------------------- 1 | 2 | /*************************************************** 3 | Adafruit CC3000 Breakout/Shield Simple HTTP Server 4 | 5 | This is a simple implementation of a bare bones 6 | HTTP server that can respond to very simple requests. 7 | Note that this server is not meant to handle high 8 | load, concurrent connections, SSL, etc. A 16mhz Arduino 9 | with 2K of memory can only handle so much complexity! 10 | This server example is best for very simple status messages 11 | or REST APIs. 12 | 13 | See the CC3000 tutorial on Adafruit's learning system 14 | for more information on setting up and using the 15 | CC3000: 16 | http://learn.adafruit.com/adafruit-cc3000-wifi 17 | 18 | Requirements: 19 | 20 | This sketch requires the Adafruit CC3000 library. You can 21 | download the library from: 22 | https://github.com/adafruit/Adafruit_CC3000_Library 23 | 24 | For information on installing libraries in the Arduino IDE 25 | see this page: 26 | http://arduino.cc/en/Guide/Libraries 27 | 28 | Usage: 29 | 30 | Update the SSID and, if necessary, the CC3000 hardware pin 31 | information below, then run the sketch and check the 32 | output of the serial port. After connecting to the 33 | wireless network successfully the sketch will output 34 | the IP address of the server and start listening for 35 | connections. Once listening for connections, connect 36 | to the server IP from a web browser. For example if your 37 | server is listening on IP 192.168.1.130 you would access 38 | http://192.168.1.130/ from your web browser. 39 | 40 | Created by Tony DiCola and adapted from HTTP server code created by Eric Friedrich. 41 | 42 | This code was adapted from Adafruit CC3000 library example 43 | code which has the following license: 44 | 45 | Designed specifically to work with the Adafruit WiFi products: 46 | ----> https://www.adafruit.com/products/1469 47 | 48 | Adafruit invests time and resources providing this open source code, 49 | please support Adafruit and open-source hardware by purchasing 50 | products from Adafruit! 51 | 52 | Written by Limor Fried & Kevin Townsend for Adafruit Industries. 53 | BSD license, all text above must be included in any redistribution 54 | ****************************************************/ 55 | #include 56 | #include 57 | #include "utility/debug.h" 58 | #include "utility/socket.h" 59 | 60 | // These are the interrupt and control pins 61 | #define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin! 62 | // These can be any two pins 63 | #define ADAFRUIT_CC3000_VBAT 5 64 | #define ADAFRUIT_CC3000_CS 10 65 | // Use hardware SPI for the remaining pins 66 | // On an UNO, SCK = 13, MISO = 12, and MOSI = 11 67 | 68 | Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, 69 | SPI_CLOCK_DIVIDER); // you can change this clock speed 70 | 71 | #define WLAN_SSID "myNetwork" // cannot be longer than 32 characters! 72 | #define WLAN_PASS "myPassword" 73 | // Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2 74 | #define WLAN_SECURITY WLAN_SEC_WPA2 75 | 76 | #define LISTEN_PORT 80 // What TCP port to listen on for connections. 77 | // The HTTP protocol uses port 80 by default. 78 | 79 | #define MAX_ACTION 10 // Maximum length of the HTTP action that can be parsed. 80 | 81 | #define MAX_PATH 64 // Maximum length of the HTTP request path that can be parsed. 82 | // There isn't much memory available so keep this short! 83 | 84 | #define BUFFER_SIZE MAX_ACTION + MAX_PATH + 20 // Size of buffer for incoming request data. 85 | // Since only the first line is parsed this 86 | // needs to be as large as the maximum action 87 | // and path plus a little for whitespace and 88 | // HTTP version. 89 | 90 | #define TIMEOUT_MS 500 // Amount of time in milliseconds to wait for 91 | // an incoming request to finish. Don't set this 92 | // too high or your server could be slow to respond. 93 | 94 | Adafruit_CC3000_Server httpServer(LISTEN_PORT); 95 | uint8_t buffer[BUFFER_SIZE+1]; 96 | int bufindex = 0; 97 | char action[MAX_ACTION+1]; 98 | char path[MAX_PATH+1]; 99 | 100 | void setup(void) 101 | { 102 | Serial.begin(115200); 103 | Serial.println(F("Hello, CC3000!\n")); 104 | 105 | Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC); 106 | 107 | // Initialise the module 108 | Serial.println(F("\nInitializing...")); 109 | if (!cc3000.begin()) 110 | { 111 | Serial.println(F("Couldn't begin()! Check your wiring?")); 112 | while(1); 113 | } 114 | 115 | Serial.print(F("\nAttempting to connect to ")); Serial.println(WLAN_SSID); 116 | if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) { 117 | Serial.println(F("Failed!")); 118 | while(1); 119 | } 120 | 121 | Serial.println(F("Connected!")); 122 | 123 | Serial.println(F("Request DHCP")); 124 | while (!cc3000.checkDHCP()) 125 | { 126 | delay(100); // ToDo: Insert a DHCP timeout! 127 | } 128 | 129 | // Display the IP address DNS, Gateway, etc. 130 | while (! displayConnectionDetails()) { 131 | delay(1000); 132 | } 133 | 134 | // ****************************************************** 135 | // You can safely remove this to save some flash memory! 136 | // ****************************************************** 137 | Serial.println(F("\r\nNOTE: This sketch may cause problems with other sketches")); 138 | Serial.println(F("since the .disconnect() function is never called, so the")); 139 | Serial.println(F("AP may refuse connection requests from the CC3000 until a")); 140 | Serial.println(F("timeout period passes. This is normal behaviour since")); 141 | Serial.println(F("there isn't an obvious moment to disconnect with a server.\r\n")); 142 | 143 | // Start listening for connections 144 | httpServer.begin(); 145 | 146 | Serial.println(F("Listening for connections...")); 147 | } 148 | 149 | void loop(void) 150 | { 151 | // Try to get a client which is connected. 152 | Adafruit_CC3000_ClientRef client = httpServer.available(); 153 | if (client) { 154 | Serial.println(F("Client connected.")); 155 | // Process this request until it completes or times out. 156 | // Note that this is explicitly limited to handling one request at a time! 157 | 158 | // Clear the incoming data buffer and point to the beginning of it. 159 | bufindex = 0; 160 | memset(&buffer, 0, sizeof(buffer)); 161 | 162 | // Clear action and path strings. 163 | memset(&action, 0, sizeof(action)); 164 | memset(&path, 0, sizeof(path)); 165 | 166 | // Set a timeout for reading all the incoming data. 167 | unsigned long endtime = millis() + TIMEOUT_MS; 168 | 169 | // Read all the incoming data until it can be parsed or the timeout expires. 170 | bool parsed = false; 171 | while (!parsed && (millis() < endtime) && (bufindex < BUFFER_SIZE)) { 172 | if (client.available()) { 173 | buffer[bufindex++] = client.read(); 174 | } 175 | parsed = parseRequest(buffer, bufindex, action, path); 176 | } 177 | 178 | // Handle the request if it was parsed. 179 | if (parsed) { 180 | Serial.println(F("Processing request")); 181 | Serial.print(F("Action: ")); Serial.println(action); 182 | Serial.print(F("Path: ")); Serial.println(path); 183 | // Check the action to see if it was a GET request. 184 | if (strcmp(action, "GET") == 0) { 185 | // Respond with the path that was accessed. 186 | // First send the success response code. 187 | client.fastrprintln(F("HTTP/1.1 200 OK")); 188 | // Then send a few headers to identify the type of data returned and that 189 | // the connection will not be held open. 190 | client.fastrprintln(F("Content-Type: text/plain")); 191 | client.fastrprintln(F("Connection: close")); 192 | client.fastrprintln(F("Server: Adafruit CC3000")); 193 | // Send an empty line to signal start of body. 194 | client.fastrprintln(F("")); 195 | // Now send the response data. 196 | client.fastrprintln(F("Hello world!")); 197 | client.fastrprint(F("You accessed path: ")); client.fastrprintln(path); 198 | } 199 | else { 200 | // Unsupported action, respond with an HTTP 405 method not allowed error. 201 | client.fastrprintln(F("HTTP/1.1 405 Method Not Allowed")); 202 | client.fastrprintln(F("")); 203 | } 204 | } 205 | 206 | // Wait a short period to make sure the response had time to send before 207 | // the connection is closed (the CC3000 sends data asyncronously). 208 | delay(100); 209 | 210 | // Close the connection when done. 211 | Serial.println(F("Client disconnected")); 212 | client.close(); 213 | } 214 | } 215 | 216 | // Return true if the buffer contains an HTTP request. Also returns the request 217 | // path and action strings if the request was parsed. This does not attempt to 218 | // parse any HTTP headers because there really isn't enough memory to process 219 | // them all. 220 | // HTTP request looks like: 221 | // [method] [path] [version] \r\n 222 | // Header_key_1: Header_value_1 \r\n 223 | // ... 224 | // Header_key_n: Header_value_n \r\n 225 | // \r\n 226 | bool parseRequest(uint8_t* buf, int bufSize, char* action, char* path) { 227 | // Check if the request ends with \r\n to signal end of first line. 228 | if (bufSize < 2) 229 | return false; 230 | if (buf[bufSize-2] == '\r' && buf[bufSize-1] == '\n') { 231 | parseFirstLine((char*)buf, action, path); 232 | return true; 233 | } 234 | return false; 235 | } 236 | 237 | // Parse the action and path from the first line of an HTTP request. 238 | void parseFirstLine(char* line, char* action, char* path) { 239 | // Parse first word up to whitespace as action. 240 | char* lineaction = strtok(line, " "); 241 | if (lineaction != NULL) 242 | strncpy(action, lineaction, MAX_ACTION); 243 | // Parse second word up to whitespace as path. 244 | char* linepath = strtok(NULL, " "); 245 | if (linepath != NULL) 246 | strncpy(path, linepath, MAX_PATH); 247 | } 248 | 249 | // Tries to read the IP address and other connection details 250 | bool displayConnectionDetails(void) 251 | { 252 | uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv; 253 | 254 | if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv)) 255 | { 256 | Serial.println(F("Unable to retrieve the IP Address!\r\n")); 257 | return false; 258 | } 259 | else 260 | { 261 | Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress); 262 | Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask); 263 | Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway); 264 | Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv); 265 | Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv); 266 | Serial.println(); 267 | return true; 268 | } 269 | } -------------------------------------------------------------------------------- /examples/buildtest/buildtest.ino: -------------------------------------------------------------------------------- 1 | /*************************************************** 2 | This is an example for the Adafruit CC3000 Wifi Breakout & Shield 3 | 4 | Designed specifically to work with the Adafruit WiFi products: 5 | ----> https://www.adafruit.com/products/1469 6 | 7 | Adafruit invests time and resources providing this open source code, 8 | please support Adafruit and open-source hardware by purchasing 9 | products from Adafruit! 10 | 11 | Written by Kevin Townsend & Limor Fried for Adafruit Industries. 12 | BSD license, all text above must be included in any redistribution 13 | ****************************************************/ 14 | 15 | /* 16 | 17 | This example does a full test of core connectivity: 18 | * Initialization 19 | * SSID Scan 20 | * AP connection 21 | * DHCP printout 22 | * DNS lookup 23 | * Ping 24 | * Disconnect 25 | It's a good idea to run this sketch when first setting up the 26 | module. 27 | 28 | */ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include "utility/debug.h" 35 | 36 | // These are the interrupt and control pins 37 | #define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin! 38 | // These can be any two pins 39 | #define ADAFRUIT_CC3000_VBAT 5 40 | #define ADAFRUIT_CC3000_CS 10 41 | // Use hardware SPI for the remaining pins 42 | // On an UNO, SCK = 13, MISO = 12, and MOSI = 11 43 | Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, 44 | SPI_CLOCK_DIVIDER); // you can change this clock speed but DI 45 | 46 | #define WLAN_SSID "myNetwork" // cannot be longer than 32 characters! 47 | #define WLAN_PASS "myPassword" 48 | // Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2 49 | #define WLAN_SECURITY WLAN_SEC_WPA2 50 | 51 | 52 | 53 | /**************************************************************************/ 54 | /*! 55 | @brief Sets up the HW and the CC3000 module (called automatically 56 | on startup) 57 | */ 58 | /**************************************************************************/ 59 | void setup(void) 60 | { 61 | Serial.begin(115200); 62 | Serial.println(F("Hello, CC3000!\n")); 63 | 64 | displayDriverMode(); 65 | Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC); 66 | 67 | /* Initialise the module */ 68 | Serial.println(F("\nInitialising the CC3000 ...")); 69 | if (!cc3000.begin()) 70 | { 71 | Serial.println(F("Unable to initialise the CC3000! Check your wiring?")); 72 | while(1); 73 | } 74 | 75 | /* Optional: Update the Mac Address to a known value */ 76 | /* 77 | uint8_t macAddress[6] = { 0x08, 0x00, 0x28, 0x01, 0x79, 0xB7 }; 78 | if (!cc3000.setMacAddress(macAddress)) 79 | { 80 | Serial.println(F("Failed trying to update the MAC address")); 81 | while(1); 82 | } 83 | */ 84 | 85 | uint16_t firmware = checkFirmwareVersion(); 86 | if (firmware < 0x113) { 87 | Serial.println(F("Wrong firmware version!")); 88 | for(;;); 89 | } 90 | 91 | displayMACAddress(); 92 | 93 | /* Optional: Get the SSID list (not available in 'tiny' mode) */ 94 | #ifndef CC3000_TINY_DRIVER 95 | listSSIDResults(); 96 | #endif 97 | 98 | /* Delete any old connection data on the module */ 99 | Serial.println(F("\nDeleting old connection profiles")); 100 | if (!cc3000.deleteProfiles()) { 101 | Serial.println(F("Failed!")); 102 | while(1); 103 | } 104 | 105 | /* Optional: Set a static IP address instead of using DHCP. 106 | Note that the setStaticIPAddress function will save its state 107 | in the CC3000's internal non-volatile memory and the details 108 | will be used the next time the CC3000 connects to a network. 109 | This means you only need to call the function once and the 110 | CC3000 will remember the connection details. To switch back 111 | to using DHCP, call the setDHCP() function (again only needs 112 | to be called once). 113 | */ 114 | /* 115 | uint32_t ipAddress = cc3000.IP2U32(192, 168, 1, 19); 116 | uint32_t netMask = cc3000.IP2U32(255, 255, 255, 0); 117 | uint32_t defaultGateway = cc3000.IP2U32(192, 168, 1, 1); 118 | uint32_t dns = cc3000.IP2U32(8, 8, 4, 4); 119 | if (!cc3000.setStaticIPAddress(ipAddress, netMask, defaultGateway, dns)) { 120 | Serial.println(F("Failed to set static IP!")); 121 | while(1); 122 | } 123 | */ 124 | /* Optional: Revert back from static IP addres to use DHCP. 125 | See note for setStaticIPAddress above, this only needs to be 126 | called once and will be remembered afterwards by the CC3000. 127 | */ 128 | /* 129 | if (!cc3000.setDHCP()) { 130 | Serial.println(F("Failed to set DHCP!")); 131 | while(1); 132 | } 133 | */ 134 | 135 | /* Attempt to connect to an access point */ 136 | char *ssid = WLAN_SSID; /* Max 32 chars */ 137 | Serial.print(F("\nAttempting to connect to ")); Serial.println(ssid); 138 | 139 | /* NOTE: Secure connections are not available in 'Tiny' mode! 140 | By default connectToAP will retry indefinitely, however you can pass an 141 | optional maximum number of retries (greater than zero) as the fourth parameter. 142 | 143 | ALSO NOTE: By default connectToAP will retry forever until it can connect to 144 | the access point. This means if the access point doesn't exist the call 145 | will _never_ return! You can however put in an optional maximum retry count 146 | by passing a 4th parameter to the connectToAP function below. This should 147 | be a number of retries to make before giving up, for example 5 would retry 148 | 5 times and then fail if a connection couldn't be made. 149 | */ 150 | if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) { 151 | Serial.println(F("Failed!")); 152 | while(1); 153 | } 154 | 155 | Serial.println(F("Connected!")); 156 | 157 | /* Wait for DHCP to complete */ 158 | Serial.println(F("Request DHCP")); 159 | while (!cc3000.checkDHCP()) 160 | { 161 | delay(100); // ToDo: Insert a DHCP timeout! 162 | } 163 | 164 | /* Display the IP address DNS, Gateway, etc. */ 165 | while (! displayConnectionDetails()) { 166 | delay(1000); 167 | } 168 | 169 | #ifndef CC3000_TINY_DRIVER 170 | /* Try looking up www.adafruit.com */ 171 | uint32_t ip = 0; 172 | Serial.print(F("www.adafruit.com -> ")); 173 | while (ip == 0) { 174 | if (! cc3000.getHostByName("www.adafruit.com", &ip)) { 175 | Serial.println(F("Couldn't resolve!")); 176 | } 177 | delay(500); 178 | } 179 | cc3000.printIPdotsRev(ip); 180 | 181 | /* Do a quick ping test on adafruit.com */ 182 | Serial.print(F("\n\rPinging ")); cc3000.printIPdotsRev(ip); Serial.print("..."); 183 | uint8_t replies = cc3000.ping(ip, 5); 184 | Serial.print(replies); Serial.println(F(" replies")); 185 | if (replies) 186 | Serial.println(F("Ping successful!")); 187 | #endif 188 | 189 | /* You need to make sure to clean up after yourself or the CC3000 can freak out */ 190 | /* the next time you try to connect ... */ 191 | Serial.println(F("\n\nClosing the connection")); 192 | cc3000.disconnect(); 193 | } 194 | 195 | void loop(void) 196 | { 197 | delay(1000); 198 | } 199 | 200 | /**************************************************************************/ 201 | /*! 202 | @brief Displays the driver mode (tiny of normal), and the buffer 203 | size if tiny mode is not being used 204 | 205 | @note The buffer size and driver mode are defined in cc3000_common.h 206 | */ 207 | /**************************************************************************/ 208 | void displayDriverMode(void) 209 | { 210 | #ifdef CC3000_TINY_DRIVER 211 | Serial.println(F("CC3000 is configure in 'Tiny' mode")); 212 | #else 213 | Serial.print(F("RX Buffer : ")); 214 | Serial.print(CC3000_RX_BUFFER_SIZE); 215 | Serial.println(F(" bytes")); 216 | Serial.print(F("TX Buffer : ")); 217 | Serial.print(CC3000_TX_BUFFER_SIZE); 218 | Serial.println(F(" bytes")); 219 | #endif 220 | } 221 | 222 | /**************************************************************************/ 223 | /*! 224 | @brief Tries to read the CC3000's internal firmware patch ID 225 | */ 226 | /**************************************************************************/ 227 | uint16_t checkFirmwareVersion(void) 228 | { 229 | uint8_t major, minor; 230 | uint16_t version; 231 | 232 | #ifndef CC3000_TINY_DRIVER 233 | if(!cc3000.getFirmwareVersion(&major, &minor)) 234 | { 235 | Serial.println(F("Unable to retrieve the firmware version!\r\n")); 236 | version = 0; 237 | } 238 | else 239 | { 240 | Serial.print(F("Firmware V. : ")); 241 | Serial.print(major); Serial.print(F(".")); Serial.println(minor); 242 | version = major; version <<= 8; version |= minor; 243 | } 244 | #endif 245 | return version; 246 | } 247 | 248 | /**************************************************************************/ 249 | /*! 250 | @brief Tries to read the 6-byte MAC address of the CC3000 module 251 | */ 252 | /**************************************************************************/ 253 | void displayMACAddress(void) 254 | { 255 | uint8_t macAddress[6]; 256 | 257 | if(!cc3000.getMacAddress(macAddress)) 258 | { 259 | Serial.println(F("Unable to retrieve MAC Address!\r\n")); 260 | } 261 | else 262 | { 263 | Serial.print(F("MAC Address : ")); 264 | cc3000.printHex((byte*)&macAddress, 6); 265 | } 266 | } 267 | 268 | 269 | /**************************************************************************/ 270 | /*! 271 | @brief Tries to read the IP address and other connection details 272 | */ 273 | /**************************************************************************/ 274 | bool displayConnectionDetails(void) 275 | { 276 | uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv; 277 | 278 | if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv)) 279 | { 280 | Serial.println(F("Unable to retrieve the IP Address!\r\n")); 281 | return false; 282 | } 283 | else 284 | { 285 | Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress); 286 | Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask); 287 | Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway); 288 | Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv); 289 | Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv); 290 | Serial.println(); 291 | return true; 292 | } 293 | } 294 | 295 | /**************************************************************************/ 296 | /*! 297 | @brief Begins an SSID scan and prints out all the visible networks 298 | */ 299 | /**************************************************************************/ 300 | 301 | void listSSIDResults(void) 302 | { 303 | uint32_t index; 304 | uint8_t valid, rssi, sec; 305 | char ssidname[33]; 306 | 307 | if (!cc3000.startSSIDscan(&index)) { 308 | Serial.println(F("SSID scan failed!")); 309 | return; 310 | } 311 | 312 | Serial.print(F("Networks found: ")); Serial.println(index); 313 | Serial.println(F("================================================")); 314 | 315 | while (index) { 316 | index--; 317 | 318 | valid = cc3000.getNextSSID(&rssi, &sec, ssidname); 319 | 320 | Serial.print(F("SSID Name : ")); Serial.print(ssidname); 321 | Serial.println(); 322 | Serial.print(F("RSSI : ")); 323 | Serial.println(rssi); 324 | Serial.print(F("Security Mode: ")); 325 | Serial.println(sec); 326 | Serial.println(); 327 | } 328 | Serial.println(F("================================================")); 329 | 330 | cc3000.stopSSIDscan(); 331 | } 332 | -------------------------------------------------------------------------------- /examples/driverpatch_1_12/driverpatch_1_12.ino: -------------------------------------------------------------------------------- 1 | // Adafruit CC3000 Firmware V1.12 Upgrade Sketch 2 | // Based on firmware patcher for MSP430 chips published by Texas Instruments. 3 | // 4 | // This sketch will upgrade CC3000 modules up to firmware version 1.12. 5 | // 6 | // You can find more details about the changes in the 1.12 firmware from TI at: 7 | // http://processors.wiki.ti.com/index.php/CC3000_Release_Notes 8 | // 9 | // WARNING: Upgrade firmware at your own risk! In general if the CC3000 is 10 | // currently working fine for your needs then hold off on the upgrade. 11 | // 12 | // Usage (read all the steps before strarting): 13 | // - Wire up your Arduino to the CC3000 just like you're running buildtest or 14 | // other examples. 15 | // - Adjust the ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_VBAT 16 | // defines below to match your wiring (just like running buildtest). 17 | // - Load the sketch on your Arduino and open the serial monitor at 115200 baud. 18 | // - You should see a prompt waiting for a key press to continue. Enter text 19 | // and press enter to start the upgrade. 20 | // - You will see text printed as the firmware is upgraded. The upgrade process 21 | // should be quick and take less than a minute. 22 | // - You might see a message at the end that the firmware version or MAC address 23 | // couldn't be read--this can be ignored. 24 | // - Once the firmware upgrade is complete, run the buildtest sketch to check 25 | // the CC3000 functionality. 26 | // - During the firmware upgrade the CC3000 MAC address might be lost. You can 27 | // write a new MAC address by uncommenting the appropriate line in the buildtest 28 | // example. Make sure to save your MAC address before upgrading the firmware 29 | // if you'd like to keep it the same after 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | // Define _BV macro for platforms without it (Due). 37 | #ifndef _BV 38 | #define _BV(bit) (1 << (bit)) 39 | #endif 40 | 41 | #include "utility/debug.h" 42 | #include "utility/nvmem.h" 43 | #include "driverpatchinc.h" 44 | 45 | #define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin! 46 | #define ADAFRUIT_CC3000_CS 10 47 | #define ADAFRUIT_CC3000_VBAT 5 48 | 49 | Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT); 50 | 51 | /**************************************************************************/ 52 | /*! 53 | @brief Displays the driver mode (tiny of normal), and the buffer 54 | size if tiny mode is not being used 55 | 56 | @note The buffer size and driver mode are defined in cc3000_common.h 57 | */ 58 | /**************************************************************************/ 59 | void displayDriverMode(void) 60 | { 61 | #ifdef CC3000_TINY_DRIVER 62 | Serial.println(F("CC3000 is configure in 'Tiny' mode")); 63 | #else 64 | Serial.print(F("RX Buffer : ")); 65 | Serial.print(CC3000_RX_BUFFER_SIZE); 66 | Serial.println(F(" bytes")); 67 | Serial.print(F("TX Buffer : ")); 68 | Serial.print(CC3000_TX_BUFFER_SIZE); 69 | Serial.println(F(" bytes")); 70 | #endif 71 | } 72 | 73 | /**************************************************************************/ 74 | /*! 75 | @brief Tries to read the CC3000's internal firmware patch ID 76 | */ 77 | /**************************************************************************/ 78 | void displayFirmwareVersion(void) 79 | { 80 | #ifndef CC3000_TINY_DRIVER 81 | uint8_t major, minor; 82 | 83 | if(!cc3000.getFirmwareVersion(&major, &minor)) 84 | { 85 | Serial.println(F("Unable to retrieve the firmware version!\r\n")); 86 | } 87 | else 88 | { 89 | Serial.print(F("Firmware V. : ")); 90 | Serial.print(major); Serial.print(F(".")); Serial.println(minor); 91 | } 92 | #endif 93 | } 94 | 95 | /**************************************************************************/ 96 | /*! 97 | @brief Tries to read the 6-byte MAC address of the CC3000 module 98 | */ 99 | /**************************************************************************/ 100 | boolean MACvalid = false; 101 | // array to store MAC address from EEPROM 102 | uint8_t cMacFromEeprom[MAC_ADDR_LEN]; 103 | void displayMACAddress(void) 104 | { 105 | if(!cc3000.getMacAddress(cMacFromEeprom)) 106 | { 107 | Serial.println(F("Unable to retrieve MAC Address!\r\n")); 108 | MACvalid = false; 109 | } 110 | else 111 | { 112 | Serial.print(F("MAC Address : ")); 113 | cc3000.printHex((byte*)&cMacFromEeprom, 6); 114 | MACvalid = true; 115 | } 116 | } 117 | 118 | 119 | 120 | /**************************************************************************/ 121 | /*! 122 | @brief Sets up the HW and the CC3000 module (called automatically 123 | on startup) 124 | */ 125 | /**************************************************************************/ 126 | 127 | uint8_t ucStatus_Dr, return_status = 0xFF; 128 | uint8_t counter = 0; 129 | 130 | // array to store RM parameters from EEPROM 131 | unsigned char cRMParamsFromEeprom[128]; 132 | 133 | 134 | // 2 dim array to store address and length of new FAT 135 | uint16_t aFATEntries[2][NVMEM_RM_FILEID + 1] = 136 | /* address */ {{0x50, 0x1f0, 0x1390, 0x0390, 0x2390, 0x4390, 0x6390, 0x63a0, 0x63b0, 0x63f0, 0x6430, 0x6830}, 137 | /* length */ {0x1a0, 0x1a0, 0x1000, 0x1000, 0x2000, 0x2000, 0x10, 0x10, 0x40, 0x40, 0x400, 0x200 }}; 138 | /* 0. NVS */ 139 | /* 1. NVS Shadow */ 140 | /* 2. Wireless Conf */ 141 | /* 3. Wireless Conf Shadow */ 142 | /* 4. BT (WLAN driver) Patches */ 143 | /* 5. WiLink (Firmware) Patches */ 144 | /* 6. MAC addr */ 145 | /* 7. Frontend Vars */ 146 | /* 8. IP config */ 147 | /* 9. IP config Shadow */ 148 | /* 10. Bootloader Patches */ 149 | /* 11. Radio Module params */ 150 | /* 12. AES128 for smart config */ 151 | /* 13. user file */ 152 | /* 14. user file */ 153 | /* 15. user file */ 154 | 155 | 156 | void setup(void) 157 | { 158 | Serial.begin(115200); 159 | Serial.println(F("Hello, CC3000!\n")); 160 | 161 | Serial.println(F("Hit any key & return to start")); 162 | while (!Serial.available()); 163 | 164 | pinMode(9, OUTPUT); 165 | pinMode(8, OUTPUT); 166 | pinMode(7, OUTPUT); 167 | pinMode(6, OUTPUT); 168 | digitalWrite(9, LOW); 169 | digitalWrite(8, LOW); 170 | digitalWrite(7, LOW); 171 | digitalWrite(6, LOW); 172 | 173 | displayDriverMode(); 174 | displayFreeRam(); 175 | 176 | /* Initialise the module */ 177 | Serial.println(F("\nInitialising the CC3000 ...")); 178 | if (!cc3000.begin(2)) // init with NO patches! 179 | { 180 | Serial.println(F("Unable to initialise the CC3000! Check your wiring?")); 181 | while(1); 182 | } 183 | 184 | displayFirmwareVersion(); 185 | displayMACAddress(); 186 | 187 | return_status = 1; 188 | uint8_t index; 189 | uint8_t *pRMParams; 190 | 191 | while ((return_status) && (counter < 3)) { 192 | // read RM parameters 193 | // read in 16 parts to work with tiny driver 194 | 195 | return_status = 0; 196 | pRMParams = cRMParamsFromEeprom; 197 | 198 | for (index = 0; index < 16; index++) { 199 | return_status |= nvmem_read(NVMEM_RM_FILEID, 8, 8*index, pRMParams); 200 | Serial.print(F("\n\rRead NVRAM $")); Serial.print(8*index); Serial.print("\t"); 201 | for(uint8_t x=0; x<8; x++) { 202 | Serial.print("0x"); Serial.print(pRMParams[x], HEX); Serial.print(", "); 203 | } 204 | pRMParams += 8; 205 | } 206 | counter++; 207 | } 208 | // if RM file is not valid, load the default one 209 | if (counter == 3) { 210 | Serial.println(F("\n\rLoad default params")); 211 | pRMParams = (uint8_t *)cRMdefaultParams; 212 | } 213 | 214 | return_status = 1; 215 | 216 | while (return_status) { 217 | // write new FAT 218 | return_status = fat_write_content(aFATEntries[0], aFATEntries[1]); 219 | Serial.print(F("Wrote FAT entries: ")); Serial.println(return_status, DEC); 220 | } 221 | 222 | return_status = 1; 223 | 224 | Serial.println(F("Write params")); 225 | 226 | while (return_status) { 227 | // write RM parameters 228 | // write in 4 parts to work with tiny driver 229 | 230 | return_status = 0; 231 | 232 | for (index = 0; index < 4; index++) { 233 | return_status |= nvmem_write(NVMEM_RM_FILEID, 32, 32*index, (pRMParams + 32*index)); 234 | Serial.println(F("Wrote 32 bytes to NVRAM")); 235 | } 236 | } 237 | Serial.println(F("Wrote params")); 238 | 239 | return_status = 1; 240 | 241 | // write back the MAC address, only if exist 242 | if (MACvalid) { 243 | // zero out MCAST bit if set 244 | cMacFromEeprom[0] &= 0xfe; 245 | while (return_status) { 246 | return_status = nvmem_set_mac_address(cMacFromEeprom); 247 | } 248 | } 249 | 250 | ucStatus_Dr = 1; 251 | Serial.println(F("Writing driver patch")); 252 | 253 | while (ucStatus_Dr) { 254 | //writing driver patch to EEPRROM - PORTABLE CODE 255 | // Note that the array itself is changing between the different Service Packs 256 | ucStatus_Dr = nvmem_write_patch(NVMEM_WLAN_DRIVER_SP_FILEID, drv_length, wlan_drv_patch); 257 | } 258 | 259 | 260 | Serial.println(F("Wrote driver patch")); 261 | 262 | Serial.println(F("Writing firmware")); 263 | 264 | unsigned char ucStatus_FW = 1; 265 | 266 | while (ucStatus_FW) { 267 | //writing FW patch to EAPRROM - PORTABLE CODE 268 | //Note that the array itself is changing between the different Service Packs 269 | ucStatus_FW = nvmem_write_patch(NVMEM_WLAN_FW_SP_FILEID, fw_length, fw_patch); 270 | } 271 | 272 | Serial.println(F("Starting w/patches")); 273 | 274 | cc3000.reboot(); 275 | 276 | Serial.println(F("Patched!")); 277 | displayFirmwareVersion(); 278 | displayMACAddress(); 279 | } 280 | 281 | 282 | //***************************************************************************** 283 | // 284 | //! fat_write_content 285 | //! 286 | //! \param[in] file_address array of file address in FAT table:\n 287 | //! this is the absolute address of the file in the EEPROM. 288 | //! \param[in] file_length array of file length in FAT table:\n 289 | //! this is the upper limit of the file size in the EEPROM. 290 | //! 291 | //! \return on succes 0, error otherwise 292 | //! 293 | //! \brief parse the FAT table from eeprom 294 | // 295 | //***************************************************************************** 296 | uint8_t fat_write_content(uint16_t *file_address, uint16_t *file_length) 297 | { 298 | uint16_t index = 0; 299 | uint8_t ucStatus; 300 | uint8_t fatTable[48]; 301 | uint8_t* fatTablePtr = fatTable; 302 | uint8_t LS[3] = "LS"; 303 | 304 | // first, write the magic number 305 | ucStatus = nvmem_write(16, 2, 0, LS); 306 | 307 | for (; index <= NVMEM_RM_FILEID; index++) 308 | { 309 | // write address low char and mark as allocated 310 | *fatTablePtr++ = (uint8_t)(file_address[index] & 0xff) | _BV(0); 311 | 312 | // write address high char 313 | *fatTablePtr++ = (uint8_t)((file_address[index]>>8) & 0xff); 314 | 315 | // write length low char 316 | *fatTablePtr++ = (uint8_t)(file_length[index] & 0xff); 317 | 318 | // write length high char 319 | *fatTablePtr++ = (uint8_t)((file_length[index]>>8) & 0xff); 320 | } 321 | 322 | // second, write the FAT 323 | // write in two parts to work with tiny driver 324 | ucStatus = nvmem_write(16, 24, 4, fatTable); 325 | ucStatus = nvmem_write(16, 24, 24+4, &fatTable[24]); 326 | 327 | // third, we want to erase any user files 328 | memset(fatTable, 0, sizeof(fatTable)); 329 | ucStatus = nvmem_write(16, 16, 52, fatTable); 330 | 331 | return ucStatus; 332 | } 333 | 334 | 335 | void loop(void) 336 | { 337 | delay(1000); 338 | } -------------------------------------------------------------------------------- /examples/driverpatch_1_14/driverpatch_1_14.ino: -------------------------------------------------------------------------------- 1 | // Adafruit CC3000 Firmware V1.14 Upgrade Sketch 2 | // Based on firmware patcher for MSP430 chips published by Texas Instruments. 3 | // 4 | // This sketch will upgrade CC3000 modules up to firmware version 1.14. 5 | // 6 | // You can find more details about the changes in the 1.14 firmware from TI at: 7 | // http://processors.wiki.ti.com/index.php/CC3000_Release_Notes 8 | // 9 | // WARNING: Upgrade firmware at your own risk! In general if the CC3000 is 10 | // currently working fine for your needs then hold off on the upgrade. 11 | // 12 | // Usage (read all the steps before strarting): 13 | // - Wire up your Arduino to the CC3000 just like you're running buildtest or 14 | // other examples. 15 | // - Adjust the ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_VBAT 16 | // defines below to match your wiring (just like running buildtest). 17 | // - Load the sketch on your Arduino and open the serial monitor at 115200 baud. 18 | // - You should see a prompt waiting for a key press to continue. Enter text 19 | // and press enter to start the upgrade. 20 | // - You will see text printed as the firmware is upgraded. The upgrade process 21 | // should be quick and take less than a minute. 22 | // - You might see a message at the end that the firmware version or MAC address 23 | // couldn't be read--this can be ignored. 24 | // - Once the firmware upgrade is complete, run the buildtest sketch to check 25 | // the CC3000 functionality. 26 | // - During the firmware upgrade the CC3000 MAC address might be lost. You can 27 | // write a new MAC address by uncommenting the appropriate line in the buildtest 28 | // example. Make sure to save your MAC address before upgrading the firmware 29 | // if you'd like to keep it the same after 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | // Define _BV macro for platforms without it (Due). 37 | #ifndef _BV 38 | #define _BV(bit) (1 << (bit)) 39 | #endif 40 | 41 | #include "utility/debug.h" 42 | #include "utility/nvmem.h" 43 | #include "driverpatchinc_1_14.h" 44 | 45 | #define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin! 46 | #define ADAFRUIT_CC3000_CS 10 47 | #define ADAFRUIT_CC3000_VBAT 5 48 | 49 | Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT); 50 | 51 | /**************************************************************************/ 52 | /*! 53 | @brief Displays the driver mode (tiny of normal), and the buffer 54 | size if tiny mode is not being used 55 | 56 | @note The buffer size and driver mode are defined in cc3000_common.h 57 | */ 58 | /**************************************************************************/ 59 | void displayDriverMode(void) 60 | { 61 | #ifdef CC3000_TINY_DRIVER 62 | Serial.println(F("CC3000 is configure in 'Tiny' mode")); 63 | #else 64 | Serial.print(F("RX Buffer : ")); 65 | Serial.print(CC3000_RX_BUFFER_SIZE); 66 | Serial.println(F(" bytes")); 67 | Serial.print(F("TX Buffer : ")); 68 | Serial.print(CC3000_TX_BUFFER_SIZE); 69 | Serial.println(F(" bytes")); 70 | #endif 71 | } 72 | 73 | /**************************************************************************/ 74 | /*! 75 | @brief Tries to read the CC3000's internal firmware patch ID 76 | */ 77 | /**************************************************************************/ 78 | void displayFirmwareVersion(void) 79 | { 80 | #ifndef CC3000_TINY_DRIVER 81 | uint8_t major, minor; 82 | 83 | if(!cc3000.getFirmwareVersion(&major, &minor)) 84 | { 85 | Serial.println(F("Unable to retrieve the firmware version!\r\n")); 86 | } 87 | else 88 | { 89 | Serial.print(F("Firmware V. : ")); 90 | Serial.print(major); Serial.print(F(".")); Serial.println(minor); 91 | } 92 | #endif 93 | } 94 | 95 | /**************************************************************************/ 96 | /*! 97 | @brief Tries to read the 6-byte MAC address of the CC3000 module 98 | */ 99 | /**************************************************************************/ 100 | boolean MACvalid = false; 101 | // array to store MAC address from EEPROM 102 | uint8_t cMacFromEeprom[MAC_ADDR_LEN]; 103 | void displayMACAddress(void) 104 | { 105 | if(!cc3000.getMacAddress(cMacFromEeprom)) 106 | { 107 | Serial.println(F("Unable to retrieve MAC Address!\r\n")); 108 | MACvalid = false; 109 | } 110 | else 111 | { 112 | Serial.print(F("MAC Address : ")); 113 | cc3000.printHex((byte*)&cMacFromEeprom, 6); 114 | MACvalid = true; 115 | } 116 | } 117 | 118 | 119 | 120 | /**************************************************************************/ 121 | /*! 122 | @brief Sets up the HW and the CC3000 module (called automatically 123 | on startup) 124 | */ 125 | /**************************************************************************/ 126 | 127 | uint8_t ucStatus_Dr, return_status = 0xFF; 128 | uint8_t counter = 0; 129 | 130 | // array to store RM parameters from EEPROM 131 | unsigned char cRMParamsFromEeprom[128]; 132 | 133 | 134 | // 2 dim array to store address and length of new FAT 135 | uint16_t aFATEntries[2][NVMEM_RM_FILEID + 1] = 136 | /* address */ {{0x50, 0x1f0, 0x1390, 0x0390, 0x2390, 0x4390, 0x6390, 0x63a0, 0x63b0, 0x63f0, 0x6430, 0x6830}, 137 | /* length */ {0x1a0, 0x1a0, 0x1000, 0x1000, 0x2000, 0x2000, 0x10, 0x10, 0x40, 0x40, 0x400, 0x200 }}; 138 | /* 0. NVS */ 139 | /* 1. NVS Shadow */ 140 | /* 2. Wireless Conf */ 141 | /* 3. Wireless Conf Shadow */ 142 | /* 4. BT (WLAN driver) Patches */ 143 | /* 5. WiLink (Firmware) Patches */ 144 | /* 6. MAC addr */ 145 | /* 7. Frontend Vars */ 146 | /* 8. IP config */ 147 | /* 9. IP config Shadow */ 148 | /* 10. Bootloader Patches */ 149 | /* 11. Radio Module params */ 150 | /* 12. AES128 for smart config */ 151 | /* 13. user file */ 152 | /* 14. user file */ 153 | /* 15. user file */ 154 | 155 | 156 | void setup(void) 157 | { 158 | Serial.begin(115200); 159 | Serial.println(F("Hello, CC3000!\n")); 160 | 161 | Serial.println(F("Hit any key & return to start")); 162 | while (!Serial.available()); 163 | 164 | pinMode(9, OUTPUT); 165 | pinMode(8, OUTPUT); 166 | pinMode(7, OUTPUT); 167 | pinMode(6, OUTPUT); 168 | digitalWrite(9, LOW); 169 | digitalWrite(8, LOW); 170 | digitalWrite(7, LOW); 171 | digitalWrite(6, LOW); 172 | 173 | displayDriverMode(); 174 | displayFreeRam(); 175 | 176 | /* Initialise the module */ 177 | Serial.println(F("\nInitialising the CC3000 ...")); 178 | if (!cc3000.begin(2)) // init with NO patches! 179 | { 180 | Serial.println(F("Unable to initialise the CC3000! Check your wiring?")); 181 | while(1); 182 | } 183 | 184 | displayFirmwareVersion(); 185 | displayMACAddress(); 186 | 187 | return_status = 1; 188 | uint8_t index; 189 | uint8_t *pRMParams; 190 | 191 | while ((return_status) && (counter < 3)) { 192 | // read RM parameters 193 | // read in 16 parts to work with tiny driver 194 | 195 | return_status = 0; 196 | pRMParams = cRMParamsFromEeprom; 197 | 198 | for (index = 0; index < 16; index++) { 199 | return_status |= nvmem_read(NVMEM_RM_FILEID, 8, 8*index, pRMParams); 200 | Serial.print(F("\n\rRead NVRAM $")); Serial.print(8*index); Serial.print("\t"); 201 | for(uint8_t x=0; x<8; x++) { 202 | Serial.print("0x"); Serial.print(pRMParams[x], HEX); Serial.print(", "); 203 | } 204 | pRMParams += 8; 205 | } 206 | counter++; 207 | } 208 | // if RM file is not valid, load the default one 209 | if (counter == 3) { 210 | Serial.println(F("\n\rLoad default params")); 211 | pRMParams = (uint8_t *)cRMdefaultParams; 212 | } 213 | 214 | return_status = 1; 215 | 216 | while (return_status) { 217 | // write new FAT 218 | return_status = fat_write_content(aFATEntries[0], aFATEntries[1]); 219 | Serial.print(F("Wrote FAT entries: ")); Serial.println(return_status, DEC); 220 | } 221 | 222 | return_status = 1; 223 | 224 | Serial.println(F("Write params")); 225 | 226 | while (return_status) { 227 | // write RM parameters 228 | // write in 4 parts to work with tiny driver 229 | 230 | return_status = 0; 231 | 232 | for (index = 0; index < 4; index++) { 233 | return_status |= nvmem_write(NVMEM_RM_FILEID, 32, 32*index, (pRMParams + 32*index)); 234 | Serial.println(F("Wrote 32 bytes to NVRAM")); 235 | } 236 | } 237 | Serial.println(F("Wrote params")); 238 | 239 | return_status = 1; 240 | 241 | // write back the MAC address, only if exist 242 | if (MACvalid) { 243 | // zero out MCAST bit if set 244 | cMacFromEeprom[0] &= 0xfe; 245 | while (return_status) { 246 | return_status = nvmem_set_mac_address(cMacFromEeprom); 247 | } 248 | } 249 | 250 | ucStatus_Dr = 1; 251 | Serial.println(F("Writing driver patch")); 252 | 253 | while (ucStatus_Dr) { 254 | //writing driver patch to EEPRROM - PORTABLE CODE 255 | // Note that the array itself is changing between the different Service Packs 256 | ucStatus_Dr = nvmem_write_patch(NVMEM_WLAN_DRIVER_SP_FILEID, drv_length, wlan_drv_patch); 257 | } 258 | 259 | 260 | Serial.println(F("Wrote driver patch")); 261 | 262 | Serial.println(F("Writing firmware")); 263 | 264 | unsigned char ucStatus_FW = 1; 265 | 266 | while (ucStatus_FW) { 267 | //writing FW patch to EAPRROM - PORTABLE CODE 268 | //Note that the array itself is changing between the different Service Packs 269 | ucStatus_FW = nvmem_write_patch(NVMEM_WLAN_FW_SP_FILEID, fw_length, fw_patch); 270 | } 271 | 272 | Serial.println(F("Starting w/patches")); 273 | 274 | cc3000.reboot(); 275 | 276 | Serial.println(F("Patched!")); 277 | displayFirmwareVersion(); 278 | displayMACAddress(); 279 | } 280 | 281 | 282 | //***************************************************************************** 283 | // 284 | //! fat_write_content 285 | //! 286 | //! \param[in] file_address array of file address in FAT table:\n 287 | //! this is the absolute address of the file in the EEPROM. 288 | //! \param[in] file_length array of file length in FAT table:\n 289 | //! this is the upper limit of the file size in the EEPROM. 290 | //! 291 | //! \return on succes 0, error otherwise 292 | //! 293 | //! \brief parse the FAT table from eeprom 294 | // 295 | //***************************************************************************** 296 | uint8_t fat_write_content(uint16_t *file_address, uint16_t *file_length) 297 | { 298 | uint16_t index = 0; 299 | uint8_t ucStatus; 300 | uint8_t fatTable[48]; 301 | uint8_t* fatTablePtr = fatTable; 302 | uint8_t LS[3] = "LS"; 303 | 304 | // first, write the magic number 305 | ucStatus = nvmem_write(16, 2, 0, LS); 306 | 307 | for (; index <= NVMEM_RM_FILEID; index++) 308 | { 309 | // write address low char and mark as allocated 310 | *fatTablePtr++ = (uint8_t)(file_address[index] & 0xff) | _BV(0); 311 | 312 | // write address high char 313 | *fatTablePtr++ = (uint8_t)((file_address[index]>>8) & 0xff); 314 | 315 | // write length low char 316 | *fatTablePtr++ = (uint8_t)(file_length[index] & 0xff); 317 | 318 | // write length high char 319 | *fatTablePtr++ = (uint8_t)((file_length[index]>>8) & 0xff); 320 | } 321 | 322 | // second, write the FAT 323 | // write in two parts to work with tiny driver 324 | ucStatus = nvmem_write(16, 24, 4, fatTable); 325 | ucStatus = nvmem_write(16, 24, 24+4, &fatTable[24]); 326 | 327 | // third, we want to erase any user files 328 | memset(fatTable, 0, sizeof(fatTable)); 329 | ucStatus = nvmem_write(16, 16, 52, fatTable); 330 | 331 | return ucStatus; 332 | } 333 | 334 | 335 | void loop(void) 336 | { 337 | delay(1000); 338 | } -------------------------------------------------------------------------------- /examples/driverpatch_1_11/driverpatch_1_11.ino: -------------------------------------------------------------------------------- 1 | // Adafruit CC3000 Firmware V1.11 Upgrade Sketch 2 | // Based on firmware patcher for MSP430 chips published by Texas Instruments. 3 | // 4 | // This sketch will upgrade CC3000 modules up to firmware version 1.11.1 5 | // 6 | // You can find more details about the changes in the 1.11 firmware from TI at: 7 | // http://processors.wiki.ti.com/index.php/CC3000_Wi-Fi_Downloads_1.11.1 8 | // 9 | // WARNING: Upgrade firmware at your own risk! In general if the CC3000 is 10 | // currently working fine for your needs then hold off on the upgrade. 11 | // 12 | // Usage (read all the steps before strarting): 13 | // - Wire up your Arduino to the CC3000 just like you're running buildtest or 14 | // other examples. 15 | // - Adjust the ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_VBAT 16 | // defines below to match your wiring (just like running buildtest). 17 | // - Load the sketch on your Arduino and open the serial monitor at 115200 baud. 18 | // - You should see a prompt waiting for a key press to continue. Enter text 19 | // and press enter to start the upgrade. 20 | // - You will see text printed as the firmware is upgraded. The upgrade process 21 | // should be quick and take less than a minute. 22 | // - You might see a message at the end that the firmware version or MAC address 23 | // couldn't be read--this can be ignored. 24 | // - Once the firmware upgrade is complete, run the buildtest sketch to check 25 | // the CC3000 functionality. 26 | // - During the firmware upgrade the CC3000 MAC address might be lost. You can 27 | // write a new MAC address by uncommenting the appropriate line in the buildtest 28 | // example. Make sure to save your MAC address before upgrading the firmware 29 | // if you'd like to keep it the same after 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | // Define _BV macro for platforms without it (Due). 37 | #ifndef _BV 38 | #define _BV(bit) (1 << (bit)) 39 | #endif 40 | 41 | #include "utility/debug.h" 42 | #include "utility/nvmem.h" 43 | #include "driverpatchinc.h" 44 | 45 | #define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin! 46 | #define ADAFRUIT_CC3000_CS 10 47 | #define ADAFRUIT_CC3000_VBAT 5 48 | 49 | Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT); 50 | 51 | /**************************************************************************/ 52 | /*! 53 | @brief Displays the driver mode (tiny of normal), and the buffer 54 | size if tiny mode is not being used 55 | 56 | @note The buffer size and driver mode are defined in cc3000_common.h 57 | */ 58 | /**************************************************************************/ 59 | void displayDriverMode(void) 60 | { 61 | #ifdef CC3000_TINY_DRIVER 62 | Serial.println(F("CC3000 is configure in 'Tiny' mode")); 63 | #else 64 | Serial.print(F("RX Buffer : ")); 65 | Serial.print(CC3000_RX_BUFFER_SIZE); 66 | Serial.println(F(" bytes")); 67 | Serial.print(F("TX Buffer : ")); 68 | Serial.print(CC3000_TX_BUFFER_SIZE); 69 | Serial.println(F(" bytes")); 70 | #endif 71 | } 72 | 73 | /**************************************************************************/ 74 | /*! 75 | @brief Tries to read the CC3000's internal firmware patch ID 76 | */ 77 | /**************************************************************************/ 78 | void displayFirmwareVersion(void) 79 | { 80 | #ifndef CC3000_TINY_DRIVER 81 | uint8_t major, minor; 82 | 83 | if(!cc3000.getFirmwareVersion(&major, &minor)) 84 | { 85 | Serial.println(F("Unable to retrieve the firmware version!\r\n")); 86 | } 87 | else 88 | { 89 | Serial.print(F("Firmware V. : ")); 90 | Serial.print(major); Serial.print(F(".")); Serial.println(minor); 91 | } 92 | #endif 93 | } 94 | 95 | /**************************************************************************/ 96 | /*! 97 | @brief Tries to read the 6-byte MAC address of the CC3000 module 98 | */ 99 | /**************************************************************************/ 100 | boolean MACvalid = false; 101 | // array to store MAC address from EEPROM 102 | uint8_t cMacFromEeprom[MAC_ADDR_LEN]; 103 | void displayMACAddress(void) 104 | { 105 | if(!cc3000.getMacAddress(cMacFromEeprom)) 106 | { 107 | Serial.println(F("Unable to retrieve MAC Address!\r\n")); 108 | MACvalid = false; 109 | } 110 | else 111 | { 112 | Serial.print(F("MAC Address : ")); 113 | cc3000.printHex((byte*)&cMacFromEeprom, 6); 114 | MACvalid = true; 115 | } 116 | } 117 | 118 | 119 | 120 | /**************************************************************************/ 121 | /*! 122 | @brief Sets up the HW and the CC3000 module (called automatically 123 | on startup) 124 | */ 125 | /**************************************************************************/ 126 | 127 | uint8_t ucStatus_Dr, return_status = 0xFF; 128 | uint8_t counter = 0; 129 | 130 | // array to store RM parameters from EEPROM 131 | unsigned char cRMParamsFromEeprom[128]; 132 | 133 | 134 | // 2 dim array to store address and length of new FAT 135 | uint16_t aFATEntries[2][NVMEM_RM_FILEID + 1] = 136 | /* address */ {{0x50, 0x1f0, 0x1390, 0x0390, 0x2390, 0x4390, 0x6390, 0x63a0, 0x63b0, 0x63f0, 0x6430, 0x6830}, 137 | /* length */ {0x1a0, 0x1a0, 0x1000, 0x1000, 0x2000, 0x2000, 0x10, 0x10, 0x40, 0x40, 0x400, 0x200 }}; 138 | /* 0. NVS */ 139 | /* 1. NVS Shadow */ 140 | /* 2. Wireless Conf */ 141 | /* 3. Wireless Conf Shadow */ 142 | /* 4. BT (WLAN driver) Patches */ 143 | /* 5. WiLink (Firmware) Patches */ 144 | /* 6. MAC addr */ 145 | /* 7. Frontend Vars */ 146 | /* 8. IP config */ 147 | /* 9. IP config Shadow */ 148 | /* 10. Bootloader Patches */ 149 | /* 11. Radio Module params */ 150 | /* 12. AES128 for smart config */ 151 | /* 13. user file */ 152 | /* 14. user file */ 153 | /* 15. user file */ 154 | 155 | 156 | void setup(void) 157 | { 158 | Serial.begin(115200); 159 | Serial.println(F("Hello, CC3000!\n")); 160 | 161 | Serial.println(F("Hit any key & return to start")); 162 | while (!Serial.available()); 163 | 164 | pinMode(9, OUTPUT); 165 | pinMode(8, OUTPUT); 166 | pinMode(7, OUTPUT); 167 | pinMode(6, OUTPUT); 168 | digitalWrite(9, LOW); 169 | digitalWrite(8, LOW); 170 | digitalWrite(7, LOW); 171 | digitalWrite(6, LOW); 172 | 173 | displayDriverMode(); 174 | displayFreeRam(); 175 | 176 | /* Initialise the module */ 177 | Serial.println(F("\nInitialising the CC3000 ...")); 178 | if (!cc3000.begin(2)) // init with NO patches! 179 | { 180 | Serial.println(F("Unable to initialise the CC3000! Check your wiring?")); 181 | while(1); 182 | } 183 | 184 | displayFirmwareVersion(); 185 | displayMACAddress(); 186 | 187 | return_status = 1; 188 | uint8_t index; 189 | uint8_t *pRMParams; 190 | 191 | while ((return_status) && (counter < 3)) { 192 | // read RM parameters 193 | // read in 16 parts to work with tiny driver 194 | 195 | return_status = 0; 196 | pRMParams = cRMParamsFromEeprom; 197 | 198 | for (index = 0; index < 16; index++) { 199 | return_status |= nvmem_read(NVMEM_RM_FILEID, 8, 8*index, pRMParams); 200 | Serial.print(F("\n\rRead NVRAM $")); Serial.print(8*index); Serial.print("\t"); 201 | for(uint8_t x=0; x<8; x++) { 202 | Serial.print("0x"); Serial.print(pRMParams[x], HEX); Serial.print(", "); 203 | } 204 | pRMParams += 8; 205 | } 206 | counter++; 207 | } 208 | // if RM file is not valid, load the default one 209 | if (counter == 3) { 210 | Serial.println(F("\n\rLoad default params")); 211 | pRMParams = (uint8_t *)cRMdefaultParams; 212 | } 213 | 214 | return_status = 1; 215 | 216 | while (return_status) { 217 | // write new FAT 218 | return_status = fat_write_content(aFATEntries[0], aFATEntries[1]); 219 | Serial.print(F("Wrote FAT entries: ")); Serial.println(return_status, DEC); 220 | } 221 | 222 | return_status = 1; 223 | 224 | Serial.println(F("Write params")); 225 | 226 | while (return_status) { 227 | // write RM parameters 228 | // write in 4 parts to work with tiny driver 229 | 230 | return_status = 0; 231 | 232 | for (index = 0; index < 4; index++) { 233 | return_status |= nvmem_write(NVMEM_RM_FILEID, 32, 32*index, (pRMParams + 32*index)); 234 | Serial.println(F("Wrote 32 bytes to NVRAM")); 235 | } 236 | } 237 | Serial.println(F("Wrote params")); 238 | 239 | return_status = 1; 240 | 241 | // write back the MAC address, only if exist 242 | if (MACvalid) { 243 | // zero out MCAST bit if set 244 | cMacFromEeprom[0] &= 0xfe; 245 | while (return_status) { 246 | return_status = nvmem_set_mac_address(cMacFromEeprom); 247 | } 248 | } 249 | 250 | ucStatus_Dr = 1; 251 | Serial.println(F("Writing driver patch")); 252 | 253 | while (ucStatus_Dr) { 254 | //writing driver patch to EEPRROM - PORTABLE CODE 255 | // Note that the array itself is changing between the different Service Packs 256 | ucStatus_Dr = nvmem_write_patch(NVMEM_WLAN_DRIVER_SP_FILEID, drv_length, wlan_drv_patch); 257 | } 258 | 259 | 260 | Serial.println(F("Wrote driver patch")); 261 | 262 | Serial.println(F("Writing firmware")); 263 | 264 | unsigned char ucStatus_FW = 1; 265 | 266 | while (ucStatus_FW) { 267 | //writing FW patch to EAPRROM - PORTABLE CODE 268 | //Note that the array itself is changing between the different Service Packs 269 | ucStatus_FW = nvmem_write_patch(NVMEM_WLAN_FW_SP_FILEID, fw_length, fw_patch); 270 | } 271 | 272 | Serial.println(F("Starting w/patches")); 273 | 274 | cc3000.reboot(); 275 | 276 | Serial.println(F("Patched!")); 277 | displayFirmwareVersion(); 278 | displayMACAddress(); 279 | } 280 | 281 | 282 | //***************************************************************************** 283 | // 284 | //! fat_write_content 285 | //! 286 | //! \param[in] file_address array of file address in FAT table:\n 287 | //! this is the absolute address of the file in the EEPROM. 288 | //! \param[in] file_length array of file length in FAT table:\n 289 | //! this is the upper limit of the file size in the EEPROM. 290 | //! 291 | //! \return on succes 0, error otherwise 292 | //! 293 | //! \brief parse the FAT table from eeprom 294 | // 295 | //***************************************************************************** 296 | uint8_t fat_write_content(uint16_t *file_address, uint16_t *file_length) 297 | { 298 | uint16_t index = 0; 299 | uint8_t ucStatus; 300 | uint8_t fatTable[48]; 301 | uint8_t* fatTablePtr = fatTable; 302 | uint8_t LS[3] = "LS"; 303 | 304 | // first, write the magic number 305 | ucStatus = nvmem_write(16, 2, 0, LS); 306 | 307 | for (; index <= NVMEM_RM_FILEID; index++) 308 | { 309 | // write address low char and mark as allocated 310 | *fatTablePtr++ = (uint8_t)(file_address[index] & 0xff) | _BV(0); 311 | 312 | // write address high char 313 | *fatTablePtr++ = (uint8_t)((file_address[index]>>8) & 0xff); 314 | 315 | // write length low char 316 | *fatTablePtr++ = (uint8_t)(file_length[index] & 0xff); 317 | 318 | // write length high char 319 | *fatTablePtr++ = (uint8_t)((file_length[index]>>8) & 0xff); 320 | } 321 | 322 | // second, write the FAT 323 | // write in two parts to work with tiny driver 324 | ucStatus = nvmem_write(16, 24, 4, fatTable); 325 | ucStatus = nvmem_write(16, 24, 24+4, &fatTable[24]); 326 | 327 | // third, we want to erase any user files 328 | memset(fatTable, 0, sizeof(fatTable)); 329 | ucStatus = nvmem_write(16, 16, 52, fatTable); 330 | 331 | return ucStatus; 332 | } 333 | 334 | 335 | void loop(void) 336 | { 337 | delay(1000); 338 | } -------------------------------------------------------------------------------- /examples/driverpatch_1_13/driverpatch_1_13.ino: -------------------------------------------------------------------------------- 1 | // Adafruit CC3000 Firmware V1.13 Upgrade Sketch 2 | // Based on firmware patcher for MSP430 chips published by Texas Instruments. 3 | // 4 | // This sketch will upgrade CC3000 modules up to firmware version 1.13. 5 | // 6 | // You can find more details about the changes in the 1.13 firmware from TI at: 7 | // http://processors.wiki.ti.com/index.php/CC3000_Release_Notes 8 | // 9 | // In general the 1.13 release is a bug fix release with fixes for stability 10 | // issues that caused the CC3000 to hang when under load. 11 | // 12 | // WARNING: Upgrade firmware at your own risk! In general if the CC3000 is 13 | // currently working fine for your needs then hold off on the upgrade. 14 | // 15 | // Usage (read all the steps before strarting): 16 | // - Wire up your Arduino to the CC3000 just like you're running buildtest or 17 | // other examples. 18 | // - Adjust the ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_VBAT 19 | // defines below to match your wiring (just like running buildtest). 20 | // - Load the sketch on your Arduino and open the serial monitor at 115200 baud. 21 | // - You should see a prompt waiting for a key press to continue. Enter text 22 | // and press enter to start the upgrade. 23 | // - You will see text printed as the firmware is upgraded. The upgrade process 24 | // should be quick and take less than a minute. 25 | // - You might see a message at the end that the firmware version or MAC address 26 | // couldn't be read--this can be ignored. 27 | // - Once the firmware upgrade is complete, run the buildtest sketch to check 28 | // the CC3000 functionality. 29 | // - During the firmware upgrade the CC3000 MAC address might be lost. You can 30 | // write a new MAC address by uncommenting the appropriate line in the buildtest 31 | // example. Make sure to save your MAC address before upgrading the firmware 32 | // if you'd like to keep it the same after 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | // Define _BV macro for platforms without it (Due). 40 | #ifndef _BV 41 | #define _BV(bit) (1 << (bit)) 42 | #endif 43 | 44 | #include "utility/debug.h" 45 | #include "utility/nvmem.h" 46 | #include "driverpatchinc_1_13.h" 47 | 48 | #define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin! 49 | #define ADAFRUIT_CC3000_CS 10 50 | #define ADAFRUIT_CC3000_VBAT 5 51 | 52 | Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT); 53 | 54 | /**************************************************************************/ 55 | /*! 56 | @brief Displays the driver mode (tiny of normal), and the buffer 57 | size if tiny mode is not being used 58 | 59 | @note The buffer size and driver mode are defined in cc3000_common.h 60 | */ 61 | /**************************************************************************/ 62 | void displayDriverMode(void) 63 | { 64 | #ifdef CC3000_TINY_DRIVER 65 | Serial.println(F("CC3000 is configure in 'Tiny' mode")); 66 | #else 67 | Serial.print(F("RX Buffer : ")); 68 | Serial.print(CC3000_RX_BUFFER_SIZE); 69 | Serial.println(F(" bytes")); 70 | Serial.print(F("TX Buffer : ")); 71 | Serial.print(CC3000_TX_BUFFER_SIZE); 72 | Serial.println(F(" bytes")); 73 | #endif 74 | } 75 | 76 | /**************************************************************************/ 77 | /*! 78 | @brief Tries to read the CC3000's internal firmware patch ID 79 | */ 80 | /**************************************************************************/ 81 | void displayFirmwareVersion(void) 82 | { 83 | #ifndef CC3000_TINY_DRIVER 84 | uint8_t major, minor; 85 | 86 | if(!cc3000.getFirmwareVersion(&major, &minor)) 87 | { 88 | Serial.println(F("Unable to retrieve the firmware version!\r\n")); 89 | } 90 | else 91 | { 92 | Serial.print(F("Firmware V. : ")); 93 | Serial.print(major); Serial.print(F(".")); Serial.println(minor); 94 | } 95 | #endif 96 | } 97 | 98 | /**************************************************************************/ 99 | /*! 100 | @brief Tries to read the 6-byte MAC address of the CC3000 module 101 | */ 102 | /**************************************************************************/ 103 | boolean MACvalid = false; 104 | // array to store MAC address from EEPROM 105 | uint8_t cMacFromEeprom[MAC_ADDR_LEN]; 106 | void displayMACAddress(void) 107 | { 108 | if(!cc3000.getMacAddress(cMacFromEeprom)) 109 | { 110 | Serial.println(F("Unable to retrieve MAC Address!\r\n")); 111 | MACvalid = false; 112 | } 113 | else 114 | { 115 | Serial.print(F("MAC Address : ")); 116 | cc3000.printHex((byte*)&cMacFromEeprom, 6); 117 | MACvalid = true; 118 | } 119 | } 120 | 121 | 122 | 123 | /**************************************************************************/ 124 | /*! 125 | @brief Sets up the HW and the CC3000 module (called automatically 126 | on startup) 127 | */ 128 | /**************************************************************************/ 129 | 130 | uint8_t ucStatus_Dr, return_status = 0xFF; 131 | uint8_t counter = 0; 132 | 133 | // array to store RM parameters from EEPROM 134 | unsigned char cRMParamsFromEeprom[128]; 135 | 136 | 137 | // 2 dim array to store address and length of new FAT 138 | uint16_t aFATEntries[2][NVMEM_RM_FILEID + 1] = 139 | /* address */ {{0x50, 0x1f0, 0x1390, 0x0390, 0x2390, 0x4390, 0x6390, 0x63a0, 0x63b0, 0x63f0, 0x6430, 0x6830}, 140 | /* length */ {0x1a0, 0x1a0, 0x1000, 0x1000, 0x2000, 0x2000, 0x10, 0x10, 0x40, 0x40, 0x400, 0x200 }}; 141 | /* 0. NVS */ 142 | /* 1. NVS Shadow */ 143 | /* 2. Wireless Conf */ 144 | /* 3. Wireless Conf Shadow */ 145 | /* 4. BT (WLAN driver) Patches */ 146 | /* 5. WiLink (Firmware) Patches */ 147 | /* 6. MAC addr */ 148 | /* 7. Frontend Vars */ 149 | /* 8. IP config */ 150 | /* 9. IP config Shadow */ 151 | /* 10. Bootloader Patches */ 152 | /* 11. Radio Module params */ 153 | /* 12. AES128 for smart config */ 154 | /* 13. user file */ 155 | /* 14. user file */ 156 | /* 15. user file */ 157 | 158 | 159 | void setup(void) 160 | { 161 | Serial.begin(115200); 162 | Serial.println(F("Hello, CC3000!\n")); 163 | 164 | Serial.println(F("Hit any key & return to start")); 165 | while (!Serial.available()); 166 | 167 | pinMode(9, OUTPUT); 168 | pinMode(8, OUTPUT); 169 | pinMode(7, OUTPUT); 170 | pinMode(6, OUTPUT); 171 | digitalWrite(9, LOW); 172 | digitalWrite(8, LOW); 173 | digitalWrite(7, LOW); 174 | digitalWrite(6, LOW); 175 | 176 | displayDriverMode(); 177 | displayFreeRam(); 178 | 179 | /* Initialise the module */ 180 | Serial.println(F("\nInitialising the CC3000 ...")); 181 | if (!cc3000.begin(2)) // init with NO patches! 182 | { 183 | Serial.println(F("Unable to initialise the CC3000! Check your wiring?")); 184 | while(1); 185 | } 186 | 187 | displayFirmwareVersion(); 188 | displayMACAddress(); 189 | 190 | return_status = 1; 191 | uint8_t index; 192 | uint8_t *pRMParams; 193 | 194 | while ((return_status) && (counter < 3)) { 195 | // read RM parameters 196 | // read in 16 parts to work with tiny driver 197 | 198 | return_status = 0; 199 | pRMParams = cRMParamsFromEeprom; 200 | 201 | for (index = 0; index < 16; index++) { 202 | return_status |= nvmem_read(NVMEM_RM_FILEID, 8, 8*index, pRMParams); 203 | Serial.print(F("\n\rRead NVRAM $")); Serial.print(8*index); Serial.print("\t"); 204 | for(uint8_t x=0; x<8; x++) { 205 | Serial.print("0x"); Serial.print(pRMParams[x], HEX); Serial.print(", "); 206 | } 207 | pRMParams += 8; 208 | } 209 | counter++; 210 | } 211 | // if RM file is not valid, load the default one 212 | if (counter == 3) { 213 | Serial.println(F("\n\rLoad default params")); 214 | pRMParams = (uint8_t *)cRMdefaultParams; 215 | } 216 | 217 | return_status = 1; 218 | 219 | while (return_status) { 220 | // write new FAT 221 | return_status = fat_write_content(aFATEntries[0], aFATEntries[1]); 222 | Serial.print(F("Wrote FAT entries: ")); Serial.println(return_status, DEC); 223 | } 224 | 225 | return_status = 1; 226 | 227 | Serial.println(F("Write params")); 228 | 229 | while (return_status) { 230 | // write RM parameters 231 | // write in 4 parts to work with tiny driver 232 | 233 | return_status = 0; 234 | 235 | for (index = 0; index < 4; index++) { 236 | return_status |= nvmem_write(NVMEM_RM_FILEID, 32, 32*index, (pRMParams + 32*index)); 237 | Serial.println(F("Wrote 32 bytes to NVRAM")); 238 | } 239 | } 240 | Serial.println(F("Wrote params")); 241 | 242 | return_status = 1; 243 | 244 | // write back the MAC address, only if exist 245 | if (MACvalid) { 246 | // zero out MCAST bit if set 247 | cMacFromEeprom[0] &= 0xfe; 248 | while (return_status) { 249 | return_status = nvmem_set_mac_address(cMacFromEeprom); 250 | } 251 | } 252 | 253 | ucStatus_Dr = 1; 254 | Serial.println(F("Writing driver patch")); 255 | 256 | while (ucStatus_Dr) { 257 | //writing driver patch to EEPRROM - PORTABLE CODE 258 | // Note that the array itself is changing between the different Service Packs 259 | ucStatus_Dr = nvmem_write_patch(NVMEM_WLAN_DRIVER_SP_FILEID, drv_length, wlan_drv_patch); 260 | } 261 | 262 | 263 | Serial.println(F("Wrote driver patch")); 264 | 265 | Serial.println(F("Writing firmware")); 266 | 267 | unsigned char ucStatus_FW = 1; 268 | 269 | while (ucStatus_FW) { 270 | //writing FW patch to EAPRROM - PORTABLE CODE 271 | //Note that the array itself is changing between the different Service Packs 272 | ucStatus_FW = nvmem_write_patch(NVMEM_WLAN_FW_SP_FILEID, fw_length, fw_patch); 273 | } 274 | 275 | Serial.println(F("Starting w/patches")); 276 | 277 | cc3000.reboot(); 278 | 279 | Serial.println(F("Patched!")); 280 | displayFirmwareVersion(); 281 | displayMACAddress(); 282 | } 283 | 284 | 285 | //***************************************************************************** 286 | // 287 | //! fat_write_content 288 | //! 289 | //! \param[in] file_address array of file address in FAT table:\n 290 | //! this is the absolute address of the file in the EEPROM. 291 | //! \param[in] file_length array of file length in FAT table:\n 292 | //! this is the upper limit of the file size in the EEPROM. 293 | //! 294 | //! \return on succes 0, error otherwise 295 | //! 296 | //! \brief parse the FAT table from eeprom 297 | // 298 | //***************************************************************************** 299 | uint8_t fat_write_content(uint16_t *file_address, uint16_t *file_length) 300 | { 301 | uint16_t index = 0; 302 | uint8_t ucStatus; 303 | uint8_t fatTable[48]; 304 | uint8_t* fatTablePtr = fatTable; 305 | uint8_t LS[3] = "LS"; 306 | 307 | // first, write the magic number 308 | ucStatus = nvmem_write(16, 2, 0, LS); 309 | 310 | for (; index <= NVMEM_RM_FILEID; index++) 311 | { 312 | // write address low char and mark as allocated 313 | *fatTablePtr++ = (uint8_t)(file_address[index] & 0xff) | _BV(0); 314 | 315 | // write address high char 316 | *fatTablePtr++ = (uint8_t)((file_address[index]>>8) & 0xff); 317 | 318 | // write length low char 319 | *fatTablePtr++ = (uint8_t)(file_length[index] & 0xff); 320 | 321 | // write length high char 322 | *fatTablePtr++ = (uint8_t)((file_length[index]>>8) & 0xff); 323 | } 324 | 325 | // second, write the FAT 326 | // write in two parts to work with tiny driver 327 | ucStatus = nvmem_write(16, 24, 4, fatTable); 328 | ucStatus = nvmem_write(16, 24, 24+4, &fatTable[24]); 329 | 330 | // third, we want to erase any user files 331 | memset(fatTable, 0, sizeof(fatTable)); 332 | ucStatus = nvmem_write(16, 16, 52, fatTable); 333 | 334 | return ucStatus; 335 | } 336 | 337 | 338 | void loop(void) 339 | { 340 | delay(1000); 341 | } -------------------------------------------------------------------------------- /examples/GeoLocation/GeoLocation.ino: -------------------------------------------------------------------------------- 1 | /*************************************************** 2 | This is an example for the Adafruit CC3000 Wifi Breakout & Shield 3 | 4 | Designed specifically to work with the Adafruit WiFi products: 5 | ----> https://www.adafruit.com/products/1469 6 | 7 | Adafruit invests time and resources providing this open source code, 8 | please support Adafruit and open-source hardware by purchasing 9 | products from Adafruit! 10 | 11 | Written by Limor Fried, Kevin Townsend and Phil Burgess for 12 | Adafruit Industries. BSD license, all text above must be included 13 | in any redistribution 14 | ****************************************************/ 15 | 16 | /* 17 | This example queries the freegeoip.net service to get the local 18 | approximate geographic location based on IP address. Combined with 19 | code in the InternetTime sketch, this can give absolute position and 20 | time, extremely useful for seasonal calculations like sun position, 21 | insolation, day length, etc. Sure, could always add a GPS module or 22 | just plug in values from one's GPS or phone, but this has the dual 23 | luxuries of coming 'free' with the existing WiFi hardware, and being 24 | automatic (albeit a bit less accurate...but totally sufficient for 25 | the applications mentioned). 26 | 27 | Positional accuracy depends on the freegeoip.net database, in turn 28 | based on data collected by maxmind.com. No guarantees this will work 29 | for every location. 30 | 31 | Position should be polled only once, at startup, or very infrequently 32 | if making a mobile network-hopping thing, so as not to overwhelm the 33 | kindly-provided free geolocation service. 34 | */ 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include "utility/debug.h" 41 | 42 | // These are the interrupt and control pins 43 | #define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin! 44 | // These can be any two pins 45 | #define ADAFRUIT_CC3000_VBAT 5 46 | #define ADAFRUIT_CC3000_CS 10 47 | // Use hardware SPI for the remaining pins 48 | // On an UNO, SCK = 13, MISO = 12, and MOSI = 11 49 | Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, 50 | ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, 51 | SPI_CLOCK_DIVIDER); // you can change this clock speed 52 | 53 | #define WLAN_SSID "myNetwork" // cannot be longer than 32 characters! 54 | #define WLAN_PASS "myPassword" 55 | // Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2 56 | #define WLAN_SECURITY WLAN_SEC_WPA2 57 | 58 | Adafruit_CC3000_Client client; 59 | 60 | const unsigned long 61 | dhcpTimeout = 60L * 1000L, // Max time to wait for address from DHCP 62 | connectTimeout = 15L * 1000L, // Max time to wait for server connection 63 | responseTimeout = 15L * 1000L; // Max time to wait for data from server 64 | 65 | // This program prints a few tidbits of information about the current location 66 | // (Country, region (state), city, longitude and latitude). Additional info is 67 | // available but just isn't recorded by this code -- can look at jsonParse() 68 | // function to see how it's done and add what you need (or remove what you don't). 69 | // The total list of available attributes includes: ip, country_code, 70 | // country_name, region_code, region_name, city, zipcode, latitude, longitude, 71 | // metro_code and areacode. 72 | char 73 | country[20], 74 | region[20], 75 | city[20], 76 | name[13], // Temp space for name:value parsing 77 | value[64]; // Temp space for name:value parsing 78 | float 79 | longitude, latitude; 80 | 81 | void setup(void) { 82 | uint32_t ip = 0L, t; 83 | 84 | Serial.begin(115200); 85 | Serial.println(F("Hello, CC3000!")); 86 | 87 | Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC); 88 | 89 | Serial.print(F("Initializing...")); 90 | if(!cc3000.begin()) { 91 | Serial.println(F("failed. Check your wiring?")); 92 | return; 93 | } 94 | 95 | Serial.print(F("OK.\r\nConnecting to network...")); 96 | if(!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) { 97 | Serial.println(F("Failed!")); 98 | return; 99 | } 100 | Serial.println(F("connected!")); 101 | 102 | Serial.print(F("Requesting address from DHCP server...")); 103 | for(t=millis(); !cc3000.checkDHCP() && ((millis() - t) < dhcpTimeout); delay(1000)); 104 | if(cc3000.checkDHCP()) { 105 | Serial.println(F("OK")); 106 | } else { 107 | Serial.println(F("failed")); 108 | return; 109 | } 110 | 111 | while(!displayConnectionDetails()) delay(1000); 112 | 113 | // Look up server's IP address 114 | Serial.print(F("\r\nGetting server IP address...")); 115 | t = millis(); 116 | while((0L == ip) && ((millis() - t) < connectTimeout)) { 117 | if(cc3000.getHostByName("freegeoip.net", &ip)) break; 118 | delay(1000); 119 | } 120 | if(0L == ip) { 121 | Serial.println(F("failed")); 122 | return; 123 | } 124 | cc3000.printIPdotsRev(ip); 125 | Serial.println(); 126 | 127 | // Request JSON-formatted data from server (port 80) 128 | Serial.print(F("Connecting to geo server...")); 129 | client = cc3000.connectTCP(ip, 80); 130 | if(client.connected()) { 131 | Serial.print(F("connected.\r\nRequesting data...")); 132 | client.print(F("GET /json/ HTTP/1.1\r\nHost: freegeoip.net\r\n\r\n")); 133 | } else { 134 | Serial.println(F("failed")); 135 | return; 136 | } 137 | 138 | Serial.print("\r\nReading response..."); 139 | country[0] = region[0] = city[0] = 0; // Clear data 140 | jsonParse(0, 0); 141 | client.close(); 142 | Serial.println(F("OK")); 143 | 144 | /* You need to make sure to clean up after yourself or the CC3000 can freak out */ 145 | /* the next time your try to connect ... */ 146 | Serial.println(F("\nDisconnecting")); 147 | cc3000.disconnect(); 148 | 149 | Serial.print(F("\r\nRESULTS:\r\n Country: ")); 150 | Serial.println(country); 151 | Serial.print(F(" Region: ")); 152 | Serial.println(region); 153 | Serial.print(F(" City: ")); 154 | Serial.println(city); 155 | Serial.print(F(" Longitude: ")); 156 | Serial.println(longitude); 157 | Serial.print(F(" Latitude: ")); 158 | Serial.println(latitude); 159 | } 160 | 161 | void loop(void) { } // Not used by this code 162 | 163 | 164 | bool displayConnectionDetails(void) { 165 | uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv; 166 | 167 | if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv)) { 168 | Serial.println(F("Unable to retrieve the IP Address!\r\n")); 169 | return false; 170 | } else { 171 | Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress); 172 | Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask); 173 | Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway); 174 | Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv); 175 | Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv); 176 | Serial.println(); 177 | return true; 178 | } 179 | } 180 | 181 | 182 | // Helper functions swiped from Adafruit 'Gutenbird' code (with changes) 183 | 184 | boolean jsonParse(int depth, byte endChar) { 185 | int c, i; 186 | boolean readName = true; 187 | for(;;) { 188 | while(isspace(c = timedRead())); // Scan past whitespace 189 | if(c < 0) return false; // Timeout 190 | if(c == endChar) return true; // EOD 191 | 192 | if(c == '{') { // Object follows 193 | if(!jsonParse(depth + 1, '}')) return false; 194 | if(!depth) return true; // End of file 195 | } else if(c == '[') { // Array follows 196 | if(!jsonParse(depth + 1,']')) return false; 197 | } else if((c == '"') || (c == '\'')) { // String follows 198 | if(readName) { // Name-reading mode 199 | if(!readString(name, sizeof(name)-1, c)) return false; 200 | } else { // Value-reading mode 201 | if(!readString(value, sizeof(value)-1, c)) return false; 202 | // Process name and value strings: 203 | if (!strcasecmp(name, "country_name")) { 204 | strncpy(country, value, sizeof(country)-1); 205 | } else if(!strcasecmp(name, "region_name")) { 206 | strncpy(region, value, sizeof(region)-1); 207 | } else if(!strcasecmp(name, "city")) { 208 | strncpy(city, value, sizeof(city)-1); 209 | } 210 | } 211 | } else if(c == ':') { // Separator between name:value 212 | readName = false; // Now in value-reading mode 213 | value[0] = 0; // Clear existing value data 214 | } else if(c == ',') { // Separator between name/value pairs 215 | readName = true; // Now in name-reading mode 216 | name[0] = 0; // Clear existing name data 217 | } else { 218 | // Else true/false/null or a number follows. 219 | value[0] = c; 220 | if(!strcasecmp(name, "longitude")) { 221 | if(!readString(value+1, sizeof(value)-1, ',')) return false; 222 | longitude = atof(value); 223 | } else if(!strcasecmp(name, "latitude")) { 224 | if(!readString(value+1, sizeof(value)-1, ',')) return false; 225 | latitude = atof(value); 226 | } 227 | readName = true; // Now in name-reading mode 228 | name[0] = 0; // Clear existing name data 229 | } 230 | } 231 | } 232 | 233 | // Read string from client stream into destination buffer, up to a maximum 234 | // requested length. Buffer should be at least 1 byte larger than this to 235 | // accommodate NUL terminator. Opening quote is assumed already read, 236 | // closing quote will be discarded, and stream will be positioned 237 | // immediately following the closing quote (regardless whether max length 238 | // is reached -- excess chars are discarded). Returns true on success 239 | // (including zero-length string), false on timeout/read error. 240 | boolean readString(char *dest, int maxLen, char quote) { 241 | int c, len = 0; 242 | 243 | while((c = timedRead()) != quote) { // Read until closing quote 244 | if(c == '\\') { // Escaped char follows 245 | c = timedRead(); // Read it 246 | // Certain escaped values are for cursor control -- 247 | // there might be more suitable printer codes for each. 248 | if (c == 'b') c = '\b'; // Backspace 249 | else if(c == 'f') c = '\f'; // Form feed 250 | else if(c == 'n') c = '\n'; // Newline 251 | else if(c == 'r') c = '\r'; // Carriage return 252 | else if(c == 't') c = '\t'; // Tab 253 | else if(c == 'u') c = unidecode(4); 254 | else if(c == 'U') c = unidecode(8); 255 | // else c is unaltered -- an escaped char such as \ or " 256 | } // else c is a normal unescaped char 257 | 258 | if(c < 0) return false; // Timeout 259 | 260 | // In order to properly position the client stream at the end of 261 | // the string, characters are read to the end quote, even if the max 262 | // string length is reached...the extra chars are simply discarded. 263 | if(len < maxLen) dest[len++] = c; 264 | } 265 | 266 | dest[len] = 0; 267 | return true; // Success (even if empty string) 268 | } 269 | 270 | // Read a given number of hexadecimal characters from client stream, 271 | // representing a Unicode symbol. Return -1 on error, else return nearest 272 | // equivalent glyph in printer's charset. (See notes below -- for now, 273 | // always returns '-' or -1.) 274 | int unidecode(byte len) { 275 | int c, v, result = 0; 276 | while(len--) { 277 | if((c = timedRead()) < 0) return -1; // Stream timeout 278 | if ((c >= '0') && (c <= '9')) v = c - '0'; 279 | else if((c >= 'A') && (c <= 'F')) v = 10 + c - 'A'; 280 | else if((c >= 'a') && (c <= 'f')) v = 10 + c - 'a'; 281 | else return '-'; // garbage 282 | result = (result << 4) | v; 283 | } 284 | 285 | return '?'; 286 | } 287 | 288 | // Read from client stream with a 5 second timeout. Although an 289 | // essentially identical method already exists in the Stream() class, 290 | // it's declared private there...so this is a local copy. 291 | int timedRead(void) { 292 | unsigned long start = millis(); 293 | while((!client.available()) && ((millis() - start) < 5000L)); 294 | return client.read(); // -1 on timeout 295 | } 296 | 297 | --------------------------------------------------------------------------------