mirror of
https://github.com/martin-ger/esp_wifi_repeater.git
synced 2023-04-24 01:48:22 +03:00
Added remote monitoring capability
This commit is contained in:
Binary file not shown.
Binary file not shown.
1
include/string.h
Normal file
1
include/string.h
Normal file
@@ -0,0 +1 @@
|
||||
//Nothing here.
|
||||
27
user/pcap.h
Normal file
27
user/pcap.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef __PCAP_H__
|
||||
#define __PCAP_H__
|
||||
|
||||
#define PCAP_VERSION_MAJOR 2
|
||||
#define PCAP_VERSION_MINOR 4
|
||||
#define PCAP_MAGIC_NUMBER 0xa1b2c3d4
|
||||
|
||||
#define LINKTYPE_ETHERNET 1
|
||||
|
||||
struct pcap_file_header {
|
||||
uint32_t magic;
|
||||
uint16_t version_major;
|
||||
uint16_t version_minor;
|
||||
uint32_t thiszone; /* gmt to local correction */
|
||||
uint32_t sigfigs; /* accuracy of timestamps */
|
||||
uint32_t snaplen; /* max length saved portion of each pkt */
|
||||
uint32_t linktype; /* data link type (LINKTYPE_*) */
|
||||
};
|
||||
|
||||
struct pcap_pkthdr {
|
||||
uint32_t ts_sec; /* time stamp sec */
|
||||
uint32_t ts_usec; /* time stamp usec */
|
||||
uint32_t caplen; /* length of portion present */
|
||||
uint32_t len; /* length this packet (off wire) */
|
||||
};
|
||||
|
||||
#endif /* __PCAP_H__ */
|
||||
@@ -92,7 +92,30 @@ int ring_buffer_enqueue(ring_buffer_t *rbuff, uint8_t ch)
|
||||
|
||||
}
|
||||
|
||||
uint8_t ring_buffer_dequeue(ring_buffer_t *rbuff)
|
||||
#ifdef RB_ENABLE_DISCARD
|
||||
int ring_buffer_enqueue_bulk(ring_buffer_t *rbuff, uint8_t *inp, int len)
|
||||
{
|
||||
int temp_flag = 0;
|
||||
if (rbuff == NULL) return -1; // Check for valid structure
|
||||
if (rbuff->buffer == NULL) return -1; // Check if it in initialized
|
||||
|
||||
if (rbuff->data_present + len > rbuff->buffer_size) return -1; // too large - discard all
|
||||
|
||||
if (rbuff->end_ptr - rbuff->write_ptr > len) {
|
||||
os_memcpy(rbuff->write_ptr, inp, len);
|
||||
rbuff->write_ptr += len;
|
||||
rbuff->data_present += len;
|
||||
} else {
|
||||
int i;
|
||||
for (i=0; i<len;i++) {
|
||||
ring_buffer_enqueue(rbuff, inp[i]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int ring_buffer_dequeue(ring_buffer_t *rbuff)
|
||||
{
|
||||
uint8_t ch;
|
||||
if (rbuff == NULL) return -1; // Check for valid structure
|
||||
@@ -101,7 +124,7 @@ uint8_t ring_buffer_dequeue(ring_buffer_t *rbuff)
|
||||
if (rbuff->data_present == 0)
|
||||
{
|
||||
DBG("\nDeQueuuing from RingBuffer - No Data in ring buffer [%d] \n", rbuff->data_present);
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -114,11 +137,11 @@ uint8_t ring_buffer_dequeue(ring_buffer_t *rbuff)
|
||||
|
||||
//DBG("DeQueuuing from RingBuffer %c [%3d]\n", ch, rbuff->data_present);
|
||||
|
||||
return ch;
|
||||
return (int)ch;
|
||||
}
|
||||
|
||||
uint16_t ring_buffer_data(ring_buffer_t *rbuff)
|
||||
{
|
||||
DBG("\nData in ring buffer: %d\n", rbuff->data_present);
|
||||
return (rbuff->data_present);
|
||||
}
|
||||
|
||||
uint16_t ring_buffer_data(ring_buffer_t *rbuff)
|
||||
{
|
||||
DBG("\nData in ring buffer: %d\n", rbuff->data_present);
|
||||
return (rbuff->data_present);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#ifndef _RING_BUFFER_H_
|
||||
#define _RING_BUFFER_H_
|
||||
|
||||
#include "ets_sys.h"
|
||||
#include "osapi.h"
|
||||
#include "osapi.h"
|
||||
#include "mem.h"
|
||||
#include "os_type.h"
|
||||
#include "ets_sys.h"
|
||||
#include "osapi.h"
|
||||
#include "osapi.h"
|
||||
#include "mem.h"
|
||||
#include "os_type.h"
|
||||
|
||||
//typedef unsigned char uint8_t;
|
||||
// typedef unsigned int uint16_t;
|
||||
@@ -21,7 +21,8 @@ typedef struct ring_buffer
|
||||
|
||||
ring_buffer_t * ring_buffer_init(int max_size);
|
||||
int ring_buffer_enqueue(ring_buffer_t *rbuff, uint8_t ch);
|
||||
uint8_t ring_buffer_dequeue(ring_buffer_t *rbuff);
|
||||
uint16_t ring_buffer_data(ring_buffer_t *rbuff);
|
||||
int ring_buffer_enqueue_bulk(ring_buffer_t *rbuff, uint8_t *inp, int len);
|
||||
int ring_buffer_dequeue(ring_buffer_t *rbuff);
|
||||
uint16_t ring_buffer_data(ring_buffer_t *rbuff);
|
||||
uint16_t ring_buffer_clear(ring_buffer_t *rbuff);
|
||||
#endif // _RING_BUFFER_H_
|
||||
|
||||
@@ -9,8 +9,22 @@ typedef enum {SIG_DO_NOTHING=0, SIG_START_SERVER=1, SIG_SEND_DATA, SIG_UART0, SI
|
||||
#define WIFI_AP_SSID "MyAP"
|
||||
#define WIFI_AP_PASSWORD "none"
|
||||
|
||||
#define SERVER_PORT 7777
|
||||
|
||||
#define MAX_CLIENTS 10
|
||||
|
||||
//
|
||||
// Define this if you want to have access to the config console via TCP.
|
||||
// Ohterwise only local access via serial is possible
|
||||
//
|
||||
#define REMOTE_CONFIG 1
|
||||
#define CONSOLE_SERVER_PORT 7777
|
||||
|
||||
//
|
||||
// Define this if you want to offer monitoring access to all transmitted data between the soft AP and all STAs.
|
||||
// Data is mirrored in pcap format to the given port
|
||||
// CAUTION: this might be a privacy issue!!!
|
||||
//
|
||||
//#define REMOTE_MONITORING 1
|
||||
#define MONITOR_SERVER_PORT 8888
|
||||
//#define DROP_PACKET_IF_NOT_RECORDED 1
|
||||
|
||||
#endif
|
||||
|
||||
226
user/user_main.c
226
user/user_main.c
@@ -19,7 +19,14 @@
|
||||
#include "ring_buffer.h"
|
||||
#include "config_flash.h"
|
||||
|
||||
/* Hold the sytem wise configuration */
|
||||
#ifdef REMOTE_MONITORING
|
||||
#include "pcap.h"
|
||||
#endif
|
||||
|
||||
/* Some stats */
|
||||
uint32_t Bytes_in = 0, Bytes_out = 0;
|
||||
|
||||
/* Hold the system wide configuration */
|
||||
sysconfig_t config;
|
||||
|
||||
/* System Task, for signals refer to user_config.h */
|
||||
@@ -29,11 +36,166 @@ os_event_t user_procTaskQueue[user_procTaskQueueLen];
|
||||
static void user_procTask(os_event_t *events);
|
||||
|
||||
static ring_buffer_t *console_rx_buffer, *console_tx_buffer;
|
||||
static char hwaddr[6];
|
||||
|
||||
struct netif *netif_ap;
|
||||
static netif_input_fn orig_input_ap;
|
||||
static netif_linkoutput_fn orig_output_ap;
|
||||
|
||||
#ifdef REMOTE_MONITORING
|
||||
static uint8_t monitoring_on = 0;
|
||||
static ring_buffer_t *pcap_buffer;
|
||||
struct espconn *cur_mon_conn;
|
||||
static uint8_t monitoring_send_ongoing = 0;
|
||||
|
||||
static void ICACHE_FLASH_ATTR tcp_monitor_sent_cb(void *arg)
|
||||
{
|
||||
uint16_t len, remainder;
|
||||
|
||||
struct espconn *pespconn = (struct espconn *)arg;
|
||||
//os_printf("tcp_client_sent_cb(): Data sent to monitor\n");
|
||||
|
||||
monitoring_send_ongoing = 0;
|
||||
if (!monitoring_on) return;
|
||||
|
||||
len = pcap_buffer->data_present;
|
||||
if (len > 0) {
|
||||
if (len > 1400)
|
||||
len = 1400;
|
||||
|
||||
remainder = pcap_buffer->end_ptr - pcap_buffer->read_ptr + 1;
|
||||
if (remainder < len)
|
||||
len = remainder;
|
||||
|
||||
//os_printf("tcp_monitor_sent_cb(): %d Bytes sent to monitor\n", len);
|
||||
espconn_sent(pespconn, pcap_buffer->read_ptr, len);
|
||||
monitoring_send_ongoing = 1;
|
||||
|
||||
pcap_buffer->data_present -= len;
|
||||
pcap_buffer->read_ptr += len;
|
||||
if (pcap_buffer->read_ptr == pcap_buffer->end_ptr + 1)
|
||||
pcap_buffer->read_ptr = pcap_buffer->buffer;
|
||||
}
|
||||
}
|
||||
|
||||
static void ICACHE_FLASH_ATTR tcp_monitor_discon_cb(void *arg)
|
||||
{
|
||||
os_printf("tcp_monitor_discon_cb(): client disconnected\n");
|
||||
struct espconn *pespconn = (struct espconn *)arg;
|
||||
|
||||
monitoring_on = 0;
|
||||
while (pcap_buffer->data_present)
|
||||
ring_buffer_dequeue(pcap_buffer);
|
||||
}
|
||||
|
||||
|
||||
/* Called when a client connects to the monitor server */
|
||||
static void ICACHE_FLASH_ATTR tcp_monitor_connected_cb(void *arg)
|
||||
{
|
||||
struct espconn *pespconn = (struct espconn *)arg;
|
||||
struct pcap_file_header pcf_hdr;
|
||||
|
||||
int fputs_into_ringbuff(ring_buffer_t *buffer, uint8_t *strbuffer, int length)
|
||||
os_printf("tcp_monitor_connected_cb(): Client connected\r\n");
|
||||
|
||||
pcap_buffer->write_ptr = pcap_buffer->read_ptr = pcap_buffer->buffer;
|
||||
pcap_buffer->end_ptr = pcap_buffer->buffer + pcap_buffer->buffer_size - 1;
|
||||
pcap_buffer->rb_empty = 1;
|
||||
pcap_buffer->rb_full = 0;
|
||||
pcap_buffer->data_present = 0;
|
||||
|
||||
cur_mon_conn = pespconn;
|
||||
|
||||
espconn_regist_sentcb(pespconn, tcp_monitor_sent_cb);
|
||||
espconn_regist_disconcb(pespconn, tcp_monitor_discon_cb);
|
||||
//espconn_regist_recvcb(pespconn, tcp_client_recv_cb);
|
||||
espconn_regist_time(pespconn, 300, 1); // Specific to console only
|
||||
|
||||
pcf_hdr.magic = PCAP_MAGIC_NUMBER;
|
||||
pcf_hdr.version_major = PCAP_VERSION_MAJOR;
|
||||
pcf_hdr.version_minor = PCAP_VERSION_MINOR;
|
||||
pcf_hdr.thiszone = 0;
|
||||
pcf_hdr.sigfigs = 0;
|
||||
pcf_hdr.snaplen = 1600;
|
||||
pcf_hdr.linktype = LINKTYPE_ETHERNET;
|
||||
|
||||
espconn_sent(pespconn, (uint8_t *)&pcf_hdr, sizeof(pcf_hdr));
|
||||
monitoring_send_ongoing = 1;
|
||||
|
||||
monitoring_on = 1;
|
||||
}
|
||||
|
||||
|
||||
int ICACHE_FLASH_ATTR put_packet_to_ringbuf(ring_buffer_t *buf, struct pbuf *p) {
|
||||
struct pcap_pkthdr pcap_phdr;
|
||||
uint32_t t_usecs;
|
||||
|
||||
if (buf->buffer_size-buf->data_present >= sizeof(pcap_phdr)+p->len) {
|
||||
//os_printf("Put %d Bytes into RingBuff\r\n", sizeof(pcap_phdr)+p->len);
|
||||
t_usecs = system_get_time();
|
||||
pcap_phdr.ts_sec = t_usecs/1000000;
|
||||
pcap_phdr.ts_usec = t_usecs%1000000;
|
||||
pcap_phdr.caplen = p->len;
|
||||
pcap_phdr.len = p->tot_len;
|
||||
ring_buffer_enqueue_bulk(buf, (uint8_t*)&pcap_phdr, sizeof(pcap_phdr));
|
||||
if (p->len != p->tot_len)
|
||||
os_printf(">>>Len %d != TotalLen %d!\r\n", p->len, p->tot_len);
|
||||
ring_buffer_enqueue_bulk(buf, p->payload, p->len);
|
||||
} else {
|
||||
//os_printf("Packet with %d Bytes discarded\r\n", p->len);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
err_t ICACHE_FLASH_ATTR my_input_ap (struct pbuf *p, struct netif *inp) {
|
||||
|
||||
//os_printf("Got packet from STA\r\n");
|
||||
Bytes_in += p->tot_len;
|
||||
|
||||
#ifdef REMOTE_MONITORING
|
||||
if (monitoring_on) {
|
||||
if (put_packet_to_ringbuf(pcap_buffer, p) == 0) {
|
||||
if (!monitoring_send_ongoing)
|
||||
tcp_monitor_sent_cb(cur_mon_conn);
|
||||
} else {
|
||||
#ifdef DROP_PACKET_IF_NOT_RECORDED
|
||||
pbuf_free(p);
|
||||
return;
|
||||
#else
|
||||
os_printf(".", p->len);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
orig_input_ap (p, inp);
|
||||
}
|
||||
|
||||
err_t ICACHE_FLASH_ATTR my_output_ap (struct netif *outp, struct pbuf *p) {
|
||||
|
||||
//os_printf("Send packet to STA\r\n");
|
||||
Bytes_out += p->tot_len;
|
||||
|
||||
#ifdef REMOTE_MONITORING
|
||||
if (monitoring_on) {
|
||||
if (put_packet_to_ringbuf(pcap_buffer, p) == 0) {
|
||||
if (!monitoring_send_ongoing)
|
||||
tcp_monitor_sent_cb(cur_mon_conn);
|
||||
} else {
|
||||
#ifdef DROP_PACKET_IF_NOT_RECORDED
|
||||
pbuf_free(p);
|
||||
return;
|
||||
#else
|
||||
os_printf(".", p->len);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
orig_output_ap (outp, p);
|
||||
}
|
||||
|
||||
int ICACHE_FLASH_ATTR fputs_into_ringbuff(ring_buffer_t *buffer, uint8_t *strbuffer, int length)
|
||||
{
|
||||
uint8_t index = 0, ch;
|
||||
for (index = 0; index < length; index++)
|
||||
@@ -45,7 +207,7 @@ int fputs_into_ringbuff(ring_buffer_t *buffer, uint8_t *strbuffer, int length)
|
||||
return index;
|
||||
}
|
||||
|
||||
int fgets_from_ringbuff(ring_buffer_t *buffer, uint8_t *strbuffer, int max_length)
|
||||
int ICACHE_FLASH_ATTR fgets_from_ringbuff(ring_buffer_t *buffer, uint8_t *strbuffer, int max_length)
|
||||
{
|
||||
uint8_t max_unload, i, index = 0;
|
||||
uint8_t bytes_ringbuffer = buffer->data_present;
|
||||
@@ -206,6 +368,8 @@ void console_handle_command(struct espconn *pespconn)
|
||||
config.ap_password,
|
||||
config.ap_open);
|
||||
fputs_into_ringbuff(console_tx_buffer, response, os_strlen(response));
|
||||
os_sprintf(response, "Bytes in %d Bytes out %d\r\n", Bytes_in, Bytes_out);
|
||||
fputs_into_ringbuff(console_tx_buffer, response, os_strlen(response));
|
||||
goto command_handled;
|
||||
}
|
||||
}
|
||||
@@ -328,7 +492,7 @@ command_handled:
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#ifdef REMOTE_CONFIG
|
||||
static void ICACHE_FLASH_ATTR tcp_client_recv_cb(void *arg,
|
||||
char *data,
|
||||
unsigned short length)
|
||||
@@ -351,11 +515,6 @@ static void ICACHE_FLASH_ATTR tcp_client_recv_cb(void *arg,
|
||||
*(data+length) = 0;
|
||||
}
|
||||
|
||||
static void ICACHE_FLASH_ATTR tcp_client_sent_cb(void *arg)
|
||||
{
|
||||
struct espconn *pespconn = (struct espconn *)arg;
|
||||
os_printf("tcp_client_sent_cb(): Data sent to client\n");
|
||||
}
|
||||
|
||||
static void ICACHE_FLASH_ATTR tcp_client_discon_cb(void *arg)
|
||||
{
|
||||
@@ -363,7 +522,8 @@ static void ICACHE_FLASH_ATTR tcp_client_discon_cb(void *arg)
|
||||
struct espconn *pespconn = (struct espconn *)arg;
|
||||
}
|
||||
|
||||
/* Called wen a client connects to server */
|
||||
|
||||
/* Called when a client connects to the console server */
|
||||
static void ICACHE_FLASH_ATTR tcp_client_connected_cb(void *arg)
|
||||
{
|
||||
char payload[128];
|
||||
@@ -371,15 +531,14 @@ static void ICACHE_FLASH_ATTR tcp_client_connected_cb(void *arg)
|
||||
|
||||
os_printf("tcp_client_connected_cb(): Client connected\r\n");
|
||||
|
||||
wifi_get_macaddr(0, hwaddr);
|
||||
|
||||
//espconn_regist_sentcb(pespconn, tcp_client_sent_cb);
|
||||
espconn_regist_disconcb(pespconn, tcp_client_discon_cb);
|
||||
espconn_regist_recvcb(pespconn, tcp_client_recv_cb);
|
||||
espconn_regist_time(pespconn, 15, 1); // Specific to console only
|
||||
espconn_regist_time(pespconn, 300, 1); // Specific to console only
|
||||
os_sprintf(payload, "CMD>");
|
||||
espconn_sent(pespconn, payload, os_strlen(payload));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//Priority 0 Task
|
||||
@@ -396,8 +555,16 @@ static void ICACHE_FLASH_ATTR user_procTask(os_event_t *events)
|
||||
netif_sta = netif_list->next;
|
||||
//os_printf("STA: %c%c%d\r\n", netif_sta->name[0], netif_sta->name[1], netif_sta->num);
|
||||
|
||||
/* Switch AP to NAT */
|
||||
netif_ap->napt = 1;
|
||||
|
||||
/* Hook into the traffic of the internal AP */
|
||||
orig_input_ap = netif_ap->input;
|
||||
netif_ap->input = my_input_ap;
|
||||
|
||||
orig_output_ap = netif_ap->linkoutput;
|
||||
netif_ap->linkoutput = my_output_ap;
|
||||
|
||||
break;
|
||||
|
||||
case SIG_CONSOLE_TX:
|
||||
@@ -536,7 +703,8 @@ void ICACHE_FLASH_ATTR user_init()
|
||||
wifi_set_opmode(STATIONAP_MODE);
|
||||
user_set_softap_config();
|
||||
|
||||
os_printf("Starting TCP Server on %d port\r\n", SERVER_PORT);
|
||||
#ifdef REMOTE_CONFIG
|
||||
os_printf("Starting Console TCP Server on %d port\r\n", CONSOLE_SERVER_PORT);
|
||||
struct espconn *pCon = (struct espconn *)os_zalloc(sizeof(struct espconn));
|
||||
if (pCon == NULL)
|
||||
{
|
||||
@@ -548,13 +716,39 @@ void ICACHE_FLASH_ATTR user_init()
|
||||
pCon->type = ESPCONN_TCP;
|
||||
pCon->state = ESPCONN_NONE;
|
||||
pCon->proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp));
|
||||
pCon->proto.tcp->local_port = SERVER_PORT;
|
||||
pCon->proto.tcp->local_port = CONSOLE_SERVER_PORT;
|
||||
|
||||
/* Register callback when clients connect to the server */
|
||||
espconn_regist_connectcb(pCon, tcp_client_connected_cb);
|
||||
|
||||
/* Put the connection in accept mode */
|
||||
espconn_accept(pCon);
|
||||
#endif
|
||||
|
||||
#ifdef REMOTE_MONITORING
|
||||
pcap_buffer = ring_buffer_init(0x4000);
|
||||
|
||||
os_printf("Starting Monitor TCP Server on %d port\r\n", MONITOR_SERVER_PORT);
|
||||
struct espconn *mCon = (struct espconn *)os_zalloc(sizeof(struct espconn));
|
||||
if (mCon == NULL)
|
||||
{
|
||||
os_printf("CONNECT FAIL\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Equivalent to bind */
|
||||
mCon->type = ESPCONN_TCP;
|
||||
mCon->state = ESPCONN_NONE;
|
||||
mCon->proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp));
|
||||
mCon->proto.tcp->local_port = MONITOR_SERVER_PORT;
|
||||
|
||||
/* Register callback when clients connect to the server */
|
||||
espconn_regist_connectcb(mCon, tcp_monitor_connected_cb);
|
||||
|
||||
/* Put the connection in accept mode */
|
||||
espconn_accept(mCon);
|
||||
#endif
|
||||
|
||||
|
||||
// Now start the STA-Mode
|
||||
user_set_station_config();
|
||||
|
||||
Reference in New Issue
Block a user