mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-11-04 09:01:40 +01:00 
			
		
		
		
	
		
			
	
	
		
			167 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			167 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Licensed under the Apache License, Version 2.0 (the "License");
							 | 
						||
| 
								 | 
							
								// you may not use this file except in compliance with the License.
							 | 
						||
| 
								 | 
							
								// You may obtain a copy of the License at
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//     http://www.apache.org/licenses/LICENSE-2.0
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Unless required by applicable law or agreed to in writing, software
							 | 
						||
| 
								 | 
							
								// distributed under the License is distributed on an "AS IS" BASIS,
							 | 
						||
| 
								 | 
							
								// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
							 | 
						||
| 
								 | 
							
								// See the License for the specific language governing permissions and
							 | 
						||
| 
								 | 
							
								// limitations under the License.
							 | 
						||
| 
								 | 
							
								#include "esp_netif.h"
							 | 
						||
| 
								 | 
							
								#include "esp_log.h"
							 | 
						||
| 
								 | 
							
								#include "driver/uart.h"
							 | 
						||
| 
								 | 
							
								#include "esp_console.h"
							 | 
						||
| 
								 | 
							
								#include "esp_vfs_dev.h"
							 | 
						||
| 
								 | 
							
								#include "linenoise/linenoise.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Internal functions declaration referenced in io object
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								static esp_err_t netsuite_io_transmit(void *h, void *buffer, size_t len);
							 | 
						||
| 
								 | 
							
								static esp_err_t netsuite_io_attach(esp_netif_t * esp_netif, void * args);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief IO object netif related configuration with data-path function callbacks
							 | 
						||
