diff --git a/examples/README.txt b/examples/README.txt index ad0a36fa8..66f221770 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -193,11 +193,6 @@ examples/canard Example application for canutils/libcarnard. -examples/cc3000 -^^^^^^^^^^^^^^^ - - This is a test for the TI CC3000 wireless networking module. - examples/cctype ^^^^^^^^^^^^^^^ diff --git a/examples/cc3000/.gitignore b/examples/cc3000/.gitignore deleted file mode 100644 index fa1ec7579..000000000 --- a/examples/cc3000/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -/Make.dep -/.depend -/.built -/*.asm -/*.obj -/*.rel -/*.lst -/*.sym -/*.adb -/*.lib -/*.src diff --git a/examples/cc3000/Kconfig b/examples/cc3000/Kconfig deleted file mode 100644 index 9b1d8b306..000000000 --- a/examples/cc3000/Kconfig +++ /dev/null @@ -1,27 +0,0 @@ -# -# For a description of the syntax of this configuration file, -# see the file kconfig-language.txt in the NuttX tools repository. -# - -config EXAMPLES_CC3000BASIC - bool "A Basic Application to use CC3000 Module" - default n - depends on WL_CC3000 - ---help--- - Enable the CC3000BASIC example - -if EXAMPLES_CC3000BASIC - -config EXAMPLES_CC3000_MEM_CHECK - bool "Memory check instrumentation" - default n - ---help--- - Define to help debug memory issues - -config EXAMPLES_CC3000_STACK_CHECK - bool "Stack check instrumentation" - default n - ---help--- - Define to help debug stack size issues - -endif diff --git a/examples/cc3000/Make.defs b/examples/cc3000/Make.defs deleted file mode 100644 index bae631e10..000000000 --- a/examples/cc3000/Make.defs +++ /dev/null @@ -1,39 +0,0 @@ -############################################################################ -# apps/examples/cc3000/Make.defs -# Adds selected applications to apps/ build -# -# Copyright (C) 2015 Gregory Nutt. All rights reserved. -# Author: Gregory Nutt -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 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. -# 3. Neither the name NuttX nor the names of its contributors may be -# used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -############################################################################ - -ifeq ($(CONFIG_EXAMPLES_CC3000BASIC),y) -CONFIGURED_APPS += examples/cc3000 -endif diff --git a/examples/cc3000/Makefile b/examples/cc3000/Makefile deleted file mode 100644 index 2f34323fc..000000000 --- a/examples/cc3000/Makefile +++ /dev/null @@ -1,159 +0,0 @@ -############################################################################ -# apps/examples/cc3000/Makefile -# -# Copyright (C) 2008, 2010-2013 Gregory Nutt. All rights reserved. -# Author: Gregory Nutt -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 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. -# 3. Neither the name NuttX nor the names of its contributors may be -# used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -############################################################################ - --include $(TOPDIR)/.config --include $(TOPDIR)/Make.defs -include $(APPDIR)/Make.defs - -# Hello, World! built-in application info - -APPNAME = c3b -PRIORITY = SCHED_PRIORITY_DEFAULT -STACKSIZE = 608 - -APPNAME1 = shell -PRIORITY1 = SCHED_PRIORITY_DEFAULT -STACKSIZE1 = 980 - -# Hello, World! Example - -ASRCS = -CSRCS = board.c telnetd_driver.c telnetd_daemon.c - -CC3000SRC = cc3000basic.c -SHELLSRC = shell.c -MAINSRC = $(CC3000SRC) $(SHELLSRC) - -AOBJS = $(ASRCS:.S=$(OBJEXT)) -COBJS = $(CSRCS:.c=$(OBJEXT)) - -CC3000OBJ = $(CC3000SRC:.c=$(OBJEXT)) -SHELLOBJ = $(SHELLSRC:.c=$(OBJEXT)) -MAINOBJ = $(MAINSRC:.c=$(OBJEXT)) - -SRCS = $(ASRCS) $(CSRCS) $(MAINSRC) -OBJS = $(AOBJS) $(COBJS) - -ifneq ($(CONFIG_BUILD_KERNEL),y) - OBJS += $(MAINOBJ) -endif - -ifeq ($(CONFIG_WINDOWS_NATIVE),y) - BIN = ..\..\libapps$(LIBEXT) -else -ifeq ($(WINTOOL),y) - BIN = ..\\..\\libapps$(LIBEXT) -else - BIN = ../../libapps$(LIBEXT) -endif -endif - -ifeq ($(WINTOOL),y) - INSTALL_DIR = "${shell cygpath -w $(BIN_DIR)}" -else - INSTALL_DIR = $(BIN_DIR) -endif - -CONFIG_XYZ_PROGNAME1 ?= cc3000$(EXEEXT) -PROGNAME1 = $(CONFIG_XYZ_PROGNAME1) - -CONFIG_XYZ_PROGNAME2 ?= shell$(EXEEXT) -PROGNAME2 = $(CONFIG_XYZ_PROGNAME2) - -ROOTDEPPATH = --dep-path . - -# Common build - -VPATH = - -all: .built -.PHONY: clean depend distclean preconfig -.PRECIOUS: ../../libapps$(LIBEXT) - -$(AOBJS): %$(OBJEXT): %.S - $(call ASSEMBLE, $<, $@) - -$(COBJS) $(MAINOBJ): %$(OBJEXT): %.c - $(call COMPILE, $<, $@) - -.built: $(OBJS) - $(call ARCHIVE, $(BIN), $(OBJS)) - @touch .built - -ifeq ($(CONFIG_BUILD_KERNEL),y) -$(BIN_DIR)$(DELIM)$(PROGNAME1): $(OBJS) $(CC3000OBJ) - @echo "LD: $(PROGNAME1)" - $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME1) $(ARCHCRT0OBJ) $(MAINOBJ) $(LDLIBS) - $(Q) $(NM) -u $(INSTALL_DIR)$(DELIM)$(PROGNAME1) - -$(BIN_DIR)$(DELIM)$(PROGNAME2): $(OBJS) $(SHELLOBJ) - @echo "LD: $(PROGNAME2)" - $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME2) $(ARCHCRT0OBJ) $(MAINOBJ) $(LDLIBS) - $(Q) $(NM) -u $(INSTALL_DIR)$(DELIM)$(PROGNAME2) - -install: $(BIN_DIR)$(DELIM)$(PROGNAME1) $(BIN_DIR)$(DELIM)$(PROGNAME2) - -else -install: - -endif - -ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) -$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile - $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) - $(call REGISTER,$(APPNAME1),$(PRIORITY1),$(STACKSIZE1),$(APPNAME1)_main) - -context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat -else -context: -endif - -.depend: Makefile $(SRCS) - @$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep - @touch $@ - -depend: .depend - -clean: - $(call DELFILE, .built) - $(call CLEAN) - -distclean: clean - $(call DELFILE, Make.dep) - $(call DELFILE, .depend) - -preconfig: - --include Make.dep diff --git a/examples/cc3000/board.c b/examples/cc3000/board.c deleted file mode 100644 index c8a6423be..000000000 --- a/examples/cc3000/board.c +++ /dev/null @@ -1,178 +0,0 @@ -/**************************************************************************** - * apps/examples/cc3000/board.c - * - * This code is based on the TI sample code "Basic WiFi Application" - * and has the callback routines that TI expects for their library. - * - * TI uses callback routines to make their library portable: these routines, - * and the routines in the SPI files, will be different for an Arduino, - * a TI MSP430, a PIC, etc. but the core library shouldn't have to be - * changed. - * - * Derives from an application to demo an Arduino connected to the TI CC3000 - * - * Copyright (C) 2013 Chris Magagna - cmagagna@yahoo.com - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Don't sue me if my code blows up your board and burns down your house - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include "board.h" -#include -#include -#include -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define NETAPP_IPCONFIG_MAC_OFFSET (20) -#define CC3000_APP_BUFFER_SIZE (5) -#define CC3000_RX_BUFFER_OVERHEAD_SIZE (20) - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -volatile unsigned long ulSmartConfigFinished, - ulCC3000Connected, - ulCC3000DHCP, - OkToDoShutDown, - ulCC3000DHCP_configured; - -volatile uint8_t ucStopSmartConfig; - -uint8_t asyncNotificationWaiting = false; -long lastAsyncEvent; -uint8_t dhcpIPAddress[4]; - -/**************************************************************************** - * Public Functions - ****************************************************************************/ -/* The TI library calls this routine when asynchronous events happen. - * - * For example you tell the CC3000 to turn itself on and connect - * to an access point then your code can go on to do its own thing. - * When the CC3000 is done configuring itself (e.g. it gets an IP - * address from the DHCP server) it will call this routine so you - * can take appropriate action. - */ - -void CC3000_AsyncCallback(long lEventType, char * data, uint8_t length) -{ - lastAsyncEvent = lEventType; - - switch (lEventType) - { - case HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE: - ulSmartConfigFinished = 1; - ucStopSmartConfig = 1; - asyncNotificationWaiting=true; - break; - - case HCI_EVNT_WLAN_UNSOL_CONNECT: - ulCC3000Connected = 1; - asyncNotificationWaiting=true; - break; - - case HCI_EVNT_WLAN_UNSOL_DISCONNECT: - ulCC3000Connected = 0; - ulCC3000DHCP = 0; - ulCC3000DHCP_configured = 0; - asyncNotificationWaiting=true; - break; - - case HCI_EVNT_WLAN_UNSOL_DHCP: - /* Notes: - * 1) IP config parameters are received swapped - * 2) IP config parameters are valid only if status is OK, i.e. ulCC3000DHCP becomes 1 - * only if status is OK, the flag is set to 1 and the addresses are valid - */ - - if (*(data + NETAPP_IPCONFIG_MAC_OFFSET) == 0) - { - ulCC3000DHCP = 1; - dhcpIPAddress[0] = data[3]; - dhcpIPAddress[1] = data[2]; - dhcpIPAddress[2] = data[1]; - dhcpIPAddress[3] = data[0]; - } - else - { - ulCC3000DHCP = 0; - dhcpIPAddress[0] = 0; - dhcpIPAddress[1] = 0; - dhcpIPAddress[2] = 0; - dhcpIPAddress[3] = 0; - } - asyncNotificationWaiting=true; - break; - - case HCI_EVENT_CC3000_CAN_SHUT_DOWN: - OkToDoShutDown = 1; - asyncNotificationWaiting=true; - break; - - default: - asyncNotificationWaiting=true; - break; - } -} - -/* The TI library calls these routines on CC3000 startup. - * - * This library does not send firmware, driver, or bootloader patches - * so we do nothing and we return NULL. - */ - -char *SendFirmwarePatch(unsigned long *Length) -{ - *Length = 0; - return NULL; -} - -char *SendDriverPatch(unsigned long *Length) -{ - *Length = 0; - return NULL; -} - -char *SendBootloaderPatch(unsigned long *Length) -{ - *Length = 0; - return NULL; -} - -/* This is my routine to simplify CC3000 startup. - * - * It sets the Arduino pins then calls the normal CC3000 routines - * wlan_init() with all the callbacks and wlan_start() with 0 - * to indicate we're not sending any patches. - */ - -void CC3000_Init(void) -{ - static bool once = false; - - if (!once) - { - wireless_archinitialize(132); - once = true; - } - - cc3000_wlan_init(132, CC3000_AsyncCallback, - SendFirmwarePatch, - SendDriverPatch, - SendBootloaderPatch); - - wlan_start(0); -} diff --git a/examples/cc3000/board.h b/examples/cc3000/board.h deleted file mode 100644 index df1d87085..000000000 --- a/examples/cc3000/board.h +++ /dev/null @@ -1,179 +0,0 @@ -/**************************************************************************** - * This file is part of the ArduinoCC3000 library. - * Version 1.0.1b - * - * Copyright (C) 2013 Chris Magagna - cmagagna@yahoo.com - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Don't sue me if my code blows up your board and burns down your house - * - * This file is the main module for the Arduino CC3000 library. - * Your program must call CC3000_Init() before any other API calls. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Some things are different for the Teensy 3.0, so set a flag if we're using - * that hardware. - */ - -#if defined(__arm__) && defined(CORE_TEENSY) && defined(__MK20DX128__) -# define TEENSY3 1 -#endif - -/* I used the Teensy 3.0 to get the Arduino CC3000 library working but the - Teensy's hardware SPI and the CC3000's SPI didn't like each other so I had - to send the bits manually. For the Uno, Nano, etc. you can probably leave - this unchanged. If your Arduino can't talk to the CC3000 and you're sure - your wiring is OK then try changing this. */ - -#ifdef TEENSY3 -#define USE_HARDWARE_SPI false -#else -#define USE_HARDWARE_SPI true -#endif - -// These are the Arduino pins that connect to the CC3000 -// (in addition to standard SPI pins MOSI, MISO, and SCK) -// -// The WLAN_IRQ pin must be supported by attachInterrupt -// on your platform - -#ifndef TEENSY3 - -#define WLAN_CS 10 // Arduino pin connected to CC3000 WLAN_SPI_CS -#define WLAN_EN 9 // Arduino pin connected to CC3000 VBAT_SW_EN -#define WLAN_IRQ 3 // Arduino pin connected to CC3000 WLAN_SPI_IRQ -#define WLAN_IRQ_INTNUM 1 // The attachInterrupt() number that corresponds - // to WLAN_IRQ -#define WLAN_MOSI MOSI -#define WLAN_MISO MISO -#define WLAN_SCK SCK -#else - -#define WLAN_CS 25 -#define WLAN_MISO 26 -#define WLAN_IRQ 27 -#define WLAN_IRQ_INTNUM 27 // On the Teensy 3.0 the interrupt # is the same as the pin # -#define WLAN_MOSI 28 -#define WLAN_SCK 29 -#define WLAN_EN 30 - -#endif - -/* The timing between setting the CS pin and reading the IRQ pin is very - * tight on the CC3000, and sometimes the default Arduino digitalRead() - * and digitalWrite() functions are just too slow. - * - * For many of the CC3000 library functions this isn't a big deal because the - * IRQ pin is tied to an interrupt routine but some of them of them disable - * the interrupt routine and read the pins directly. Because digitalRead() - * / Write() are so slow once in a while the Arduino will be in the middle of - * its pin code and the CC3000 will flip another pin's state and it will be - * missed, and everything locks up. - * - * The upshot of all of this is we need to read & write the pin states - * directly, which is very fast compared to the built in Arduino functions. - * - * The Teensy 3.0's library has built in macros called digitalReadFast() - * & digitalWriteFast() that compile down to direct port manipulations but - * are still readable, so use those if possible. - * - * There's a digitalReadFast() / digitalWriteFast() library for Arduino but - * it looks like it hasn't been updated since 2010 so I think it's best to - * just use the direct port manipulations. - */ - -#ifdef TEENSY3 - -#define Read_CC3000_IRQ_Pin() digitalReadFast(WLAN_IRQ) -#define Set_CC3000_CS_NotActive() digitalWriteFast(WLAN_CS, HIGH) -#define Set_CC3000_CS_Active() digitalWriteFast(WLAN_CS, LOW) - -#else - -// This is hardcoded for an ATMega328 and pin 3. You will need to change this -// for other MCUs or pins - -#define Read_CC3000_IRQ_Pin() ((PIND & B00001000) ? 1 : 0) - -// This is hardcoded for an ATMega328 and pin 10. You will need to change this -// for other MCUs or pins -#define Set_CC3000_CS_NotActive() PORTB |= B00000100 -#define Set_CC3000_CS_Active() PORTB &= B11111011 - -#endif - -#define MAC_ADDR_LEN 6 -#define DISABLE (0) -#define ENABLE (1) - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -#if 0 -/* AES key "smartconfigAES16" */ - -const uint8_t smartconfigkey[] = - { - 0x73, 0x6d, 0x61, 0x72, 0x74, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x41, 0x45, 0x53, 0x31, 0x36 - }; -#endif - -/* If you uncomment the line below the library will leave out a lot of the - * higher level functions but use a lot less memory. From: - * - * http://processors.wiki.ti.com/index.php/Tiny_Driver_Support - * - * CC3000's new driver has flexible memory compile options. - * - * This feature comes in handy when we want to use a limited RAM size MCU. - * - * Using The Tiny Driver Compilation option will create a tiny version of our - * host driver with lower data, stack and code consumption. - * - * By enabling this feature, host driver's RAM consumption can be reduced to - * minimum of 251 bytes. - * - * The Tiny host driver version will limit the host driver API to the most - * essential ones. - * - * Code size depends on actual APIs used. - * - * RAM size depends on the largest packet sent and received. - * - * CC3000 can now be used with ultra low cost MCUs, consuming 251 byte of RAM - * and 2K to 6K byte of code size, depending on the API usage. - */ - -//#define CC3000_TINY_DRIVER 1 - -extern uint8_t asyncNotificationWaiting; -extern long lastAsyncEvent; -extern uint8_t dhcpIPAddress[]; -extern volatile unsigned long ulSmartConfigFinished; -extern volatile unsigned long ulCC3000Connected; -extern volatile unsigned long ulCC3000DHCP; -extern volatile unsigned long OkToDoShutDown; -extern volatile unsigned long ulCC3000DHCP_configured; -extern volatile uint8_t ucStopSmartConfig; - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -void CC3000_Init(void); diff --git a/examples/cc3000/cc3000basic.c b/examples/cc3000/cc3000basic.c deleted file mode 100644 index b71de3edb..000000000 --- a/examples/cc3000/cc3000basic.c +++ /dev/null @@ -1,987 +0,0 @@ -/**************************************************************************** - * apps/examples/cc3000basic.c - * - * Derives from an application to demo an Arduino connected to the TI CC3000 - * - * Copyright (C) 2013 Chris Magagna - cmagagna@yahoo.com - * Port to nuttx: - * Alan Carvalho de Assis - * David Sidrane - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Don't sue me if my code blows up your board and burns down your house - * - **************************************************************************** - * - * To connect an Arduino to the CC3000 you'll need to make these 6 connections - * (in addition to the WiFi antenna, power etc). - * - * Name / pin on CC3000 module / pin on CC3000EM board / purpose - * - * SPI_CS / 12 / J4-8 / SPI Chip Select - * The Arduino will set this pin LOW when it wants to - * exchange data with the CC3000. By convention this is - * Arduino pin 10, but any pin can be used. In this - * program it will be called WLAN_CS - * - * SPI_DOUT / 13 / J4-9 / Data from the module to the Arduino - * This is Arduino's MISO pin, and is how the CC3000 - * will get bytes to the Arduino. For most Arduinos - * MISO is pin 12 - * - * SPI_IRQ / 14 / J4-10 / CC3000 host notify - * The CC3000 will drive this pin LOW to let the Arduino - * know it's ready to send data. For a regular Arduino - * (Uno, Nano, Leonardo) this will have to be connected - * to pin 2 or 3 so you can use attachInterrupt(). In - * this program it will be called WLAN_IRQ - * - * SPI_DIN / 15 / J4-11 Data from the Arduino to the CC3000 - * This is the Arduino's MOSI pin, and is how the Arduino - * will get bytes to the CC3000. For most Arduinos - * MOSI is pin 11 - * - * SPI_CLK / 17 / J4-12 SPI clock - * This is the Arduino's SCK pin. For most Arduinos - * SCK is pin 13 - * - * VBAT_SW_EN / 26 / J5-5 Module enable - * The Arduino will set this pin HIGH to turn the CC3000 - * on. Any pin can be used. In this program it will be - * called WLAN_EN - * - * WARNING #1: The CC3000 runs at 3.6V maximum so you can't run it from your - * regular 5V Arduino power pin. Run it from 3.3V! - * - * WARNING #2: When transmitting the CC3000 will use up to 275mA current. Most - * Arduinos' 3.3V pins can only supply up to 50mA current, so you'll need a - * separate power supply for it (or a voltage regulator like the LD1117V33 - * connected to your Arduino's 5V power pin). - * - * WARNING #3: The CC3000's IO pins are not 5V tolerant. If you're using a 5V - * Arduino you will need a level shifter to convert these signals to 3.3V - * so you don't blow up the module. - * - * You'll need to shift the pins for WLAN_CS, MOSI, SCK, and WLAN_EN. MISO can be - * connected directly because it's an input pin for the Arduino and the Arduino - * can read 3.3V signals directly. For WLAN_IRQ use a pullup resistor of 20K to - * 100K Ohm -- one leg to the Arduino input pin + CC3000 SPI_IRQ pin, the other - * leg to +3.3V. - * - * You can use a level shifter chip like the 74LVC245 or TXB0104 or you can use - * a pair of resistors to make a voltage divider like this: - * - * Arduino pin -----> 560 Ohm --+--> 1K Ohm -----> GND - * | - * | - * +---> CC3000 pin - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -/* - * Memory Analyses - * - * total used free largest - * Mem: 16560 11144 5416 5384 - * PID SIZE USED THREAD NAME - * 0 0 0 Idle Task - * 1 876 772 init - * 2 604 588 c3b - * 3 236 220 - * - * 8 364 348 - * - * 9 260 196 - * 10 380 364 Telnet dd - * 11 860 844 Telnet sd - */ - -#include - -#include "board.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "shell.h" - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -void Initialize(void); -void helpme(void); -int execute(int cmd); -void ShowBufferSize(void); -void StartSmartConfig(void); -void ManualConnect(void); -void ManualAddProfile(void); -void ListAccessPoints(void); -void PrintIPBytes(uint8_t *ipBytes); -void ShowInformation(void); - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define MS_PER_SEC 1000 -#define US_PER_MS 1000 -#define US_PER_SEC 1000000 - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static uint8_t isInitialized = false; - -#ifdef CONFIG_EXAMPLES_CC3000_MEM_CHECK -static struct mallinfo mmstart; -static struct mallinfo mmprevious; -#endif - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -#ifdef CONFIG_EXAMPLES_CC3000_MEM_CHECK -static void show_memory_usage(struct mallinfo *mmbefore, - struct mallinfo *mmafter) -{ - int diff; - - printf(" total used free largest\n"); - printf("Before:%11d%11d%11d%11d\n", - mmbefore->arena, mmbefore->uordblks, mmbefore->fordblks, mmbefore->mxordblk); - printf("After: %11d%11d%11d%11d\n", - mmafter->arena, mmafter->uordblks, mmafter->fordblks, mmafter->mxordblk); - - diff = mmbefore->uordblks - mmafter->uordblks; - if (diff < 0) - { - printf("Change:%11d allocated\n", -diff); - } - else if (diff > 0) - { - printf("Change:%11d freed\n", diff); - } - -#ifdef CONFIG_EXAMPLES_CC3000_STACK_CHECK - stkmon_disp(); -#endif -} -#endif - -#ifdef CONFIG_EXAMPLES_CC3000_STACK_CHECK -static char buff[CONFIG_TASK_NAME_SIZE+1]; -static void _stkmon_disp(FAR struct tcb_s *tcb, FAR void *arg) -{ -#if CONFIG_TASK_NAME_SIZE > 0 - strncpy(buff,tcb->name,CONFIG_TASK_NAME_SIZE); - buff[CONFIG_TASK_NAME_SIZE] = '\0'; - syslog(LOG_INFO, "%5d %6d %6d %s\n", - tcb->pid, tcb->adj_stack_size, up_check_tcbstack(tcb), buff); -#else - syslog(LOG_INFO, "%5d %6d %6d\n", - tcb->pid, tcb->adj_stack_size, up_check_tcbstack(tcb)); -#endif -} -#endif - -static bool wait(long timeoutMs, volatile unsigned long *what, - volatile unsigned long is) -{ - long t_ms; - struct timeval end, start; - - gettimeofday(&start, NULL); - - while (*what != is) - { - usleep(10*US_PER_MS); - gettimeofday(&end, NULL); - t_ms = ((end.tv_sec - start.tv_sec) * MS_PER_SEC) + ((end.tv_usec - start.tv_usec) / US_PER_MS) ; - if (t_ms > timeoutMs) - { - return false; - } - } - - return true; -} - -static bool wait_on(long timeoutMs, volatile unsigned long *what, - volatile unsigned long is, char * msg) -{ - printf(msg); - printf("..."); - fflush(stdout); - bool ret = wait(timeoutMs,what,is); - if (!ret) - { - printf(" FAILED:Timeout!\n"); - } - else - { - printf(" Succeed\n"); - } - - fflush(stdout); - return ret; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -#ifndef CONFIG_EXAMPLES_CC3000_STACK_CHECK -# define stkmon_disp() -#else -void stkmon_disp(void) -{ -#if CONFIG_TASK_NAME_SIZE > 0 - syslog(LOG_INFO, "%-5s %-6s %-6s %s\n", "PID", "SIZE", "USED", "THREAD NAME"); -#else - syslog(LOG_INFO, "%-5s %-6s %-6s\n", "PID", "SIZE", "USED"); -#endif - sched_foreach(_stkmon_disp, NULL); -} -#endif - -void AsyncEventPrint(void) -{ - printf("\n"); - switch (lastAsyncEvent) - { - printf("CC3000 Async event: Simple config done\n"); - break; - - case HCI_EVNT_WLAN_UNSOL_CONNECT: - printf("CC3000 Async event: Unsolicited connect\n"); - break; - - case HCI_EVNT_WLAN_UNSOL_DISCONNECT: - printf("CC3000 Async event: Unsolicted disconnect\n"); - break; - - case HCI_EVNT_WLAN_UNSOL_DHCP: - printf("CC3000 Async event: Got IP address via DHCP: "); - printf("%d", dhcpIPAddress[0]); - printf("."); - printf("%d", dhcpIPAddress[1]); - printf("."); - printf("%d", dhcpIPAddress[2]); - printf("."); - printf("%d\n", dhcpIPAddress[3]); - break; - - case HCI_EVENT_CC3000_CAN_SHUT_DOWN: - printf("CC3000 Async event: OK to shut down\n"); - break; - - case HCI_EVNT_WLAN_KEEPALIVE: - /* Once initialized, the CC3000 will send these keepalive events - * every 20 seconds. - */ - - printf("CC3000 Async event: Keepalive\n"); - return; - break; - - default: - printf("AsyncCallback called with unhandled event! (0x%lx)\n", - (unsigned long)lastAsyncEvent); - break; - } -} - -void helpme(void) -{ - printf("\n+-------------------------------------------+\n"); - printf("| Nuttx CC3000 Demo Program |\n"); - printf("+-------------------------------------------+\n\n"); - printf(" 01 - Initialize the CC3000\n"); - printf(" 02 - Show RX & TX buffer sizes, & free RAM\n"); - printf(" 03 - Start Smart Config\n"); - printf(" 04 - Manually connect to AP\n"); - printf(" 05 - Manually add connection profile\n"); - printf(" 06 - List access points\n"); - printf(" 07 - Show CC3000 information\n"); - printf(" 08 - Telnet\n"); - printf("\n Type 01-07 to select above option: "); -} - -int execute(int cmd) -{ - int ret = 0; - if (asyncNotificationWaiting) - { - asyncNotificationWaiting = false; - AsyncEventPrint(); - } - - printf("\n"); - switch(cmd) - { - case '1': - Initialize(); - break; - - case '2': - ShowBufferSize(); - break; - - case '3': - StartSmartConfig(); - break; - - case '4': - ManualConnect(); - break; - - case '5': - ManualAddProfile(); - break; - - case '6': - ListAccessPoints(); - break; - - case '7': - ShowInformation(); - break; - - case '8': - if (!isInitialized) - { - Initialize(); - } - -#ifdef CONFIG_EXAMPLES_CC3000_MEM_CHECK - mmprevious= mallinfo(); - show_memory_usage(&mmstart,&mmprevious); -#endif - shell_main(0, 0); -#ifdef CONFIG_EXAMPLES_CC3000_MEM_CHECK - mmprevious= mallinfo(); - show_memory_usage(&mmstart,&mmprevious); -#endif - break; - - case 'q': - case 'Q': - ret = 1; - break; - - default: - printf("**Unknown command \"%d\" **\n", cmd); - break; - } - - return ret; -} - -void Initialize(void) -{ -#ifdef CONFIG_EXAMPLES_CC3000_MEM_CHECK - mmstart = mallinfo(); - memcpy(&mmprevious, &mmstart, sizeof(struct mallinfo)); - show_memory_usage(&mmstart,&mmprevious); -#endif - - uint8_t fancyBuffer[MAC_ADDR_LEN]; - - if (isInitialized) - { - printf("CC3000 already initialized. Shutting down and restarting...\n"); - wlan_stop(); - usleep(1000000); /* Delay 1s */ - } - - printf("Initializing CC3000...\n"); - CC3000_Init(); -#ifdef CONFIG_EXAMPLES_CC3000_STACK_CHECK - stkmon_disp(); -#endif - printf(" CC3000 init complete.\n"); - - if (nvmem_read_sp_version(fancyBuffer) == 0) - { - printf(" Firmware version is: "); - printf("%d", fancyBuffer[0]); - printf("."); - printf("%d\n", fancyBuffer[1]); - } - else - { - printf("Unable to get firmware version. Can't continue.\n"); - return; - } - -#if 0 - if (nvmem_get_mac_address(fancyBuffer) == 0) - { - printf(" MAC address: "); - for (i = 0; i < MAC_ADDR_LEN; i++) - { - if (i != 0) - { - printf(":"); - } - printf("%x", fancyBuffer[i]); - } - - printf("\n"); - isInitialized = true; - } - else - { - printf("Unable to get MAC address. Can't continue.\n"); - } -#else - isInitialized = true; -#endif - -#ifdef CONFIG_EXAMPLES_CC3000_MEM_CHECK - mmprevious = mallinfo(); - show_memory_usage(&mmstart,&mmprevious); -#endif -} - -/* This just shows the compiled size of the transmit & recieve buffers */ - -void ShowBufferSize(void) -{ - printf("Transmit buffer is %d bytes", CC3000_TX_BUFFER_SIZE); - printf("Receive buffer is %d bytes", CC3000_RX_BUFFER_SIZE); -} - -/* Smart Config is TI's way to let you connect your device to your WiFi network - * without needing a keyboard and display to enter the network name, password, - * etc. You run a little app on your iPhone, Android device, or laptop with Java - * and it sends the config info to the CC3000 automagically, so the end user - * doesn't need to do anything complicated. More details here: - * - * http://processors.wiki.ti.com/index.php/CC3000_Smart_Config - * - * This example deletes any currently saved WiFi profiles and goes over the top - * with error checking, so it's easier to see exactly what's going on. You - * probably won't need all of this code for your own Smart Config implementation. - * - * This example also doesn't use any of the AES enhanced security setup API calls - * because frankly they're weirder than I want to deal with. - */ - -/* The Simple Config Prefix always needs to be 'TTT' */ - -char simpleConfigPrefix[] = {'T', 'T', 'T'}; - -/* This is the default Device Name that TI's Smart Config app for iPhone etc. use. - * You can change it to whatever you want, but then your users will need to type - * that name into their phone or tablet when they run Smart Config. - */ - -char device_name[] = "CC3000"; - -void StartSmartConfig(void) -{ - long rval; - - if (!isInitialized) - { - printf("CC3000 not initialized; can't run Smart Config.\n"); - return; - } - - printf("Starting Smart Config\n"); - - printf(" Disabling auto-connect policy..."); - if ((rval = wlan_ioctl_set_connection_policy(DISABLE, DISABLE, DISABLE)) !=0) - { - printf(" Failed!\n Setting auto connection policy failed, error: %lx\n", - (unsigned long)rval); - return; - } - - printf(" Succeed\n"); - printf(" Deleting all existing profiles..."); - fflush(stdout); - - if ((rval = wlan_ioctl_del_profile(255)) !=0) - { - printf(" Failed!\n Deleting all profiles failed, error: %lx\n", - (unsigned long)rval); - return; - } - - printf(" Succeed\n"); - wait_on(20*MS_PER_SEC, &ulCC3000Connected, 0, " Waiting until disconnected"); - - printf(" Setting smart config prefix..."); - fflush(stdout); - - if ((rval = wlan_smart_config_set_prefix(simpleConfigPrefix)) !=0) - { - printf(" Failed!\n Setting smart config prefix failed, error: %lx", - (unsigned long)rval); - return; - } - - printf(" Succeed\n"); - printf(" Starting smart config..."); - fflush(stdout); - - if ((rval = wlan_smart_config_start(0)) !=0) - { - printf(" Failed!\n Starting smart config failed, error: %lx\n", - (unsigned long)rval); - return; - } - - printf(" Succeed\n"); - - if (!wait_on(30*MS_PER_SEC, &ulSmartConfigFinished, 1, " Waiting on Starting smart config done")) - { - printf(" Timed out waiting for Smart Config to finish. Hopefully it did anyway\n"); - } - - printf(" Smart Config packet %s!\n",ulSmartConfigFinished ? "seen" : "NOT seen"); - - printf(" Enabling auto-connect policy..."); - fflush(stdout); - - if ((rval = wlan_ioctl_set_connection_policy(DISABLE, DISABLE, ENABLE)) !=0) - { - printf(" Failed!\n Setting auto connection policy failed, error: %lx\n", - (unsigned long)rval); - return; - } - - printf(" Succeed\n"); - printf(" Stopping CC3000...\n"); - fflush(stdout); - wlan_stop(); /* No error returned here, so nothing to check */ - - printf(" Pausing for 2 seconds...\n"); - usleep(2000000); - - printf(" Restarting CC3000... \n"); - wlan_start(0); /* No error returned here, so nothing to check */ - - if (!wait_on(20*MS_PER_SEC, &ulCC3000Connected, 1, " Waiting for connection to AP")) - { - printf(" Timed out waiting for connection to AP\n"); - return; - } - - if (!wait_on(15*MS_PER_SEC, &ulCC3000DHCP, 1, " Waiting for IP address from DHCP")) - { - printf(" Timed out waiting for IP address from DHCP\n"); - return; - } - - printf(" Sending mDNS broadcast to signal we're done with Smart Config...\n"); - fflush(stdout); - - /* The API documentation says mdnsAdvertiser() is supposed to return 0 on - * success and SOC_ERROR on failure, but it looks like what it actually - * returns is the socket number it used. So we ignore it. - */ - - mdnsadvertiser(1, device_name, strlen(device_name)); - - printf(" Smart Config finished Successfully!\n"); - ShowInformation(); - fflush(stdout); -} - -/* This is an example of how you'd connect the CC3000 to an AP without using - * Smart Config or a stored profile. - * - * All the code above wlan_connect() is just for this demo program; if you're - * always going to connect to your network this way you wouldn't need it. - */ - -void ManualConnect(void) -{ - char ssidName[] = "YourAP"; - char AP_KEY[] = "yourpass"; - uint8_t rval; - - if (!isInitialized) - { - printf("CC3000 not initialized; can't run manual connect.\n"); - return; - } - - printf("Starting manual connect...\n"); - - printf(" Disabling auto-connect policy...\n"); - (void)wlan_ioctl_set_connection_policy(DISABLE, DISABLE, DISABLE); - - printf(" Deleting all existing profiles...\n"); - (void)wlan_ioctl_del_profile(255); - - wait_on(15*MS_PER_SEC, &ulCC3000Connected, 0, " Waiting until disconnected"); - - printf(" Manually connecting...\n"); - - /* Parameter 1 is the security type: WLAN_SEC_UNSEC, WLAN_SEC_WEP, - * WLAN_SEC_WPA or WLAN_SEC_WPA2 - * Parameter 3 is the MAC adddress of the AP. All the TI examples - * use NULL. I suppose you would want to specify this - * if you were security paranoid. - */ - - rval = wlan_connect(WLAN_SEC_WPA2, - ssidName, - strlen(ssidName), - NULL, - (uint8_t *)AP_KEY, - strlen(AP_KEY)); - - if (rval == 0) - { - printf(" Manual connect success.\n"); - } - else - { - printf(" Unusual return value: %d\n", rval); - } -} - -/* This is an example of manually adding a WLAN profile to the CC3000. See - * wlan_ioctl_set_connection_policy() for more details of how profiles are - * used but basically there's 7 slots where you can store AP info and if - * the connection policy is set to auto_start then the CC3000 will go - * through its profile table and try to auto-connect to something it knows - * about after it boots up. - * - * Note the API documentation for wlan_add_profile is wrong. It says it - * returns 0 on success and -1 on failure. What it really returns is - * the stored profile number (0-6, since the CC3000 can store 7) or - * 255 on failure. - * - * Unfortunately the API doesn't give you any way to see how many profiles - * are in use or which profile is stored in which slot, so if you want to - * manage multiple profiles you'll need to do that yourself. - */ - -void ManualAddProfile(void) -{ - char ssidName[] = "YourAP"; - char AP_KEY[] = "yourpass"; - uint8_t rval; - - if (!isInitialized) - { - printf("CC3000 not initialized; can't run manual add profile."); - return; - } - - printf("Starting manual add profile...\n"); - - printf(" Disabling auto connection...\n"); - wlan_ioctl_set_connection_policy(DISABLE, DISABLE, DISABLE); - - printf(" Adding profile...\n"); - rval = wlan_add_profile ( - WLAN_SEC_WPA2, /* WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2 */ - (uint8_t *)ssidName, - strlen(ssidName), - NULL, /* BSSID, TI always uses NULL */ - 0, /* Profile priority */ - 0x18, /* Key length for WEP security, undocumented why this needs to be 0x18 */ - 0x1e, /* Key index, undocumented why this needs to be 0x1e */ - 0x2, /* key management, undocumented why this needs to be 2 */ - (uint8_t *)AP_KEY, /* WPA security key */ - strlen(AP_KEY) /* WPA security key length */ - ); - - if (rval!=255) - { - /* This code is lifted from http://e2e.ti.com/support/low_power_rf/f/851/p/180859/672551.aspx; - * the actual API documentation on wlan_add_profile doesn't specify any of this.... - */ - - printf(" Manual add profile success, stored in profile: %d\n", rval); - - printf(" Enabling auto connection...\n"); - wlan_ioctl_set_connection_policy(DISABLE, DISABLE, ENABLE); - - printf(" Stopping CC3000...\n"); - wlan_stop(); - - printf(" Stopping for 5 seconds...\n"); - usleep(5000000); - - printf(" Restarting CC3000...\n"); - wlan_start(0); - - printf(" Manual add profile done!"); - } - else - { - printf(" Manual add profile failured (all profiles full?)."); - } -} - -/* The call wlan_ioctl_get_scan_results returns this structure. I couldn't - * find it in the TI library so it's defined here. It's 50 bytes with - * a semi weird arrangement but fortunately it's not as bad as it looks. - * - * numNetworksFound - 4 bytes - On the first call to wlan_ioctl_get_scan_results - * this will be set to how many APs the CC3000 sees. Although - * with 4 bytes the CC3000 could see 4 billion APs in my testing - * this number was always 20 or less so there's probably an - * internal memory limit. - * - * results - 4 bytes - 0=aged results, 1=results valid, 2=no results. Why TI - * used 32 bits to store something that could be done in 2, - * and how this field is different than isValid below, is - * a mystery to me so I just igore this field completely. - * - * isValid & rssi - 1 byte - a packed structure. The top bit (isValid) - * indicates whether or not this structure has valid data, - * the bottom 7 bits (rssi) are the signal strength of this AP. - * - * securityMode & ssidLength - 1 byte - another packed structure. The top 2 - * bits (securityMode) show how the AP is configured: - * 0 - open / no security - * 1 - WEP - * 2 - WPA - * 3 - WPA2 - * ssidLength is the lower 6 bytes and shows how many characters - * (up to 32) of the ssid_name field are valid - * - * frameTime - 2 bytes - how long, in seconds, since the CC3000 saw this AP - * beacon - * - * ssid_name - 32 bytes - The ssid name for this AP. Note that this isn't a - * regular null-terminated C string so you can't use it - * directly with a strcpy() or Serial.println() etc. and you'll - * need a 33-byte string to store it (32 valid characters + - * null terminator) - * - * bssid - 6 bytes - the MAC address of this AP - */ - -typedef struct scanResults -{ - unsigned long numNetworksFound; - unsigned long results; - unsigned isValid:1; - unsigned rssi:7; - unsigned securityMode:2; - unsigned ssidLength:6; - uint16_t frameTime; - uint8_t ssid_name[32]; - uint8_t bssid[6]; -} scanResults; - -#define NUM_CHANNELS 16 - -void ListAccessPoints(void) -{ - unsigned long aiIntervalList[NUM_CHANNELS]; - uint8_t rval; - scanResults sr; - int apCounter, i; - char localB[33]; - - if (!isInitialized) - { - printf("CC3000 not initialized; can't list access points.\n"); - return; - } - - printf("List visible access points\n"); - - printf(" Setting scan parameters...\n"); - - for (i=0; i0) - { - if ((rval=wlan_ioctl_get_scan_results(2000, (uint8_t *)&sr)) !=0) - { - printf(" Got back unusual result from wlan_ioctl_get scan, can't continue: %d\n", rval); - return; - } - } - } - while (apCounter>0); - - printf(" Access Point list finished.\n"); -} - -void PrintIPBytes(uint8_t *ipBytes) -{ - printf("%d.%d.%d.%d\n", ipBytes[3], ipBytes[2], ipBytes[1], ipBytes[0]); -} - -/* All the data in all the fields from netapp_ipconfig() are reversed, - * e.g. an IP address is read via bytes 3,2,1,0 instead of bytes - * 0,1,2,3 and the MAC address is read via bytes 5,4,3,2,1,0 instead - * of 0,1,2,3,4,5. - * - * N.B. TI is inconsistent here; nvmem_get_mac_address() returns them in - * the right order etc. - */ - -void ShowInformation(void) -{ - tNetappIpconfigRetArgs inf; - char localB[33]; - int i; - - if (!isInitialized) - { - printf("CC3000 not initialized; can't get information.\n"); - return; - } - - printf("CC3000 information:\n"); - - netapp_ipconfig(&inf); - - printf(" IP address: "); - PrintIPBytes(inf.aucIP); - - printf(" Subnet mask: "); - PrintIPBytes(inf.aucSubnetMask); - - printf(" Gateway: "); - PrintIPBytes(inf.aucDefaultGateway); - - printf(" DHCP server: "); - PrintIPBytes(inf.aucDHCPServer); - - printf(" DNS server: "); - PrintIPBytes(inf.aucDNSServer); - - printf(" MAC address: "); - for (i=(MAC_ADDR_LEN-1); i>=0; i--) - { - if (i!=(MAC_ADDR_LEN-1)) - { - printf(":"); - } - printf("%x", inf.uaMacAddr[i]); - } - - printf("\n"); - - memset(localB, 0, sizeof(localB)); - strncpy(localB, (char*)inf.uaSSID,sizeof(localB)); - - printf(" Connected to SSID: %s\n", localB); -} - -#ifdef CONFIG_BUILD_KERNEL -int main(int argc, FAR char *argv[]) -#else -int c3b_main(int argc, char *argv[]) -#endif -{ - char ch='0'; - - do - { - helpme(); - stkmon_disp(); - - ch = getchar(); - - } - while (execute(ch) == 0); - - return 0; -} diff --git a/examples/cc3000/shell.c b/examples/cc3000/shell.c deleted file mode 100644 index a1d8deb9b..000000000 --- a/examples/cc3000/shell.c +++ /dev/null @@ -1,238 +0,0 @@ -/**************************************************************************** - * apps/examples/cc3000/shell.c - * - * Copyright (C) 2013, 2017 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * This is a leverage of similar logic from uIP: - * - * Author: Adam Dunkels - * Copyright (c) 2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 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. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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. - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include -#include - -#include -#include - -#include "netutils/telnetd.h" -#include "netutils/netlib.h" - -#include "shell.h" -#include "nshlib/nshlib.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -struct ptentry_s -{ - FAR const char *commandstr; - void (*pfunc)(int argc, char **argv); -}; - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -static void shell_help(int argc, char **argv); -static void shell_quit(int argc, char **argv); -static void shell_unknown(int argc, char **argv); -static void shell_parse(FAR char *line, int len); - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static struct ptentry_s g_parsetab[] = -{ - {"help", shell_help}, - {"exit", shell_quit}, - {"?", shell_help}, - {NULL, shell_unknown} -}; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: shell_help - ****************************************************************************/ - -static void shell_help(int argc, char **argv) -{ - printf("Available commands:\n"); - printf(" help, ? - show help\n"); - printf(" exit - exit shell\n"); -} - -/**************************************************************************** - * Name: shell_help - ****************************************************************************/ - -static void shell_unknown(int argc, char **argv) -{ - if (argv[0]) - { - printf("Unknown command: %s\n", argv[0]); - } -} - -/**************************************************************************** - * Name: shell_quit - ****************************************************************************/ - -static void shell_quit(int argc, char **argv) -{ - printf("Bye!\n"); -#ifdef CONFIG_EXAMPLES_CC3000_MEM_CHECK - stkmon_disp(); -#endif - exit(0); -} - -/**************************************************************************** - * Name: shell_parse - ****************************************************************************/ - -static void shell_parse(FAR char *line, int len) -{ - struct ptentry_s *entry; - FAR char *cmd; - FAR char *saveptr; - - /* Get the command from the beginning the line */ - - cmd = strtok_r(line, " \t\n\r\f\v", &saveptr); - if (cmd) - { - /* Now find the matching command in the command table */ - - for (entry = g_parsetab; entry->commandstr != NULL; entry++) - { - if (strncmp(entry->commandstr, cmd, strlen(entry->commandstr)) == 0) - { - break; - } - } - - entry->pfunc(1, &cmd); - } -} - -/**************************************************************************** - * Name: shell_session - ****************************************************************************/ - -int shell_session(int argc, char *argv[]) -{ - char line[128]; - - printf("CC3000 command shell -- NuttX style\n"); - printf("Type '?' and return for help\n"); -#ifdef CONFIG_EXAMPLES_CC3000_MEM_CHECK - stkmon_disp(); -#endif - - for (;;) - { - printf(SHELL_PROMPT); - fflush(stdout); - - if (fgets(line, 128, stdin) == NULL) - { - break; - } - - shell_parse(line, 128); - } - - return 0; -} - -/**************************************************************************** - * Name: shell_netinit - ****************************************************************************/ - -static void shell_netinit(void) -{ - -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -#ifdef CONFIG_BUILD_KERNEL -int main(int argc, FAR char *argv[]) -#else -int shell_main(int argc, char *argv[]) -#endif -{ - struct telnetd_config_s config; - int ret; - - /* Configure the network */ - - printf("shell_main: Initializing the network\n"); - shell_netinit(); - - /* Configure the telnet daemon */ - - config.d_port = HTONS(23); - config.d_family = AF_INET; - config.d_priority = CONFIG_EXAMPLES_TELNETD_DAEMONPRIO; - config.d_stacksize = CONFIG_EXAMPLES_TELNETD_DAEMONSTACKSIZE; - config.t_priority = CONFIG_EXAMPLES_TELNETD_CLIENTPRIO; - config.t_stacksize = CONFIG_EXAMPLES_TELNETD_CLIENTSTACKSIZE; - config.t_entry = nsh_consolemain; - - /* Start the telnet daemon */ - - printf("shell_main: Starting the Telnet daemon\n"); - ret = telnetd_start(&config); - if (ret < 0) - { - printf("Failed to tart the Telnet daemon\n"); - } - - printf("shell_main: Exiting\n"); - return 0; -} diff --git a/examples/cc3000/shell.h b/examples/cc3000/shell.h deleted file mode 100644 index b247c993c..000000000 --- a/examples/cc3000/shell.h +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** - * apps/examples/cc3000/shell.h - * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. - * - ****************************************************************************/ - -#ifndef __APPS_EXAMPLES_CC3000_SHELL_H -#define __APPS_EXAMPLES_CC3000_SHELL_H - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ -/* Configuration ************************************************************/ -/* CONFIG_EXAMPLES_TELNETD_DAEMONPRIO - Priority of the Telnet daemon. - * Default: SCHED_PRIORITY_DEFAULT - * CONFIG_EXAMPLES_TELNETD_DAEMONSTACKSIZE - Stack size allocated for the - * Telnet daemon. Default: 2048 - * CONFIG_EXAMPLES_TELNETD_CLIENTPRIO- Priority of the Telnet client. - * Default: SCHED_PRIORITY_DEFAULT - * CONFIG_EXAMPLES_TELNETD_CLIENTSTACKSIZE - Stack size allocated for the - * Telnet client. Default: 2048 - * CONFIG_EXAMPLES_TELNETD_NOMAC - If the hardware has no MAC address of its - * own, define this =y to provide a bogus address for testing. - * CONFIG_EXAMPLES_TELNETD_IPADDR - The target IP address. Default 10.0.0.2 - * CONFIG_EXAMPLES_TELNETD_DRIPADDR - The default router address. Default - * 10.0.0.1 - * CONFIG_EXAMPLES_TELNETD_NETMASK - The network mask. Default: 255.255.255.0 - */ - -#ifndef CONFIG_EXAMPLES_TELNETD_DAEMONPRIO -# define CONFIG_EXAMPLES_TELNETD_DAEMONPRIO SCHED_PRIORITY_DEFAULT -#endif - -#ifndef CONFIG_EXAMPLES_TELNETD_DAEMONSTACKSIZE -# define CONFIG_EXAMPLES_TELNETD_DAEMONSTACKSIZE 384 -#endif - -#ifndef CONFIG_EXAMPLES_TELNETD_CLIENTPRIO -# define CONFIG_EXAMPLES_TELNETD_CLIENTPRIO SCHED_PRIORITY_DEFAULT -#endif - -#ifndef CONFIG_EXAMPLES_TELNETD_CLIENTSTACKSIZE -# define CONFIG_EXAMPLES_TELNETD_CLIENTSTACKSIZE 894 -#endif - -/* Other definitions ********************************************************/ - -#define SHELL_PROMPT "CC3000 1.0> " - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -int shell_main(int argc, char *argv[]); - -#endif /* __APPS_EXAMPLES_CC3000_SHELL_H */ diff --git a/examples/cc3000/telnetd.h b/examples/cc3000/telnetd.h deleted file mode 100644 index d4858864d..000000000 --- a/examples/cc3000/telnetd.h +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** - * apps/examples/cc3000/telnetd.c - * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 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. - * 3. Neither the name Gregory Nutt nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -#ifndef __APPS_EXAMPLES_CC3000_TELNETD_H -#define __APPS_EXAMPLES_CC3000_TELNETD_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -/* This structure represents the overall state of one telnet daemon instance - * (Yes, multiple telnet daemons are supported). - */ - -struct telnetd_s -{ - int port; /* The port to listen on (in network byte order) */ - int priority; /* The execution priority of the spawned task, */ - int stacksize; /* The stack size needed by the spawned task */ - main_t entry; /* The entrypoint of the task to spawn when a new - * connection is accepted. */ -}; - -/* This structure is used to passed information to telnet daemon when it - * started. It contains global information visable to all telnet daemons. - */ - -struct telnetd_common_s -{ - uint8_t ndaemons; /* The total number of daemons running */ - sem_t startsem; /* Enforces one-at-a-time startup */ - sem_t exclsem; /* Enforces exclusive access to 'minor' */ - FAR struct telnetd_s *daemon; /* Describes the new daemon */ - int minor; /* The next minor number to use */ -}; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/* This structure is used to passed information to telnet daemon when it - * started. It contains global information visable to all telnet daemons. - */ - -extern struct telnetd_common_s g_telnetdcommon; - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: telnetd_driver - * - * Description: - * Create a character driver to "wrap" the telnet session. This function - * will select and return a unique path for the new telnet device. - * - * Parameters: - * sd - The socket descriptor that represents the new telnet connection. - * daemon - A pointer to the structure representing the overall state of - * this instance of the telnet daemon. - * - * Return: - * An allocated string represent the full path to the created driver. The - * receiver of the string must de-allocate this memory when it is no longer - * needed. NULL is returned on a failure. - * - ****************************************************************************/ - -FAR char *telnetd_driver(long sd, FAR struct telnetd_s *daemon); - -#endif /* __APPS_EXAMPLES_CC3000_TELNETD_H */ - diff --git a/examples/cc3000/telnetd_daemon.c b/examples/cc3000/telnetd_daemon.c deleted file mode 100644 index eb908744b..000000000 --- a/examples/cc3000/telnetd_daemon.c +++ /dev/null @@ -1,349 +0,0 @@ -/**************************************************************************** - * apps/examples/cc3000/telnetd_daemon.c - * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 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. - * 3. Neither the name Gregory Nutt nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "netutils/telnetd.h" -#include "netutils/netlib.h" - -#include "telnetd.h" - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/* This structure is used to passed information to telnet daemon when it - * started. - */ - -struct telnetd_common_s g_telnetdcommon; - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: telnetd_daemon - * - * Description: - * This function is the Telnet daemon. It does not return (unless an - * error occurs). - * - * Parameters: - * Standard task start up arguments. - * - * Return: - * Does not return unless an error occurs. - * - ****************************************************************************/ - -static int telnetd_daemon(int argc, char *argv[]) -{ - FAR struct telnetd_s *daemon; - struct sockaddr_in myaddr; -#ifdef CONFIG_NET_SOLINGER - struct linger ling; -#endif - socklen_t addrlen; - FAR char *devpath; - pid_t pid; - int listensd; - int acceptsd; - int drvrfd; -#ifdef CONFIG_NET_HAVE_REUSEADDR - int optval; -#endif - - /* Get daemon startup info */ - - daemon = g_telnetdcommon.daemon; - g_telnetdcommon.daemon = NULL; - sem_post(&g_telnetdcommon.startsem); - DEBUGASSERT(daemon != NULL); - - /* Create a new TCP socket to use to listen for connections */ - - listensd = socket(PF_INET, SOCK_STREAM, 0); - if (listensd < 0) - { - int errval = errno; - nerr("ERROR: socket failure: %d\n", errval); - return -errval; - } - - /* Set socket to reuse address */ - -#ifdef CONFIG_NET_HAVE_REUSEADDR - optval = 1; - if (setsockopt(listensd, SOL_SOCKET, SO_REUSEADDR, (void*)&optval, sizeof(int)) < 0) - { - nerr("ERROR: setsockopt SO_REUSEADDR failure: %d\n", errno); - goto errout_with_socket; - } -#endif - - /* Bind the socket to a local address */ - - myaddr.sin_family = AF_INET; - myaddr.sin_port = daemon->port; - myaddr.sin_addr.s_addr = INADDR_ANY; - - if (bind(listensd, (struct sockaddr*)&myaddr, sizeof(struct sockaddr_in)) < 0) - { - nerr("ERROR: bind failure: %d\n", errno); - goto errout_with_socket; - } - - /* Listen for connections on the bound TCP socket */ - - if (listen(listensd, 5) < 0) - { - nerr("ERROR: listen failure %d\n", errno); - goto errout_with_socket; - } - - /* Now go silent. */ - -#ifndef CONFIG_DEBUG_FEATURES - close(0); - close(1); - close(2); -#endif - - /* Begin accepting connections */ - - for (;;) - { - ninfo("Accepting connections on port %d\n", ntohs(daemon->port)); - - addrlen = sizeof(struct sockaddr_in); - acceptsd = accept(listensd, (struct sockaddr*)&myaddr, &addrlen); - if (acceptsd < 0) - { - nerr("ERROR: accept failed: %d\n", errno); - goto errout_with_socket; - } - - /* Configure to "linger" until all data is sent when the socket is closed */ - -#ifdef CONFIG_NET_SOLINGER - ling.l_onoff = 1; - ling.l_linger = 30; /* timeout is seconds */ - if (setsockopt(acceptsd, SOL_SOCKET, SO_LINGER, &ling, sizeof(struct linger)) < 0) - { - nerr("ERROR: setsockopt failed: %d\n", errno); - goto errout_with_acceptsd; - } -#endif - - /* Create a character device to "wrap" the accepted socket descriptor */ - - ninfo("Creating the telnet driver\n"); - devpath = telnetd_driver(acceptsd, daemon); - if (devpath == NULL) - { - nerr("ERROR: telnetd_driver failed\n"); - goto errout_with_acceptsd; - } - - /* Open the driver */ - - ninfo("Opening the telnet driver\n"); - drvrfd = open(devpath, O_RDWR); - if (drvrfd < 0) - { - nerr("ERROR: Failed to open %s: %d\n", devpath, errno); - goto errout_with_acceptsd; - } - - /* We can now free the driver string */ - - free(devpath); - - /* Use this driver as stdin, stdout, and stderror */ - - (void)dup2(drvrfd, 0); - (void)dup2(drvrfd, 1); - (void)dup2(drvrfd, 2); - - /* And we can close our original driver fd */ - - if (drvrfd > 2) - { - close(drvrfd); - } - - /* Create a task to handle the connection. The created task - * will inherit the new stdin, stdout, and stderr. - */ - - ninfo("Starting the telnet session\n"); - pid = task_create("Telnet session", daemon->priority, daemon->stacksize, - daemon->entry, NULL); - if (pid < 0) - { - nerr("ERROR: Failed start the telnet session: %d\n", errno); - goto errout_with_acceptsd; - } - - /* Forget about the connection. */ - - close(0); - close(1); - close(2); - } - -errout_with_acceptsd: - close(acceptsd); - -errout_with_socket: - close(listensd); - free(daemon); - return 1; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: telnetd_start - * - * Description: - * Start the telnet daemon. - * - * Parameters: - * config A pointer to a configuration structure that characterizes the - * telnet daemon. This configuration structure may be defined - * on the caller's stack because it is not retained by the - * daemon. - * - * Return: - * The process ID (pid) of the new telnet daemon is returned on - * success; A negated errno is returned if the daemon was not successfully - * started. - * - ****************************************************************************/ - -int telnetd_start(FAR struct telnetd_config_s *config) -{ - FAR struct telnetd_s *daemon; - pid_t pid; - int ret; - - /* Allocate a state structure for the new daemon */ - - daemon = (FAR struct telnetd_s *)malloc(sizeof(struct telnetd_s)); - if (!daemon) - { - return -ENOMEM; - } - - /* Initialize the daemon structure */ - - daemon->port = config->d_port; - daemon->priority = config->t_priority; - daemon->stacksize = config->t_stacksize; - daemon->entry = config->t_entry; - - /* Initialize the common structure if this is the first daemon */ - - if (g_telnetdcommon.ndaemons < 1) - { - sem_init(&g_telnetdcommon.startsem, 0, 0); - sem_init(&g_telnetdcommon.exclsem, 0, 1); - g_telnetdcommon.minor = 0; - } - - /* Then start the new daemon */ - - g_telnetdcommon.daemon = daemon; - pid = task_create("Telnet daemon", config->d_priority, config->d_stacksize, - telnetd_daemon, NULL); - if (pid < 0) - { - int errval = errno; - free(daemon); - nerr("ERROR: Failed to start the telnet daemon: %d\n", errval); - return -errval; - } - - /* Then wait for the daemon to start and complete the handshake */ - - do - { - ret = sem_wait(&g_telnetdcommon.startsem); - - /* The only expected error condition is for sem_wait to be awakened by - * a receipt of a signal. - */ - - if (ret < 0) - { - DEBUGASSERT(errno == EINTR || errno == ECANCELED); - } - } - while (ret < 0); - - /* Return success */ - - return pid; -} diff --git a/examples/cc3000/telnetd_driver.c b/examples/cc3000/telnetd_driver.c deleted file mode 100644 index b9ef22bc8..000000000 --- a/examples/cc3000/telnetd_driver.c +++ /dev/null @@ -1,811 +0,0 @@ -/**************************************************************************** - * apps/examples/cc3000/telnetd_driver.c - * - * Copyright (C) 2007, 2009, 2011-2013 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * This is a leverage of similar logic from uIP which has a compatible BSD - * license: - * - * Author: Adam Dunkels - * Copyright (c) 2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 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. - * 3. Neither the name of the Institute, NuttX nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "netutils/telnetd.h" - -#include "telnetd.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ -/* Telnet protocol stuff ****************************************************/ - -#define ISO_nl 0x0a -#define ISO_cr 0x0d - -#define TELNET_IAC 255 -#define TELNET_WILL 251 -#define TELNET_WONT 252 -#define TELNET_DO 253 -#define TELNET_DONT 254 - -#define TELNET_RXBUFFER_SIZE 256 -#define TELNET_TXBUFFER_SIZE 256 - -/* Device stuff *************************************************************/ - -#define TELNETD_DEVFMT "/dev/telnetd%d" - -/**************************************************************************** - * Private Types - ****************************************************************************/ -/* The state of the telnet parser */ - -enum telnetd_state_e -{ - STATE_NORMAL = 0, - STATE_IAC, - STATE_WILL, - STATE_WONT, - STATE_DO, - STATE_DONT -}; - -/* This structure describes the internal state of the driver */ - -struct telnetd_dev_s -{ - sem_t td_exclsem; /* Enforces mutually exclusive access */ - uint8_t td_state; /* (See telnetd_state_e) */ - uint8_t td_pending; /* Number of valid, pending bytes in the rxbuffer */ - uint8_t td_offset; /* Offset to the valid, pending bytes in the rxbuffer */ - uint8_t td_crefs; /* The number of open references to the session */ - int td_minor; /* Minor device number */ - long td_psock; /* A clone of the internal socket structure */ - char td_rxbuffer[TELNET_RXBUFFER_SIZE]; - char td_txbuffer[TELNET_TXBUFFER_SIZE]; -}; - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ -/* Support functions */ - -#ifdef CONFIG_TELNETD_DUMPBUFFER -static inline void telnetd_dumpbuffer(FAR const char *msg, - FAR const char *buffer, unsigned int nbytes); -#else -# define telnetd_dumpbuffer(msg,buffer,nbytes) -#endif -static void telnetd_getchar(FAR struct telnetd_dev_s *priv, uint8_t ch, - FAR char *dest, int *nread); -static ssize_t telnetd_receive(FAR struct telnetd_dev_s *priv, - FAR const char *src, size_t srclen, FAR char *dest, - size_t destlen); -static bool telnetd_putchar(FAR struct telnetd_dev_s *priv, uint8_t ch, - int *nwritten); -static void telnetd_sendopt(FAR struct telnetd_dev_s *priv, uint8_t option, - uint8_t value); - -/* Character driver methods */ - -static int telnetd_open(FAR struct file *filep); -static int telnetd_close(FAR struct file *filep); -static ssize_t telnetd_read(FAR struct file *, FAR char *, size_t); -static ssize_t telnetd_write(FAR struct file *, FAR const char *, size_t); -static int telnetd_ioctl(FAR struct file *filep, int cmd, - unsigned long arg); - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static const struct file_operations g_telnetdfops = -{ - telnetd_open, /* open */ - telnetd_close, /* close */ - telnetd_read, /* read */ - telnetd_write, /* write */ - 0, /* seek */ - telnetd_ioctl /* ioctl */ -#ifndef CONFIG_DISABLE_POLL - , 0 /* poll */ -#endif -}; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: telnetd_dumpbuffer - * - * Description: - * Dump a buffer of data (debug only) - * - ****************************************************************************/ - -#ifdef CONFIG_TELNETD_DUMPBUFFER -static inline void telnetd_dumpbuffer(FAR const char *msg, - FAR const char *buffer, - unsigned int nbytes) -{ - /* CONFIG_DEBUG_FEATURES, CONFIG_DEBUG_INFO, and CONFIG_DEBUG_NET have to be - * defined or the following does nothing. - */ - - ninfodumpbuffer(msg, (FAR const uint8_t*)buffer, nbytes); -} -#endif - -/**************************************************************************** - * Name: telnetd_getchar - * - * Description: - * Get another character for the user received buffer from the RX buffer - * - ****************************************************************************/ - -static void telnetd_getchar(FAR struct telnetd_dev_s *priv, uint8_t ch, - FAR char *dest, int *nread) -{ - register int index; - - /* Ignore carriage returns */ - - if (ch != ISO_cr) - { - /* Add all other characters to the destination buffer */ - - index = *nread; - dest[index++] = ch; - *nread = index; - } -} - -/**************************************************************************** - * Name: telnetd_receive - * - * Description: - * Process a received telenet buffer - * - ****************************************************************************/ - -static ssize_t telnetd_receive(FAR struct telnetd_dev_s *priv, FAR const char *src, - size_t srclen, FAR char *dest, size_t destlen) -{ - int nread; - uint8_t ch; - - ninfo("srclen: %d destlen: %d\n", srclen, destlen); - - for (nread = 0; srclen > 0 && nread < destlen; srclen--) - { - ch = *src++; - ninfo("ch=%02x state=%d\n", ch, priv->td_state); - - switch (priv->td_state) - { - case STATE_IAC: - if (ch == TELNET_IAC) - { - telnetd_getchar(priv, ch, dest, &nread); - priv->td_state = STATE_NORMAL; - } - else - { - switch (ch) - { - case TELNET_WILL: - priv->td_state = STATE_WILL; - break; - - case TELNET_WONT: - priv->td_state = STATE_WONT; - break; - - case TELNET_DO: - priv->td_state = STATE_DO; - break; - - case TELNET_DONT: - priv->td_state = STATE_DONT; - break; - - default: - priv->td_state = STATE_NORMAL; - break; - } - } - break; - - case STATE_WILL: - /* Reply with a DONT */ - - telnetd_sendopt(priv, TELNET_DONT, ch); - priv->td_state = STATE_NORMAL; - break; - - case STATE_WONT: - /* Reply with a DONT */ - - telnetd_sendopt(priv, TELNET_DONT, ch); - priv->td_state = STATE_NORMAL; - break; - - case STATE_DO: - /* Reply with a WONT */ - - telnetd_sendopt(priv, TELNET_WONT, ch); - priv->td_state = STATE_NORMAL; - break; - - case STATE_DONT: - /* Reply with a WONT */ - - telnetd_sendopt(priv, TELNET_WONT, ch); - priv->td_state = STATE_NORMAL; - break; - - case STATE_NORMAL: - if (ch == TELNET_IAC) - { - priv->td_state = STATE_IAC; - } - else - { - telnetd_getchar(priv, ch, dest, &nread); - } - break; - } - } - - /* We get here if (1) all of the received bytes have been processed, or - * (2) if the user's buffer has become full. - */ - - if (srclen > 0) - { - /* Remember where we left off. These bytes will be returned the next - * time that telnetd_read() is called. - */ - - priv->td_pending = srclen; - priv->td_offset = (src - priv->td_rxbuffer); - } - else - { - /* All of the received bytes were consumed */ - - priv->td_pending = 0; - priv->td_offset = 0; - } - - return nread; -} - -/**************************************************************************** - * Name: telnetd_putchar - * - * Description: - * Put another character from the user buffer to the TX buffer. - * - ****************************************************************************/ - -static bool telnetd_putchar(FAR struct telnetd_dev_s *priv, uint8_t ch, - int *nread) -{ - register int index; - bool ret = false; - - /* Ignore carriage returns (we will put these in automatically as necesary) */ - - if (ch != ISO_cr) - { - /* Add all other characters to the destination buffer */ - - index = *nread; - priv->td_txbuffer[index++] = ch; - - /* Check for line feeds */ - - if (ch == ISO_nl) - { - /* Now add the carriage return */ - - priv->td_txbuffer[index++] = ISO_cr; - priv->td_txbuffer[index++] = '\0'; - - /* End of line */ - - ret = true; - } - - *nread = index; - } - - return ret; -} - -/**************************************************************************** - * Name: telnetd_sendopt - * - * Description: - * Send the telnet option bytes - * - ****************************************************************************/ - -static void telnetd_sendopt(FAR struct telnetd_dev_s *priv, uint8_t option, - uint8_t value) -{ - uint8_t optbuf[4]; - optbuf[0] = TELNET_IAC; - optbuf[1] = option; - optbuf[2] = value; - optbuf[3] = 0; - - telnetd_dumpbuffer("Send optbuf", optbuf, 4); - if (send(priv->td_psock, optbuf, 4, 0) < 0) - { - nerr("ERROR: Failed to send TELNET_IAC\n"); - } -} - -/**************************************************************************** - * Name: telnetd_open - ****************************************************************************/ - -static int telnetd_open(FAR struct file *filep) -{ - FAR struct inode *inode = filep->f_inode; - FAR struct telnetd_dev_s *priv = inode->i_private; - int tmp; - int ret; - - ninfo("td_crefs: %d\n", priv->td_crefs); - - /* O_NONBLOCK is not supported */ - - if (filep->f_oflags & O_NONBLOCK) - { - ret = -ENOSYS; - goto errout; - } - - /* Get exclusive access to the device structures */ - - ret = sem_wait(&priv->td_exclsem); - if (ret < 0) - { - ret = -errno; - goto errout; - } - - /* Increment the count of references to the device. If this the first - * time that the driver has been opened for this device, then initialize - * the device. - */ - - tmp = priv->td_crefs + 1; - if (tmp > 255) - { - /* More than 255 opens; uint8_t would overflow to zero */ - - ret = -EMFILE; - goto errout_with_sem; - } - - /* Save the new open count on success */ - - priv->td_crefs = tmp; - ret = OK; - -errout_with_sem: - sem_post(&priv->td_exclsem); - -errout: - return ret; -} - -/**************************************************************************** - * Name: telnetd_close - ****************************************************************************/ - -static int telnetd_close(FAR struct file *filep) -{ - FAR struct inode *inode = filep->f_inode; - FAR struct telnetd_dev_s *priv = inode->i_private; - FAR char *devpath; - int ret; - - ninfo("td_crefs: %d\n", priv->td_crefs); - - /* Get exclusive access to the device structures */ - - ret = sem_wait(&priv->td_exclsem); - if (ret < 0) - { - ret = -errno; - goto errout; - } - - /* Decrement the references to the driver. If the reference count will - * decrement to 0, then uninitialize the driver. - */ - - if (priv->td_crefs > 1) - { - /* Just decrement the reference count and release the semaphore */ - - priv->td_crefs--; - sem_post(&priv->td_exclsem); - } - else - { - /* Re-create the path to the driver. */ - - sched_lock(); - ret = asprintf(&devpath, TELNETD_DEVFMT, priv->td_minor); - if (ret < 0) - { - nerr("ERROR: Failed to allocate the driver path\n"); - } - else - { - /* Unregister the character driver */ - - ret = unregister_driver(devpath); - if (ret < 0) - { - nerr("ERROR: Failed to unregister the driver %s: %d\n", devpath, ret); - } - - free(devpath); - } - - /* Close the socket */ - - closesocket(priv->td_psock); - - /* Release the driver memory. What if there are threads waiting on - * td_exclsem? They will never be awakened! How could this happen? - * crefs == 1 so there are no other open references to the driver. - * But this could have if someone were trying to re-open the driver - * after every other thread has closed it. That really should not - * happen in the intended usage model. - */ - - DEBUGASSERT(priv->td_exclsem.semcount == 0); - sem_destroy(&priv->td_exclsem); - free(priv); - sched_unlock(); - } - - ret = OK; - -errout: - return ret; -} - -/**************************************************************************** - * Name: telnetd_read - ****************************************************************************/ - -static ssize_t telnetd_read(FAR struct file *filep, FAR char *buffer, size_t len) -{ - FAR struct inode *inode = filep->f_inode; - FAR struct telnetd_dev_s *priv = inode->i_private; - ssize_t ret; - - ninfo("len: %d\n", len); - - /* First, handle the case where there are still valid bytes left in the - * I/O buffer from the last time that read was called. NOTE: Much of - * what we read may be protocol stuff and may not correspond to user - * data. Hence we need the loop and we need may need to call psock_recv() - * multiple times in order to get data that the client is interested in. - */ - - do - { - if (priv->td_pending > 0) - { - /* Process the buffered telnet data */ - - FAR const char *src = &priv->td_rxbuffer[priv->td_offset]; - ret = telnetd_receive(priv, src, priv->td_pending, buffer, len); - } - - /* Read a buffer of data from the telnet client */ - - else - { - ret = recv(priv->td_psock, priv->td_rxbuffer, - TELNET_RXBUFFER_SIZE, 0); - - /* Did we receive anything? */ - - if (ret > 0) - { - /* Yes.. Process the newly received telnet data */ - - telnetd_dumpbuffer("Received buffer", priv->td_rxbuffer, ret); - ret = telnetd_receive(priv, priv->td_rxbuffer, ret, buffer, len); - } - - /* Otherwise the peer closed the connection (ret == 0) or an error - * occurred (ret < 0). - */ - - else - { - break; - } - } - } - while (ret == 0); - - /* Return: - * - * ret > 0: The number of characters copied into the user buffer by - * telnetd_receive(). - * ret <= 0: Loss of connection or error events reported by recv(). - */ - - return ret; -} - -/**************************************************************************** - * Name: telnetd_write - ****************************************************************************/ - -static ssize_t telnetd_write(FAR struct file *filep, FAR const char *buffer, size_t len) -{ - FAR struct inode *inode = filep->f_inode; - FAR struct telnetd_dev_s *priv = inode->i_private; - FAR const char *src = buffer; - ssize_t nsent; - ssize_t ret; - int ncopied; - char ch; - bool eol; - - ninfo("len: %d\n", len); - - /* Process each character from the user buffer */ - - for (nsent = 0, ncopied = 0; nsent < len; nsent++) - { - /* Get the next character from the user buffer */ - - ch = *src++; - - /* Add the character to the TX buffer */ - - eol = telnetd_putchar(priv, ch, &ncopied); - - /* Was that the end of a line? Or is the buffer too full to hold the - * next largest character sequence ("\r\n\0")? - */ - - if (eol || ncopied > TELNET_TXBUFFER_SIZE-3) - { - /* Yes... send the data now */ - - ret = send(priv->td_psock, priv->td_txbuffer, ncopied, 0); - if (ret < 0) - { - nerr("ERROR: psock_send failed '%s': %d\n", priv->td_txbuffer, ret); - return ret; - } - - /* Reset the index to the beginning of the TX buffer. */ - - ncopied = 0; - } - } - - /* Send anything remaining in the TX buffer */ - - if (ncopied > 0) - { - ret = send(priv->td_psock, priv->td_txbuffer, ncopied, 0); - if (ret < 0) - { - nerr("ERROR: psock_send failed '%s': %d\n", priv->td_txbuffer, ret); - return ret; - } - } - - /* Notice that we don't actually return the number of bytes sent, but - * rather, the number of bytes that the caller asked us to send. We may - * have sent more bytes (because of CR-LF expansion and because of NULL - * termination). But it confuses some logic if you report that you sent - * more than you were requested to. - */ - - return len; -} - -/**************************************************************************** - * Name: telnetd_poll - ****************************************************************************/ - -static int telnetd_ioctl(FAR struct file *filep, int cmd, unsigned long arg) -{ -#if 0 /* No ioctl commands are yet supported */ - struct inode *inode = filep->f_inode; - struct cdcacm_dev_s *priv = inode->i_private; - int ret = OK; - - switch (cmd) - { - /* Add ioctl commands here */ - - default: - ret = -ENOTTY; - break; - } - - return ret; -#else - return -ENOTTY; -#endif -} - -/**************************************************************************** - * Name: telnetd_poll - ****************************************************************************/ - -#if 0 /* Not used by this driver */ -static int telnetd_poll(FAR struct file *filep, FAR struct pollfd *fds, - bool setup) -{ - FAR struct inode *inode = filep->f_inode; - FAR struct telnetd_dev_s *priv = inode->i_private; -} -#endif - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: telnetd_driver - * - * Description: - * Create a character driver to "wrap" the telnet session. This function - * will select and return a unique path for the new telnet device. - * - * Parameters: - * sd - The socket descriptor that represents the new telnet connection. - * daemon - A pointer to the structure representing the overall state of - * this instance of the telnet daemon. - * - * Return: - * An allocated string represent the full path to the created driver. The - * receiver of the string must de-allocate this memory when it is no longer - * needed. NULL is returned on a failure. - * - ****************************************************************************/ - -FAR char *telnetd_driver(long sd, FAR struct telnetd_s *daemon) -{ - FAR struct telnetd_dev_s *priv; - FAR char *devpath = NULL; - int ret; - - /* Allocate instance data for this driver */ - - priv = (FAR struct telnetd_dev_s*)malloc(sizeof(struct telnetd_dev_s)); - if (!priv) - { - nerr("ERROR: Failed to allocate the driver data structure\n"); - return NULL; - } - - /* Initialize the allocated driver instance */ - - sem_init(&priv->td_exclsem, 0, 1); - - priv->td_state = STATE_NORMAL; - priv->td_crefs = 0; - priv->td_pending = 0; - priv->td_offset = 0; - priv->td_psock = sd; - - - /* Allocation a unique minor device number of the telnet drvier */ - - do - { - ret = sem_wait(&g_telnetdcommon.exclsem); - if (ret < 0 && errno != -EINTR) - { - goto errout_with_dev; - } - } - while (ret < 0); - - priv->td_minor = g_telnetdcommon.minor; - g_telnetdcommon.minor++; - sem_post(&g_telnetdcommon.exclsem); - - /* Create a path and name for the driver. */ - - ret = asprintf(&devpath, TELNETD_DEVFMT, priv->td_minor); - if (ret < 0) - { - nerr("ERROR: Failed to allocate the driver path\n"); - goto errout_with_dev; - } - - /* Register the driver */ - - ret = register_driver(devpath, &g_telnetdfops, 0666, priv); - if (ret < 0) - { - nerr("ERROR: Failed to register the driver %s: %d\n", devpath, ret); - goto errout_with_devpath; - } - - /* Return the path to the new telnet driver */ - - return devpath; - -errout_with_devpath: - free(devpath); -errout_with_dev: - free(priv); - return NULL; -}