From dcb9ea4d4425ae5ea290fcda6050e09704b300ad Mon Sep 17 00:00:00 2001 From: kazu Date: Sun, 12 Mar 2017 12:42:19 +0100 Subject: [PATCH] initial commit --- Debug.h | 22 ++++ c++.h | 299 ++++++++++++++++++++++++++++++++++++++++++++++ ext/led/WS2812B.h | 244 +++++++++++++++++++++++++++++++++++++ io/IO.h | 84 +++++++++++++ io/Timer0.h | 87 ++++++++++++++ io/UART.h | 60 ++++++++++ io/fastGPIO.h | 189 +++++++++++++++++++++++++++++ net/IP.h | 27 +++++ net/MAC.h | 73 +++++++++++ net/Promiscuous.h | 52 ++++++++ net/UDP.h | 103 ++++++++++++++++ net/WiFiRaw.h | 195 ++++++++++++++++++++++++++++++ 12 files changed, 1435 insertions(+) create mode 100644 Debug.h create mode 100644 c++.h create mode 100644 ext/led/WS2812B.h create mode 100644 io/IO.h create mode 100644 io/Timer0.h create mode 100644 io/UART.h create mode 100644 io/fastGPIO.h create mode 100644 net/IP.h create mode 100644 net/MAC.h create mode 100644 net/Promiscuous.h create mode 100644 net/UDP.h create mode 100644 net/WiFiRaw.h diff --git a/Debug.h b/Debug.h new file mode 100644 index 0000000..ebc9338 --- /dev/null +++ b/Debug.h @@ -0,0 +1,22 @@ +#ifndef DEBUG_H +#define DEBUG_H + +#define DEBUG + +#ifdef DEBUG + + #define debug(str) os_printf(str) + #define debugMod(module, str) os_printf("[%s] %s\n", module, str) + #define debugMod1(module, str, val) os_printf("[%s] ", module); os_printf(str, val); os_printf("\n"); + #define IF_DEBUG(a) a + +#else + + #define debug(module, str) + #define debugMod(module, str) + #define debugMod1(module, str, val) + #define IF_DEBUG(a) + +#endif + +#endif // DEBUG_H diff --git a/c++.h b/c++.h new file mode 100644 index 0000000..52c4af3 --- /dev/null +++ b/c++.h @@ -0,0 +1,299 @@ +#pragma once + +#define TRUE true +#define FALSE false + +typedef void (*int_handler_t)(void*); + +void *pvPortMalloc(size_t xWantedSize, const char* file, int line) __attribute__((malloc, alloc_size(1))); +void *pvPortRealloc(void* ptr, size_t xWantedSize, const char* file, int line) __attribute__((alloc_size(2))); +void vPortFree(void *ptr, const char* file, int line); +void *ets_memcpy(void *dest, const void *src, size_t n); +void *ets_memset(void *s, int c, size_t n); +void ets_timer_arm_new(ETSTimer *a, int b, int c, int isMstimer); +void ets_timer_setfn(ETSTimer *t, ETSTimerFunc *fn, void *parg); +void ets_timer_disarm(ETSTimer *a); +int atoi(const char *nptr); +int ets_strncmp(const char *s1, const char *s2, int len); +int ets_strcmp(const char *s1, const char *s2); +int ets_strlen(const char *s); +char *ets_strcpy(char *dest, const char *src); +char *ets_strncpy(char *dest, const char *src, size_t n); +char *ets_strstr(const char *haystack, const char *needle); +int ets_sprintf(char *str, const char *format, ...) __attribute__ ((format (printf, 2, 3))); +int os_snprintf(char *str, size_t size, const char *format, ...) __attribute__ ((format (printf, 3, 4))); +int ets_printf(const char *format, ...) __attribute__ ((format (printf, 1, 2))); +void ets_install_putc1(void* routine); + +//#define STATUS int +void uart_div_modify(int no, int freq); +//STATUS uart_tx_one_char(uint8_t uart, uint8_t TxChar); + + +void ets_isr_mask(int intr); +void ets_isr_unmask(int intr); +void ets_isr_attach(int intr, int_handler_t handler, void *arg); +void ets_intr_lock(); +void ets_intr_unlock(); +//int ets_vsnprintf(char * s, size_t n, const char * format, va_list arg) __attribute__ ((format (printf, 3, 0))); +//int ets_vprintf(int (*print_function)(int), const char * format, va_list arg) __attribute__ ((format (printf, 2, 0))); +int ets_putc(int); +bool ets_task(ETSTask task, uint8 prio, ETSEvent *queue, uint8 qlen); +bool ets_post(uint8 prio, ETSSignal sig, ETSParam par); + +#define ICACHE_RAM_ATTR __attribute__((section(".iram.text"))) + +typedef void (*int_handler_t)(void*); + +#define ETS_SLC_INUM 1 +#define ETS_SDIO_INUM 1 +#define ETS_SPI_INUM 2 +#define ETS_GPIO_INUM 4 +#define ETS_UART_INUM 5 +#define ETS_UART1_INUM 5 +#define ETS_CCOMPARE0_INUM 6 +#define ETS_SOFT_INUM 7 +#define ETS_WDT_INUM 8 +#define ETS_FRC_TIMER1_INUM 9 /* use edge*/ + +#define ETS_INTR_LOCK() \ + ets_intr_lock() + +#define ETS_INTR_UNLOCK() \ + ets_intr_unlock() + +#define ETS_INTR_ENABLE(inum) \ + ets_isr_unmask((1<r = r; + this->g = g; + this->b = b; + } + + void setHSV(const uint8_t h, const uint8_t s, const uint8_t v) { + + uint8_t region, remainder, p, q, t; + + region = h / 43; + remainder = (h - (region * 43)) * 6; + + p = (v * (255 - s)) >> 8; + q = (v * (255 - ((s * remainder) >> 8))) >> 8; + t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8; + + switch (region) { + case 0: + r = v; g = t; b = p; + break; + case 1: + r = q; g = v; b = p; + break; + case 2: + r = p; g = v; b = t; + break; + case 3: + r = p; g = q; b = v; + break; + case 4: + r = t; g = p; b = v; + break; + default: + r = v; g = p; b = q; + break; + } + + } + +}; + +template class WS2812B { + + #define LED_SET_PIN_TO_OUTPUT GPIO5_OUTPUT_SET + #define LED_SET_PIN_H GPIO5_H + #define LED_SET_PIN_L GPIO5_L + + //#define NS_PER_TICK ( (1000ul*1000ul*1000ul) / (80ul*1000ul*1000ul) ) + + /** color-value for each attached LED */ + Color colors[numLEDs]; + + public: + + /** ctor */ + WS2812B() { + + LED_SET_PIN_TO_OUTPUT; + + } + + /** set the color for the given LED */ + void setColor(const uint8_t idx, const Color rgb) { + colors[idx] = rgb; + } + + Color& getColor(const uint8_t idx) { + return colors[idx]; + } + + /** flush configured changes */ + void flush() { + + LED_SET_PIN_TO_OUTPUT; + + //cli(); + + //reset(); + +/* + send0(); + send1(); + send0(); + send1(); + send0(); + send1(); + send0(); + send1(); + */ + /* + send0(); + send0(); + send0(); + send0(); + send0(); + send0(); + send0(); + send0(); + + send1(); + send1(); + send1(); + send1(); + send1(); + send1(); + send1(); + // send0(); + + // send0(); + */ + + // process each LED + for (uint8_t i = 0; i < numLEDs; ++i) { + + const Color rgb = colors[i]; + + // send each LEDs 24-bit GRB data + sendByte(rgb.g); + sendByte(rgb.r); + sendByte(rgb.b); + + } + + reset(); + + + // sei(); + + + } + + private: + + inline void sendByte(uint8_t b) { + for (uint8_t i = 0; i < 8; ++i) { + if (b & 0b10000000) { + send1(); + } else { + send0(); + } + b <<= 1; + } + } + + __attribute__((always_inline)) inline void send1() { // 800ns high, 450ns low + LED_SET_PIN_H; + delay800(); + LED_SET_PIN_L; + delay100(); + } + + __attribute__((always_inline)) inline void send0() { // 400ns high, 850ns low + LED_SET_PIN_H; + delay100(); + LED_SET_PIN_L; + delay800(); + } + + __attribute__((always_inline)) inline void reset() { + LED_SET_PIN_L; + os_delay_us(50); + //delayMicroseconds(50); + } + + + //#pragma GCC optimize 0 + + __attribute__((always_inline)) inline void delay50() { + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + } + + + // 100 ns delay. @80 MHz one nop = 12,5ns + __attribute__((always_inline)) inline void delay100() { + delay50(); + delay50(); + } + + __attribute__((always_inline)) inline void delay200() { + delay100(); + delay100(); + } + + __attribute__((always_inline)) inline void delay400() { + delay100(); + delay100(); + delay100(); + delay100(); + } + + __attribute__((always_inline)) inline void delay500() { + delay100(); + delay100(); + delay100(); + delay100(); + delay100(); + } + + __attribute__((always_inline)) inline void delay600() { + delay100(); + delay100(); + delay100(); + delay100(); + delay100(); + delay100(); + } + + __attribute__((always_inline)) inline void delay800() { + delay400(); + delay400(); + } + + + // #pragma GCC reset_options + + + + // inline void delayNS(const uint16_t ns) { + // const uint16_t ticks = ns / NS_PER_TICK / 2; + // for (uint16_t i = 0; i < ticks; ++i) {asm("nop");} + // } + +}; + +#endif // WS2812B_H diff --git a/io/IO.h b/io/IO.h new file mode 100644 index 0000000..e74352b --- /dev/null +++ b/io/IO.h @@ -0,0 +1,84 @@ +#ifndef IO_H +#define IO_H + +// http://www.electrodragon.com/w/ESP8266_IoT_Firmware +// https://esp8266.ru/esp8266-pin-register-strapping/ +// http://www.limpkin.fr/index.php?post/2014/12/07/First-Steps-with-the-ESP8266-03-Development-Board + +//extern "C" { +// #include "eagle_soc.h" +// #include "ets_sys.h" +//} + +#include "fastGPIO.h" + +class IO { + +public: + +// // https://esp8266.ru/esp8266-pin-register-strapping/ +// static void setOutput(const uint8_t pin) { +// //PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12); +// //PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0); +// } + +// // https://esp8266.ru/esp8266-pin-register-strapping/ +// static void setInput(const uint8_t pin) { +// //PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_U); +// //PIN_PULLDWN_DIS(PERIHS_IO_MUX_GPIO0_U); +// //PIN_PULLDWN_EN(PERIHS_IO_MUX_GPIO0_U); +// } + + __attribute__((always_inline)) static inline void setPinHi(const uint8_t pin) { + GPIO_OUTPUT_SET(GPIO_ID_PIN(pin), 1); + //gpio_output_set(pin, 0, pin, 0); + } + + __attribute__((always_inline)) static inline void setPinLo(const uint8_t pin) { + GPIO_OUTPUT_SET(GPIO_ID_PIN(pin), 0); + //gpio_output_set(0, pin, pin, 0); + } + + __attribute__((always_inline)) static inline void setPin(const uint8_t pin, const bool val) { + GPIO_OUTPUT_SET(GPIO_ID_PIN(pin), val); //val ? 1 : 0; + } + + __attribute__((always_inline)) static inline bool getPin(const uint8_t pin) { + return GPIO_INPUT_GET(GPIO_ID_PIN(pin)); + } + + static inline void toggleLED0() { + static bool on = false; + on = !on; + GPIO16_OUTPUT_SET; + if (on) {GPIO16_H;} else {GPIO16_L;} + } + + static inline void toggleLED1() { + static bool on = false; + on = !on; + GPIO5_OUTPUT_SET; + if (on) {GPIO5_H;} else {GPIO5_L;} + } + + /** toggle the onboard LED */ + static inline void toggleBuiltInLED() { + static volatile bool on = false; + on = !on; + +#if PLATFORM == WEMOS_D1_MINI + GPIO2_OUTPUT_SET; + if (on) {GPIO2_H;} else {GPIO2_L;} +#elif PLATFORM == NODE_MCU + GPIO16_OUTPUT_SET; + if (on) {GPIO16_H;} else {GPIO16_L;} +#else + #error "NO PLATFORM" +#endif + + } + + +}; + +#endif // IO_H diff --git a/io/Timer0.h b/io/Timer0.h new file mode 100644 index 0000000..069a48c --- /dev/null +++ b/io/Timer0.h @@ -0,0 +1,87 @@ +#ifndef TIMER0_H +#define TIMER0_H + +#include "ESP.h" + +#define TIMER0_VARIABLES() \ + volatile timercallback Timer0::callback = nullptr; \ + volatile uint32_t Timer0::tickIncrement; \ + +typedef void(*timercallback)(void); + + +//extern "C" { +// void timer0_detachInterrupt(); +// void timer0_attachInterrupt(timercallback userFunc); +// void timer0_isr_init(); +//} + +class Timer0 { + +private: + + static volatile timercallback callback; + + static volatile uint32_t tickIncrement; + +public: + + /** creates a one-time interrupt after the given delay */ + void fireOnce(const uint32_t tickDelay) { + ETS_CCOMPARE0_DISABLE(); + ETS_CCOMPARE0_INTR_ATTACH(isrOnce, NULL); + setDelay(tickDelay); + } + + /** creates a periodic interrupt with the given delay-interval */ + void fireLoop(const uint32_t tickInterval) { + ETS_CCOMPARE0_DISABLE(); + tickIncrement = tickInterval; + ETS_CCOMPARE0_INTR_ATTACH(isrLoop, NULL); + setDelay(1000); + } + + void fireLoopHz(const uint32_t hz) { + const uint32_t ticks = (80*1000*1000) / hz; + fireLoop(ticks); + } + + void attachInterrupt(timercallback userFunc) { + callback = userFunc; + } + +// void detachInterrupt() { +// timer0_user_cb = NULL; +// ETS_CCOMPARE0_DISABLE(); +// } + + #define timer0_interrupted() (ETS_INTR_PENDING() & (_BV(ETS_COMPARE0_INUM))) + #define timer0_read() ((__extension__({uint32_t count;__asm__ __volatile__("esync; rsr %0,ccompare0":"=a" (count));count;}))) + #define timer0_write(count) __asm__ __volatile__("wsr %0,ccompare0; esync"::"a" (count) : "memory") + + + +private: + + void setDelay(const uint32_t ticks) { + timer0_write(ESP::getCycleCount() + ticks); + ETS_CCOMPARE0_ENABLE(); + } + + /** fire once, hereafter disable the timer */ + static void isrOnce(void* para) { + (void) para; + ETS_CCOMPARE0_DISABLE(); + if (callback) {callback();} + } + + /** fire periodically */ + static void isrLoop(void* para) { + (void) para; + timer0_write(ESP::getCycleCount() + tickIncrement); + if (callback) {callback();} + } + +}; + +#endif // TIMER0_H diff --git a/io/UART.h b/io/UART.h new file mode 100644 index 0000000..b006741 --- /dev/null +++ b/io/UART.h @@ -0,0 +1,60 @@ +#ifndef UART_H +#define UART_H + +class UART { + +public: + + /** setup */ + void init(UartBautRate rate) { + uart_init(rate, rate); + } + + /** how many chars are available for reading? */ + uint8_t available() { + return (READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S) & UART_RXFIFO_CNT; + } + + /** number of bytes within the TX-FIFO */ + uint8_t txFifoUsed() const { + return (( READ_PERI_REG(UART_STATUS(UART0))>>UART_TXFIFO_CNT_S)& UART_TXFIFO_CNT); + } + + /** size of the TX FIFO */ + uint8_t txFifoLen() const { + return 126; + } + + /** is it possible to add something to the TX fifo? */ + uint8_t txFifoFree() const { + return txFifoLen() - txFifoUsed(); + } + + /** fetch one char from the uart */ + char readChar() const { + return READ_PERI_REG(UART_FIFO(UART0)) & 0xFF; + } + + void writeChar(const char c) { + while(!txFifoFree()) {;} + WRITE_PERI_REG(UART_FIFO(UART0), c); + } + + +// void write(const char c) { +// uart_tx_one_char(UART0, c); +// } + + /** write the given data to the uart */ + void write(const void* data, const uint16_t len) { + for (uint16_t i = 0; i < len; ++i) { + writeChar( ((uint8_t*)data)[i] ); + //uart_tx_one_char(UART0, ((uint8_t*)data)[i]); + } + } + +}; + +extern UART uart; + +#endif // UART_H diff --git a/io/fastGPIO.h b/io/fastGPIO.h new file mode 100644 index 0000000..f7734c6 --- /dev/null +++ b/io/fastGPIO.h @@ -0,0 +1,189 @@ +/* + * fast_gpio.h + * + * Copyright (c) 2016 maowen (https://github.com/maowen) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef _ESP8266_FAST_GPIO_H_ +#define _ESP8266_FAST_GPIO_H_ + +#include "eagle_soc.h" +#include "gpio.h" + +/* GPIO0 Macros */ +#define GPIO0_MUX PERIPHS_IO_MUX_GPIO0_U +#define GPIO0_CONF PIN_FUNC_SELECT(GPIO0_MUX, FUNC_GPIO0) +#define GPIO0_OUTPUT_SET do { GPIO0_CONF; GPIO_OUTPUT_SET(0, 0); } while(0) +#define GPIO0_INPUT_SET do { GPIO0_CONF; GPIO_DIS_OUTPUT(0); } while(0) +#define GPIO0_INPUT_PULLUP_SET do { GPIO0_INPUT_SET; PIN_PULLUP_EN(GPIO0_MUX); } while(0) +#define GPIO0_IN (GPIO_INPUT_GET(BIT0)) +#define GPIO0_H (GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, BIT0)) +#define GPIO0_L (GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, BIT0)) +#define GPIO0(x) ((x)?GPIO0_H:GPIO0_L) + +/* GPIO1 Macros */ +#define GPIO1_MUX PERIPHS_IO_MUX_U0TXD_U +#define GPIO1_CONF PIN_FUNC_SELECT(GPIO1_MUX, FUNC_GPIO1) +#define GPIO1_OUTPUT_SET do { GPIO1_CONF; GPIO_OUTPUT_SET(1, 0); } while(0) +#define GPIO1_INPUT_SET do { GPIO1_CONF; GPIO_DIS_OUTPUT(1); } while(0) +#define GPIO1_INPUT_PULLUP_SET do { GPIO1_INPUT_SET; PIN_PULLUP_EN(GPIO1_MUX); } while(0) +#define GPIO1_IN (GPIO_INPUT_GET(BIT1)) +#define GPIO1_H (GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, BIT1)) +#define GPIO1_L (GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, BIT1)) +#define GPIO1(x) ((x)?GPIO1_H:GPIO1_L) + +/* GPIO2 Macros */ +#define GPIO2_MUX PERIPHS_IO_MUX_GPIO2_U +#define GPIO2_CONF PIN_FUNC_SELECT(GPIO2_MUX, FUNC_GPIO2) +#define GPIO2_OUTPUT_SET do { GPIO2_CONF; GPIO_OUTPUT_SET(2, 0); } while(0) +#define GPIO2_INPUT_SET do { GPIO2_CONF; GPIO_DIS_OUTPUT(2); } while(0) +#define GPIO2_INPUT_PULLUP_SET do { GPIO2_INPUT_SET; PIN_PULLUP_EN(GPIO2_MUX); } while(0) +#define GPIO2_IN (GPIO_INPUT_GET(BIT2)) +#define GPIO2_H (GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, BIT2)) +#define GPIO2_L (GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, BIT2)) +#define GPIO2(x) ((x)?GPIO2_H:GPIO2_L) + +/* GPIO3 Macros */ +#define GPIO3_MUX PERIPHS_IO_MUX_U0RXD_U +#define GPIO3_CONF PIN_FUNC_SELECT(GPIO3_MUX, FUNC_GPIO3) +#define GPIO3_OUTPUT_SET do { GPIO3_CONF; GPIO_OUTPUT_SET(3, 0); } while(0) +#define GPIO3_INPUT_SET do { GPIO3_CONF; GPIO_DIS_OUTPUT(3); } while(0) +#define GPIO3_INPUT_PULLUP_SET do { GPIO3_INPUT_SET; PIN_PULLUP_EN(GPIO3_MUX); } while(0) +#define GPIO3_IN (GPIO_INPUT_GET(BIT3)) +#define GPIO3_H (GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, BIT3)) +#define GPIO3_L (GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, BIT3)) +#define GPIO3(x) ((x)?GPIO3_H:GPIO3_L) + +/* GPIO4 Macros */ +#define GPIO4_MUX PERIPHS_IO_MUX_GPIO4_U +#define GPIO4_CONF PIN_FUNC_SELECT(GPIO4_MUX, FUNC_GPIO4) +#define GPIO4_OUTPUT_SET do { GPIO4_CONF; GPIO_OUTPUT_SET(4, 0); } while(0) +#define GPIO4_INPUT_SET do { GPIO4_CONF; GPIO_DIS_OUTPUT(4); } while(0) +#define GPIO4_INPUT_PULLUP_SET do { GPIO4_INPUT_SET; PIN_PULLUP_EN(GPIO4_MUX); } while(0) +#define GPIO4_IN (GPIO_INPUT_GET(BIT4)) +#define GPIO4_H (GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, BIT4)) +#define GPIO4_L (GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, BIT4)) +#define GPIO4(x) ((x)?GPIO4_H:GPIO4_L) + +/* GPIO5 Macros */ +#define GPIO5_MUX PERIPHS_IO_MUX_GPIO5_U +#define GPIO5_CONF PIN_FUNC_SELECT(GPIO5_MUX, FUNC_GPIO5) +#define GPIO5_OUTPUT_SET do { GPIO5_CONF; GPIO_OUTPUT_SET(5, 0); } while(0) +#define GPIO5_INPUT_SET do { GPIO5_CONF; GPIO_DIS_OUTPUT(5); } while(0) +#define GPIO5_INPUT_PULLUP_SET do { GPIO5_INPUT_SET; PIN_PULLUP_EN(GPIO5_MUX); } while(0) +#define GPIO5_IN (GPIO_INPUT_GET(BIT5)) +#define GPIO5_H (GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, BIT5)) +#define GPIO5_L (GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, BIT5)) +#define GPIO5(x) ((x)?GPIO5_H:GPIO5_L) + +/* Pins 6-8 not configurable as for gpio */ + +/* GPIO9 Macros */ +#define GPIO9_MUX PERIPHS_IO_MUX_SD_DATA2_U +#define GPIO9_CONF PIN_FUNC_SELECT(GPIO9_MUX, FUNC_GPIO9) +#define GPIO9_OUTPUT_SET do { GPIO9_CONF; GPIO_OUTPUT_SET(9, 0); } while(0) +#define GPIO9_INPUT_SET do { GPIO9_CONF; GPIO_DIS_OUTPUT(9); } while(0) +#define GPIO9_INPUT_PULLUP_SET do { GPIO9_INPUT_SET; PIN_PULLUP_EN(GPIO9_MUX); } while(0) +#define GPIO9_IN (GPIO_INPUT_GET(BIT9)) +#define GPIO9_H (GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, BIT9)) +#define GPIO9_L (GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, BIT9)) +#define GPIO9(x) ((x)?GPIO9_H:GPIO9_L) + +/* GPIO10 Macros */ +#define GPIO10_MUX PERIPHS_IO_MUX_SD_DATA3_U +#define GPIO10_CONF PIN_FUNC_SELECT(GPIO10_MUX, FUNC_GPIO10) +#define GPIO10_OUTPUT_SET do { GPIO10_CONF; GPIO_OUTPUT_SET(10, 0); } while(0) +#define GPIO10_INPUT_SET do { GPIO10_CONF; GPIO_DIS_OUTPUT(10); } while(0) +#define GPIO10_INPUT_PULLUP_SET do { GPIO10_INPUT_SET; PIN_PULLUP_EN(GPIO10_MUX); } while(0) +#define GPIO10_IN (GPIO_INPUT_GET(BIT10)) +#define GPIO10_H (GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, BIT10)) +#define GPIO10_L (GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, BIT10)) +#define GPIO10(x) ((x)?GPIO10_H:GPIO10_L) + +/* Pin 11 not cofigurable as gpio */ + +/* GPIO12 Macros */ +#define GPIO12_MUX PERIPHS_IO_MUX_MTDI_U +#define GPIO12_CONF PIN_FUNC_SELECT(GPIO12_MUX, FUNC_GPIO12) +#define GPIO12_OUTPUT_SET do { GPIO12_CONF; GPIO_OUTPUT_SET(12, 0); } while(0) +#define GPIO12_INPUT_SET do { GPIO12_CONF; GPIO_DIS_OUTPUT(12); } while(0) +#define GPIO12_INPUT_PULLUP_SET do { GPIO12_INPUT_SET; PIN_PULLUP_EN(GPIO12_MUX); } while(0) +#define GPIO12_INPUT_PULLUP_UNSET do { GPIO12_INPUT_SET; PIN_PULLUP_DIS(GPIO12_MUX); } while(0) +#define GPIO12_IN (GPIO_INPUT_GET(12)) +#define GPIO12_H (GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, BIT12)) +#define GPIO12_L (GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, BIT12)) +#define GPIO12(x) ((x)?GPIO12_H:GPIO12_L) + +/* GPIO13 Macros */ +#define GPIO13_MUX PERIPHS_IO_MUX_MTCK_U +#define GPIO13_CONF PIN_FUNC_SELECT(GPIO13_MUX, FUNC_GPIO13) +#define GPIO13_OUTPUT_SET do { GPIO13_CONF; GPIO_OUTPUT_SET(13, 0); } while(0) +#define GPIO13_INPUT_SET do { GPIO13_CONF; GPIO_DIS_OUTPUT(13); } while(0) +#define GPIO13_INPUT_PULLUP_SET do { GPIO13_INPUT_SET; PIN_PULLUP_EN(GPIO13_MUX); } while(0) +#define GPIO13_IN (GPIO_INPUT_GET(BIT13)) +#define GPIO13_H (GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, BIT13)) +#define GPIO13_L (GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, BIT13)) +#define GPIO13(x) ((x)?GPIO13_H:GPIO13_L) + +/* GPIO14 Macros */ +#define GPIO14_MUX PERIPHS_IO_MUX_MTMS_U +#define GPIO14_CONF PIN_FUNC_SELECT(GPIO14_MUX, FUNC_GPIO14) +#define GPIO14_OUTPUT_SET do { GPIO14_CONF; GPIO_OUTPUT_SET(14, 0); } while(0) +#define GPIO14_INPUT_SET do { GPIO14_CONF; GPIO_DIS_OUTPUT(14); } while(0) +#define GPIO14_INPUT_PULLUP_SET do { GPIO14_INPUT_SET; PIN_PULLUP_EN(GPIO14_MUX); } while(0) +#define GPIO14_IN (GPIO_INPUT_GET(14)) +#define GPIO14_H (GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, BIT14)) +#define GPIO14_L (GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, BIT14)) +#define GPIO14(x) ((x)?GPIO14_H:GPIO14_L) + +/* GPIO15 Macros */ +#define GPIO15_MUX PERIPHS_IO_MUX_MTDO_U +#define GPIO15_CONF PIN_FUNC_SELECT(GPIO15_MUX, FUNC_GPIO15) +#define GPIO15_OUTPUT_SET do { GPIO15_CONF; GPIO_OUTPUT_SET(15, 0); } while(0) +#define GPIO15_INPUT_SET do { GPIO15_CONF; GPIO_DIS_OUTPUT(15); } while(0) +#define GPIO15_INPUT_PULLUP_SET do { GPIO15_INPUT_SET; PIN_PULLUP_EN(GPIO15_MUX); } while(0) +#define GPIO15_IN (GPIO_INPUT_GET(BIT15)) +#define GPIO15_H (GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, BIT15)) +#define GPIO15_L (GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, BIT15)) +#define GPIO15(x) ((x)?GPIO15_H:GPIO15_L) + +/* GPIO16 Macros (no pullup enabled) */ +#define GPIO16_CONF \ +do { \ + WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & (uint32_t)0xffffffbd) | (uint32_t)0x1); \ + WRITE_PERI_REG(RTC_GPIO_CONF, (READ_PERI_REG(RTC_GPIO_CONF) & (uint32_t)0xfffffffe) | (uint32_t)0x0); \ +} while(0) +#define GPIO16_OUTPUT_SET \ +do { \ + GPIO16_CONF; \ + WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & (uint32)0xfffffffe) | (uint32)0x1); \ +} while(0) +#define GPIO16_INPUT_SET \ +do { \ + GPIO16_CONF; \ + WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & (uint32)0xfffffffe)); \ +} while(0) +#define GPIO16_IN (uint8_t)(READ_PERI_REG(RTC_GPIO_IN_DATA) & 1) +#define GPIO16_H WRITE_PERI_REG(RTC_GPIO_OUT, (READ_PERI_REG(RTC_GPIO_OUT) & (uint32_t)0xfffffffe) | (uint32_t)(0x1)); +#define GPIO16_L WRITE_PERI_REG(RTC_GPIO_OUT, (READ_PERI_REG(RTC_GPIO_OUT) & (uint32_t)0xfffffffe) | (uint32_t)(0x0)); +#define GPIO16(x) ((x)?GPIO16_H:GPIO16_L) + +#endif diff --git a/net/IP.h b/net/IP.h new file mode 100644 index 0000000..eca1b07 --- /dev/null +++ b/net/IP.h @@ -0,0 +1,27 @@ +#ifndef IP_H +#define IP_H + +#define Port uint16_t + +struct IP { + + uint32_t val; + + /** empty ctor */ + IP() : val(0) { + ; + } + + /** ctor with IP-string */ + IP(const char* ipStr) { + set(ipStr); + } + + /** set the IP */ + void set(const char* ipStr) { + val = ipaddr_addr(ipStr); + } + +}; + +#endif // IP_H diff --git a/net/MAC.h b/net/MAC.h new file mode 100644 index 0000000..c61e752 --- /dev/null +++ b/net/MAC.h @@ -0,0 +1,73 @@ +#ifndef MAC_H +#define MAC_H + +#include +#include +#include + +namespace WiFiRaw { + + struct MACAddress { + + uint8_t a; + uint8_t b; + uint8_t c; + uint8_t d; + uint8_t e; + uint8_t f; + + /** empty ctor */ + MACAddress() {;} + + /** ctor from distinct values */ + MACAddress(const uint8_t a, const uint8_t b, const uint8_t c, const uint8_t d, const uint8_t e, const uint8_t f) : + a(a), b(b), c(c), d(d), e(e), f(f) {;} + + /** ctor from memory region */ + MACAddress(const uint8_t* data) { + memcpy(this, data, 6); + } + + /** equal to the given mac? */ + bool operator == (const MACAddress& o) const { + return (a == o.a) && (b == o.b) && (c == o.c) && (d == o.d) && (e == o.e) && (f == o.f); + } + + std::string asString() const { + + std::string mac; mac.resize(17); + + mac[0] = toHex(a >> 4); + mac[1] = toHex(a >> 0); + mac[2] = ':'; + mac[3] = toHex(b >> 4); + mac[4] = toHex(b >> 0); + mac[5] = ':'; + mac[6] = toHex(c >> 4); + mac[7] = toHex(c >> 0); + mac[8] = ':'; + mac[9] = toHex(d >> 4); + mac[10] = toHex(d >> 0); + mac[11] = ':'; + mac[12] = toHex(e >> 4); + mac[13] = toHex(e >> 0); + mac[14] = ':'; + mac[15] = toHex(f >> 4); + mac[16] = toHex(f >> 0); + + return mac; + + } + + private: + + inline char toHex(uint8_t c) const { + const uint8_t val = c & 0xF; + return (val >= 10) ? ('A' + val - 10) : ('0' + val); + } + + }; + +} + +#endif // MAC_H diff --git a/net/Promiscuous.h b/net/Promiscuous.h new file mode 100644 index 0000000..9f6435c --- /dev/null +++ b/net/Promiscuous.h @@ -0,0 +1,52 @@ +#ifndef PROMISCUOUS_H +#define PROMISCUOUS_H + +struct RxControl { + signed rssi:8; // signal intensity of packet + unsigned rate:4; + unsigned is_group:1; + unsigned:1; + unsigned sig_mode:2; // 0:is 11n packet; 1:is not 11n packet; + unsigned legacy_length:12; // if not 11n packet, shows length of packet. + unsigned damatch0:1; + unsigned damatch1:1; + unsigned bssidmatch0:1; + unsigned bssidmatch1:1; + unsigned MCS:7; // if is 11n packet, shows the modulation // and code used (range from 0 to 76) + unsigned CWB:1; // if is 11n packet, shows if is HT40 packet or not + unsigned HT_length:16;// if is 11n packet, shows length of packet. + unsigned Smoothing:1; + unsigned Not_Sounding:1; + unsigned:1; + unsigned Aggregation:1; + unsigned STBC:2; + unsigned FEC_CODING:1; // if is 11n packet, shows if is LDPC packet or not. + unsigned SGI:1; + unsigned rxend_state:8; + unsigned ampdu_cnt:8; + unsigned channel:4; //which channel this packet in. + unsigned:12; +}; + +struct LenSeq{ + u16 len; // length of packet + u16 seq; // serial number of packet, the high 12bits are serial number, + // low 14 bits are Fragment number (usually be 0) + u8 addr3[6]; // the third address in packet +}; + +struct sniffer_buf{ + struct RxControl rx_ctrl; + u8 buf[36 ]; // head of ieee80211 packet + u16 cnt; // number count of packet + struct LenSeq lenseq[1]; //length of packet +}; + +struct sniffer_buf2{ + struct RxControl rx_ctrl; + uint8_t buf[112]; + uint16_t cnt; + uint16_t len; +}; + +#endif // PROMISCUOUS_H diff --git a/net/UDP.h b/net/UDP.h new file mode 100644 index 0000000..f4b343f --- /dev/null +++ b/net/UDP.h @@ -0,0 +1,103 @@ +#ifndef UDP_H +#define UDP_H + +extern "C" { + #include "mem.h" + #include "espconn.h" +} + +typedef void (*UDPCallback)(void* arg, char* data, unsigned short len); + +#include "../Debug.h" +#include "IP.h" + +class UDP { + +private: + + static constexpr const char* NAME = "UDP"; + + espconn* con; + +public: + + UDP() { + init(); + } + + /** dtor */ + ~UDP() { + cleanup(); + } + + + + /** bind the socket to the given local port */ + void bind(const Port localPort) { + + debugMod1(NAME, "binding to local port %d", localPort); + + // set the local port to listen on + con->proto.udp->local_port = localPort; + + // todo: check? 0=OK + const int res = espconn_create(con); + os_printf("create: %d\r\n", res); + + } + + bool send(const IP ip, const Port port, const void* data, const uint16_t dataLen) { + + debugMod1(NAME, "sending packet to remote port %d", port); + + // set remote port and IP + con->proto.udp->remote_port = port; + os_memcpy(con->proto.udp->remote_ip, &(ip.val), 4); + + //os_printf("send %d bytes\r\n", dataLen); + //os_printf("IP: %d.%d.%d.%d\n\r", con->proto.udp->remote_ip[0], con->proto.udp->remote_ip[1], con->proto.udp->remote_ip[2], con->proto.udp->remote_ip[3]); + + // send. TODO: check. 0=OK + const int res = espconn_sent(con, (unsigned char*)data, dataLen); + return (res == 0); + + } + + /** set the callback to call whenever a packet is received */ + void setRecvCallback(UDPCallback callback) { + espconn_regist_recvcb(con, callback); + } + +private: + + /** initialize the UDP "connection" */ + void init() { + + debugMod(NAME, "init()"); + + // allocate connection-objects + con = (espconn*) os_zalloc(sizeof(espconn)); + ets_memset( con, 0, sizeof( espconn ) ); + + // configure + con->type = ESPCONN_UDP; + //con->state = ESPCONN_NONE; + + con->proto.udp = (esp_udp*) os_zalloc(sizeof(esp_udp)); + + } + + /** cleanup everything */ + void cleanup() { + + debugMod(NAME, "cleanup()"); + + espconn_delete(con); + os_free(con->proto.udp); + os_free(con); + + } + +}; + +#endif // UDP_H diff --git a/net/WiFiRaw.h b/net/WiFiRaw.h new file mode 100644 index 0000000..16b440d --- /dev/null +++ b/net/WiFiRaw.h @@ -0,0 +1,195 @@ +#ifndef WIFIRAW_H +#define WIFIRAW_H + +#include "MAC.h" + +// ifconfig wlp0s26u1u2u1 down && iw dev wlp0s26u1u2u1 set monitor none && ifconfig wlp0s26u1u2u1 up && iw dev wlp0s26u1u2u1 set channel 3 +// ifconfig wlp0s26u1u2u1 down && iw dev wlp0s26u1u2u1 set monitor none && ifconfig wlp0s26u1u2u1 up iwconfig wlp0s26u1u2u1 channel 3 + +// https://supportforums.cisco.com/document/52391/80211-frames-starter-guide-learn-wireless-sniffer-traces + +namespace WiFiRaw { + + /** frame type */ + enum Type { + MANAGEMENT = 0b00, + CONTROL = 0b01, + DATA = 0b10, + RESERVED = 0b11, + }; + + /** frame sub-type */ + enum SubType { + + DATA_DATA = 0b0000, + DATA_DATA_CF_ACK = 0b0001, + DATA_DATA_CF_POLL = 0b0010, + DATA_DATA_CF_ACK_POLL = 0b0011, + DATA_NULL = 0b0100, + DATA_QOS = 0b1000, + + MGMT_ASSOC_REQUEST = 0b0000, + MGMT_PROBE_REQUEST = 0b0100, + MGMT_BEACON = 0b1000, + MGMT_DISASSOCIATION = 0b1010, + + }; + + /** + * 2 byte segment and fragment number. + * usually set by the ESP itself + */ + struct Fragment { + + uint8_t data[2]; + + /** empty ctor */ + Fragment() : data() {;} + + /** ctor with values */ + Fragment(const uint8_t fragNr, const uint16_t seqNr) { + data[1] = seqNr >> 4; + data[0] = seqNr << 4 | fragNr; + } + }; + +// /** +// * 4 byte checksum. +// * usually set by the ESP itself +// */ +// struct FCS { +// uint8_t data[4]; +// FCS() : data() {;} +// }; + + struct Header { + + uint8_t version : 2; // always 0 + uint8_t type : 2; // see enum + uint8_t subType : 4; // see enum + + struct Flags { + + uint8_t toDS : 1; // always 0 + uint8_t fromDS : 1; // unencrypted: 0 + uint8_t moreFragments : 1; // no more data: 0 , more data: 1 + uint8_t retransmission : 1; // no retransmission: 0, retransmission: 1 + uint8_t powerManagement : 1; // i am fully active: 0, tell AP that i safe power: 1, + uint8_t moreData : 1; // ? + uint8_t protectedPkt : 1; // 1 = encrypted, 0 = unencrypted + uint8_t strictlyOrdered : 1; // 0 = not strictly ordered + + Flags() : + toDS(0), fromDS(0), moreFragments(0), retransmission(0), powerManagement(0), + moreData(0), protectedPkt(0), strictlyOrdered(0) {;} + + } flags; + + uint16_t duration; // ?? + + Header(Type type, SubType subType) : version(0), type(type), subType(subType), duration(0) { + ; + } + + }; + + struct Timestamp { + + uint8_t data[8]; + + Timestamp() : data() {;} + + }; + + struct BeaconInterval { + + uint8_t data[2]; + + BeaconInterval() { + data[0] = 0x64; + data[1] = 0x00; + } + + }; + + struct Capabilities { + + uint8_t isSTA : 1; + uint16_t empty : 15; + + Capabilities() : isSTA(1), empty(0) {;} + }; + + /** base-struct for management frames */ + struct ManagementFrame { + + Timestamp ts; + BeaconInterval interval; + Capabilities capa; + + ManagementFrame() : ts(), interval(), capa() {;} + + }; + + struct UnknownPkt { + Header header; + WiFiRaw::MACAddress destination; + WiFiRaw::MACAddress transmitter; + WiFiRaw::MACAddress bssid; + }; + + + /** beacon packet */ + template struct BeaconPkt { + + Header header; + WiFiRaw::MACAddress destination; // usually broadcast ff:ff:ff:ff:ff:ff + WiFiRaw::MACAddress transmitter; // usually the AP's MAC + WiFiRaw::MACAddress bssid; // the AP's MAC + Fragment frag; + + ManagementFrame mgmt; + + T data; + + //FCS fcs; + + BeaconPkt(const WiFiRaw::MACAddress myMAC) : + header(MANAGEMENT, MGMT_BEACON), destination(0xFF,0xFF,0xFF,0xFF,0xFF,0xFF), transmitter(myMAC), bssid(myMAC) { + ; + } + + }; + + /** data packet */ + template struct DataPkt { + + Header header; + WiFiRaw::MACAddress bssid; // the AP's mac + WiFiRaw::MACAddress transmitter; // my mac + WiFiRaw::MACAddress destination; // the receiver's mac + + Fragment frag; + + uint8_t data[size]; + + //FCS fcs; + + DataPkt(const WiFiRaw::MACAddress& mine, const WiFiRaw::MACAddress& receiver, const WiFiRaw::MACAddress& bssid) : + header(DATA, DATA_DATA_CF_ACK), bssid(bssid), transmitter(mine), destination(receiver) { + header.flags.toDS = 1; + } + + }; + + + WiFiRaw::MACAddress getMyMAC() { + WiFiRaw::MACAddress mine; + wifi_get_macaddr(0x00, (uint8_t*)&mine); + return mine; + } + + +}; + +#endif // WIFIRAW_H