| 
								 | 
							
								 * and pointer to the IO object instance (unused as this is a singleton)
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								const esp_netif_driver_ifconfig_t c_driver_ifconfig = {
							 | 
						||
| 
								 | 
							
								        .driver_free_rx_buffer = NULL,
							 | 
						||
| 
								 | 
							
								        .transmit = netsuite_io_transmit,
							 | 
						||
| 
								 | 
							
								        .handle = "netsuite-io-object" // this IO object is a singleton, its handle uses as a name
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief IO object base structure used to point to internal attach function
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								const esp_netif_driver_base_t s_driver_base = {
							 | 
						||
| 
								 | 
							
								        .post_attach =  netsuite_io_attach
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief Transmit function called from esp_netif to output network stack data
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Note: This API has to conform to esp-netif transmit prototype
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param h Opaque pointer representing the io driver (unused, const string in this case)
							 | 
						||
| 
								 | 
							
								 * @param data data buffer
							 | 
						||
| 
								 | 
							
								 * @param length length of data to send
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @return ESP_OK on success
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static esp_err_t netsuite_io_transmit(void *h, void *buffer, size_t len)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    /* output the packet to stdout */
							 | 
						||
| 
								 | 
							
								    char *data = buffer;
							 | 
						||
| 
								 | 
							
								    printf("\nPacketOut:[");
							 | 
						||
| 
								 | 
							
								    for (size_t i=0; i<len; i++) {
							 | 
						||
| 
								 | 
							
								        printf("%02x", *data++);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    printf("]\n");
							 | 
						||
| 
								 | 
							
								    return ESP_OK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief Post attach adapter for netsuite i/o
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Used to exchange internal callbacks and context between esp-netif and the I/O object.
							 | 
						||
| 
								 | 
							
								 * In case of netsuite I/O, it only updates the driver config with internal callbacks and
							 | 
						||
| 
								 | 
							
								 * its instance pointer (const string in this case)
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param esp_netif handle to esp-netif object
							 | 
						||
| 
								 | 
							
								 * @param args pointer to netsuite IO
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @return ESP_OK on success
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static esp_err_t netsuite_io_attach(esp_netif_t * esp_netif, void * args)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ESP_ERROR_CHECK(esp_netif_set_driver_config(esp_netif, &c_driver_ifconfig));
							 | 
						||
| 
								 | 
							
								    return ESP_OK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief Process line read from serial input, character by character
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Converts from hex string to byte stream, so it can be processed
							 | 
						||
| 
								 | 
							
								 * in test network interface
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param line
							 | 
						||
| 
								 | 
							
								 * @param packet
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @return size of packet
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static size_t process_line(char* line, char* packet)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    size_t count = 0;
							 | 
						||
| 
								 | 
							
								    size_t i;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (i=0; i< strlen(line); i++) {
							 | 
						||
| 
								 | 
							
								        char c = line[i];
							 | 
						||
| 
								 | 
							
								        // accept both separators between bytes
							 | 
						||
| 
								 | 
							
								        if (c == '-' || c == ' ') {
							 | 
						||
| 
								 | 
							
								            ++count;
							 | 
						||
| 
								 | 
							
								            // Processing numeric characters
							 | 
						||
| 
								 | 
							
								        } else if (c >= '0' && c <= '9') {
							 | 
						||
| 
								 | 
							
								            packet[count] *= 16;
							 | 
						||
| 
								 | 
							
								            packet[count] += c - '0';
							 | 
						||
| 
								 | 
							
								            // Processing alpha-numeric hex characters
							 | 
						||
| 
								 | 
							
								        } else if (c >= 'a' && c <= 'f') {
							 | 
						||
| 
								 | 
							
								            packet[count] *= 16;
							 | 
						||
| 
								 | 
							
								            packet[count] += c - 'a' + 10;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (i>0 && strlen(line)>0) {
							 | 
						||
| 
								 | 
							
								        count++;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return count;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Created (initializes) the i/o object and returns handle ready to be attached to the esp-netif
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								void * netsuite_io_new(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    // Initialize VFS & UART so we can use std::cout/cin
							 | 
						||
| 
								 | 
							
								    setvbuf(stdin, NULL, _IONBF, 0);
							 | 
						||
| 
								 | 
							
								    setvbuf(stdout, NULL, _IONBF, 0);
							 | 
						||
| 
								 | 
							
								    /* Install UART driver for interrupt-driven reads and writes */
							 | 
						||
| 
								 | 
							
								    ESP_ERROR_CHECK( uart_driver_install( (uart_port_t)CONFIG_ESP_CONSOLE_UART_NUM,
							 | 
						||
| 
								 | 
							
								                                          256, 0, 0, NULL, 0) );
							 | 
						||
| 
								 | 
							
								    /* Tell VFS to use UART driver */
							 | 
						||
| 
								 | 
							
								    esp_vfs_dev_uart_use_driver(CONFIG_ESP_CONSOLE_UART_NUM);
							 | 
						||
| 
								 | 
							
								    esp_vfs_dev_uart_set_rx_line_endings(ESP_LINE_ENDINGS_CR);
							 | 
						||
| 
								 | 
							
								    /* Move the caret to the beginning of the next line on '\n' */
							 | 
						||
| 
								 | 
							
								    esp_vfs_dev_uart_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF);
							 | 
						||
| 
								 | 
							
								    linenoiseSetDumbMode(1);
							 | 
						||
| 
								 | 
							
								    return (void *)&s_driver_base;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * I/O receive function
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								ssize_t netsuite_io_get_packet(char *packet, size_t max_len)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    size_t size;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* read packet from stdin */
							 | 
						||
| 
								 | 
							
								    char* line = linenoise("");
							 | 
						||
| 
								 | 
							
								    if (!line) {
							 | 
						||
| 
								 | 
							
								        return -1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* convert to binary */
							 | 
						||
| 
								 | 
							
								    size = process_line(line, packet);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (size > max_len) {
							 | 
						||
| 
								 | 
							
								        return -1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    linenoiseFree(line);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return size;
							 | 
						||
| 
								 | 
							
								}
							 |