• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Разработка ‘библиотеки’ малого webсервера на esp8266.

pvvx

Активный участник сообщества
программный RTS у меня в контроллере STM32F405, на ESP8266 аппаратный.
Да не всё гладко, но на скорости 460800, работает стабильно.
Если выше то бывают потери байт.
Я решил переписать TCP2UART часть. Там сейчас всё очень плохо и ещё поменялся метод работы с пакетами TCP... Старая часть была прикручена к старому методу работы tcp_srv_conn и ныне уже можно задавать более жесткие условия, т.к. SDK почти изучен и можно изменить что не нравится.
 

lincinus

New member


А такое поведение тоже с этим может быть связано? (у меня версия свалка ver 0.2.8 (25.04.15) на PvSDK version: 0.0.0 (b1))

в какой то момент esp (192.168.1.251) пропускает подтверждение доставки и начинает бесконечно пытаться синхронизировать соединение, пока заново не переподключишься
Похоже проблема только в режиме
Sleep Mode: LIGHT
в режиме MODEM работает стабильно
 
Последнее редактирование:

sharikov

Active member
Я решил переписать TCP2UART часть.
Насколько радикально вы собираетесь переписать tcp_terminal.c ?
Я хотел добавить в ваш код TCP2UART поддержку RFC 2217 взяв за основу исходник Sercd
http://sourceforge.net/p/sercd/code/HEAD/tree/trunk/sercd.c
Потому что реально есть потребность в компорте как минимум с сигналами rts и dtr. Чтобы работала прошивка через уарт lpc1xxx, stm32 и всего остального что шьется по уарт (включая esp) причем используя их штатное по для прошивки.

Еще: при разрыве или закрытии соединения вы запрещаете все прерывания uart функцией tcp_term_int_rxtx_disable
Передастся ли остаток в буфере передачи ? Подозреваю что нет.
Это неправильно. При закрытии соединения следует прекратить прием но все остающиеся данные из буфера передачи нужно выдать в tx uart.
 

pvvx

Активный участник сообщества
Насколько радикально вы собираетесь переписать tcp_terminal.c ?
Достаточно радикально. Пислал же и предварительный тест показал, что передача и одновременно прием идет на 3Mbaud. Больше проверить пока не могу - FT2232 и меня на 3Mbaud в пределе - больше не хочет. В наляпанном наскоро тесте по новому алго выходят дырки, по несколько ms, пролетающие через несколько секунд... Остается переписать правильно, но это долго... А в старой "стряпнине" слишком много ошибок и глупостей. Оно писалось не для работы, а чтобы показать, что на ESP8266 возможен нормальный TCP2UART, а не кривизна на NodeMCU и подобном со скоростями до 1 килобайта в секунду. :)
Еще: при разрыве или закрытии соединения вы запрещаете все прерывания uart функцией tcp_term_int_rxtx_disable
Существует "бяда" с этим делом. Lwip не закрывает соединение с не переданным буфером. По тому, если встало на CTS и не задано время до "дисконнекта" после последней приемо-передаче по TCP, то кранты. Так и висит и снова не зайти. Надо что-то выдумывать, но стандартного и правильного решения нет. Т.е. такое соединение может закрыть только "аборт" всего, с опустошением всех буферов.
Это неправильно. При закрытии соединения следует прекратить прием но все остающиеся данные из буфера передачи нужно выдать в tx uart.
Поставьте 10Mbaud - всё вылетит :)
 
Последнее редактирование:

folny

New member
Hi pvvx

A few updates back not me compile code when you define the function [HASHTAG]#define[/HASHTAG] USE_ESPCONN 1 Please can modify the code to be put back to use this feature ? thanks.
 

folny

New member
Thank you for reply I would like to still use your current code you might modify these lines in order to code still works without espconn ? thanks.

void ICACHE_FLASH_ATTR tpm2net_init() {
static struct espconn tpm2conn;
static esp_udp tpm2udp;

tpm2conn.type = ESPCONN_UDP;
tpm2conn.state = ESPCONN_NONE;
tpm2conn.proto.udp = &tpm2udp;
tpm2udp.local_port=0xFFE2;
tpm2conn.reverse = NULL;
espconn_regist_recvcb(&tpm2conn, tpm2net_recv);
espconn_create(&tpm2conn);
}
 

pvvx

Активный участник сообщества
Espconn полностью исключена из базы. Отключена инициализация модуля espconn. Код espconn вырезан в libmlwip.a. Espconn не требуется - она ограничена 4-мя соединениями, пожирает память, ограничена примитивным методом работы с LwiIP и очень медленная. Единственный плюс у неё - уже включен SSL. Но SSL есть весь в исходниках и прикручивается запросто, если требуется.
 
Последнее редактирование:

folny

New member
Espconn полностью исключена из базы. Отключена инициализация модуля espconn. Код espconn вырезан в libmlwip.a. Espconn не требуется - она ограничена 4-мя соединениями, пожирает память, ограничена примитивным методом работы с LwiIP и очень медленная. Единственный плюс у неё - уже включен SSL. Но SSL есть весь в исходниках и прикручивается запросто, если требуется.
Yes it is clear to me that you have to exclude some reason, please can you advise at least how I could adapt this library in order to work with your code still unfortunately I'm not a good programmer can not do it alone.

https://github.com/sfranzyshen/esp8266_tpm2net_ws2812/blob/master/user/tpm2net.c
 

pvvx

Активный участник сообщества
Yes it is clear to me that you have to exclude some reason, please can you advise at least how I could adapt this library in order to work with your code still unfortunately I'm not a good programmer can not do it alone.

https://github.com/sfranzyshen/esp8266_tpm2net_ws2812/blob/master/user/tpm2net.c
Без espconn это всё проще и в указанном примере ошибки - там возможен вылет за пределы framebuffer.
Правильнее примерно так:
Код:
/* tpm2net.c
* Author: PV` */

#include "user_config.h"
#if USE_TMP2NET_PORT
#include "c_types.h"
#include "bios.h"
#include "user_interface.h"
#include "osapi.h"
#include "add_sdk_func.h"
#include "lwip/err.h"
#include "arch/cc.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/udp.h"
#include "hw/esp8266.h"
#include "ws2812.h"

struct sframe_head {
    uint8 id;
    uint8 blocktype;
    uint16 framelength;
    uint8 packagenum;
    uint8 numpackages;
}  __attribute__((packed));


unsigned char framebuffer[1536]; //max 512 rgb pixels
uint16_t framebuffer_len;

#define mMIN(a, b)  ((a<b)?a:b)
#define MAX_FRAME_DATA_LEN mMIN(1536, sizeof(framebuffer))

#define PIN_WS2812 0 // GPIO0

#define GPIO_OUTPUT_SET(gpio_no, bit_value) gpio_output_set(bit_value<<gpio_no, ((~bit_value)&0x01)<<gpio_no, 1<<gpio_no,0)

void ICACHE_FLASH_ATTR SEND_WS_0()
{
    MEMW();    uint32 x = GPIO_OUT;
    x |= 1 << PIN_WS2812;
    int time = 4; while(time--) { // 0.35us
        MEMW();    GPIO_OUT = x;
    }
    x &= ~(1 << PIN_WS2812);
    time = 8; while(time--) { // 0.8us
        MEMW();    GPIO_OUT = x;
    }
}

void ICACHE_FLASH_ATTR SEND_WS_1()
{
    MEMW();    uint32 x = GPIO_OUT;
    x |= 1 << PIN_WS2812;
    int time = 9; while(time--) { // 0.7us
        MEMW(); GPIO_OUT = x;
    }
    x &= ~(1 << PIN_WS2812);
    time = 5; while(time--) { // 0.6us
        MEMW();    GPIO_OUT = x;
    }
}

void ICACHE_FLASH_ATTR ws2812_strip(uint8_t * buffer, uint16_t length)
{
    int i;
    os_intr_lock();
    MEMW();    WDT_FEED = WDT_FEED_MAGIC;
    MEMW();
    __asm__ __volatile__("extw");
    // max time (0.8+0.6) * 1536 us = 2150.4 us
    for( i = 0; i < length; i++ )
    {
        uint8_t mask = 0x80;
        uint8_t byte = buffer[i];
        while (mask) {
            ( byte & mask ) ? SEND_WS_1() : SEND_WS_0();
            mask >>= 1;
          }
    }
    MEMW();
    os_intr_unlock();
}

void ICACHE_FLASH_ATTR ws2812_init()
{
//    ets_wdt_disable(); No!!!
//    WDT_CTRL &= 0x7e; // Disable WDT
    GPIO_OUT &= ~(1 << PIN_WS2812);
    GPIO_ENABLE = 1 << PIN_WS2812;
    int time = 8; while(time--) { // fill fifo
        MEMW();    GPIO_OUT &= ~(1 << PIN_WS2812);;
    }
    uint8 outbuffer[] = { 0x00, 0x00, 0x00 };
    ws2812_strip( outbuffer, sizeof(outbuffer) );
}

void ICACHE_FLASH_ATTR tpm2net_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, ip_addr_t *addr, u16_t port)
{
    struct sframe_head fhead;
    if (p == NULL)  return;
    os_printf("\nUDP recved %u bytes\n", p->tot_len);
    if(p->tot_len > sizeof(fhead)) {
        if( pbuf_copy_partial(p, &fhead, sizeof(fhead), 0) == sizeof(fhead)) {
            fhead.framelength = (fhead.framelength << 8) | (fhead.framelength >> 8);
            os_printf("Packet id = %02x, type = %02x, len = %u, pack = %u, num = %u\n", fhead.id, fhead.blocktype, fhead.framelength, fhead.packagenum, fhead.numpackages);
            if( fhead.id == 0x9C // header identifier (packet start)
                && fhead.blocktype == 0xDA // block type
                && fhead.framelength <= MAX_FRAME_DATA_LEN // check overflow
                && p->tot_len >= (fhead.framelength + sizeof(fhead) + 1) // input data len
                && pbuf_get_at(p, fhead.framelength + sizeof(fhead)) == 0x36 ) { // header end (packet stop)
                if (fhead.numpackages == 0x01) { // no frame split found
                    uint8 * fdata = (uint8 *) pvPortMalloc(fhead.framelength);
                    if(fdata != NULL) {
                        if(pbuf_copy_partial(p, fdata, fhead.framelength , sizeof(fhead)) == fhead.framelength) {
                            os_printf("ws2812 out %u bytes\n", fhead.framelength);
                            ws2812_strip(fdata, fhead.framelength); // send data to strip
                        }
                        else os_printf("Error copy\n");
                        vPortFree(fdata);
                    }
                    else os_printf("Error mem\n");
                }
                else { //frame split is found
                    if(framebuffer_len + fhead.framelength <= sizeof(framebuffer)) {
                        if(pbuf_copy_partial(p, &framebuffer[framebuffer_len], fhead.framelength , sizeof(fhead)) == fhead.framelength) {
                            framebuffer_len += fhead.framelength;
                            os_printf("ws2812 add buf %u bytes\n", fhead.framelength);
                            if (fhead.packagenum == fhead.numpackages) { // all packets found
                                os_printf("ws2812 out %u bytes\n", framebuffer_len);
                                ws2812_strip(framebuffer, framebuffer_len); // send data to strip
                                framebuffer_len = 0;
                           };
                        }
                        else os_printf("Error copy\n");
                    }
                    else os_printf("Framebuffer overflow!\n");
                };
            }
            else os_printf("Error packet\n");
        }
        else os_printf("Error copy\n");
    }
    else os_printf("Error packet\n");
    pbuf_free(p);
}

void ICACHE_FLASH_ATTR tpm2net_init(void)
{
    struct udp_pcb *pcb;
    os_printf("\nInit TMP2NET... ");
    framebuffer_len = 0;
    pcb = udp_new();
    if(pcb != NULL) {
        err_t err = udp_bind(pcb, IP_ADDR_ANY, USE_TMP2NET_PORT);
        if(err == ERR_OK) {
            udp_recv(pcb, tpm2net_recv, pcb);
            ws2812_init();
            os_printf("Ok\n");
        }
        else os_printf("Error bind\n");
    }
    else os_printf("Error mem\n");
}

#endif // USE_TMP2NET
И будет работать с любым SDK. Не проверял - проверяйте сами.
 
Последнее редактирование:

folny

New member
Без espconn это всё проще и в указанном примере ошибки - там возможен вылет за пределы framebuffer.
Правильнее примерно так:
Код:
/* tpm2net.c
* Author: PV` */

#include "user_config.h"
#include "c_types.h"
#include "bios.h"
#include "user_interface.h"
#include "osapi.h"
#include "lwip/err.h"
#include "arch/cc.h"
#include "lwip/mem.h"
#include "lwip/udp.h"

typedef struct sframe_head {
    uint8 id;
    uint8 blocktype;
    uint16 framelength;
    uint8 packagenum;
    uint8 numpackages;
}  __attribute__((packed));

#define mMIN(a, b)  ((a<b)?a:b)
#define MAX_FRAME_DATA_LEN mMIN(1536, sizeof(framebuffer))

unsigned char framebuffer[1536]; //max 512 rgb pixels
uint16_t framebuffer_len;

void ICACHE_FLASH_ATTR tpm2net_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, ip_addr_t *addr, u16_t port)
{
    struct sframe_head fhead;
    if (p == NULL)  return;
    os_printf("\nUDP recved %u bytes\n", p->tot_len);
    if(p->tot_len > sizeof(fhead)) {
        if(pbuf_copy_partial(p, &fhead, sizeof(fhead), 0) == sizeof(fhead)
                && fhead.id == 0x9C // header identifier (packet start)
                && fhead.blocktype == 0xDA // block type
                && fhead.framelength <= MAX_FRAME_DATA_LEN // check overflow
                && p->tot_len >= fhead.framelength + sizeof(fhead) // input data len
                && pbuf_get_at(p, fhead.framelength + sizeof(fhead)) == 0x36 ) { // header end (packet stop)
            if (fhead.numpackages == 0x01) { // no frame split found
                uint8 * fdata = (uint8 *) pvPortMalloc(fhead.framelength);
                if(fdata != NULL) {
                    if(pbuf_copy_partial(p, fdata, fhead.framelength , sizeof(fhead)) == fhead.framelength) {
                        ws2812_strip(fdata, fhead.framelength); // send data to strip
                    }
                    else os_printf("Error copy\n");
                    vPortFree(fdata);
                }
                else os_printf("Error mem\n");
            }
            else { //frame split is found
                if(framebuffer_len + fhead.framelength <= sizeof(framebuffer)) {
                    if(pbuf_copy_partial(p, &framebuffer[framebuffer_len], fhead.framelength , sizeof(fhead)) == fhead.framelength) {
                        framebuffer_len += fhead.framelength;
                       if (fhead.packagenum == fhead.numpackages) { // all packets found
                          ws2812_strip(framebuffer, framebuffer_len); // send data to strip
                          framebuffer_len = 0;
                       }
                    }
                    else os_printf("Error copy\n");
                }
                else os_printf("Framebuffer overflow!\n");
            }
        }
    }
    else os_printf("Error packet\n");
    pbuf_free(p);
}

void ICACHE_FLASH_ATTR tpm2net_init(void)
{
    struct udp_pcb *pcb;
    os_printf("\nInit TMP2NET\n");
    framebuffer_len = 0;
    pcb = udp_new();
    if(pcb != NULL) {
        err_t err = udp_bind(pcb, IP_ADDR_ANY, 0xFFE2);
        if(err == ERR_OK) udp_recv(pcb, tpm2net_recv, pcb);
        else os_printf("Error bind\n");
    }
    else os_printf("Error mem\n");
}
И будет работать с любым SDK. Не проверял - проверяйте сами.
Thank you for your help but the compilation will fail.

tpm2net.c:20:1: error: useless storage class specifier in empty declaration [-Werror]
} __attribute__((packed));
^
tpm2net.c: In function 'tpm2net_recv':
tpm2net.c:32:5: error: implicit declaration of function 'os_printf_plus' [-Werror=implicit-function-declaration]
os_printf("\nUDP recved %u bytes\n", p->tot_len);
^
tpm2net.c:41:17: error: implicit declaration of function 'pvPortMalloc' [-Werror=implicit-function-declaration]
uint8 * fdata = (uint8 *) pvPortMalloc(fhead.framelength);
^
tpm2net.c:44:25: error: implicit declaration of function 'ws2812_strip' [-Werror=implicit-function-declaration]
ws2812_strip(fdata, fhead.framelength); // send data to strip
^
tpm2net.c:47:21: error: implicit declaration of function 'vPortFree' [-Werror=implicit-function-declaration]
vPortFree(fdata);
^
cc1.exe: all warnings being treated as errors
../../Makefile:165: recipe for target '.output/eagle/obj/tpm2net.o' failed
mingw32-make[2]: Leaving directory 'C:/Espressif/examples/Web_Base/app/user'
mingw32-make[2]: *** [.output/eagle/obj/tpm2net.o] Error 1
../Makefile:154: recipe for target '.subdirs' failed
mingw32-make[1]: Leaving directory 'C:/Espressif/examples/Web_Base/app'
mingw32-make[1]: *** [.subdirs] Error 2
C:/Espressif/examples/Web_Base/Makefile:154: recipe for target '.subdirs' failed
mingw32-make.exe: *** [.subdirs] Error 2
 

pvvx

Активный участник сообщества
Последнее редактирование:

folny

New member
[HASHTAG]#include[/HASHTAG] "add_sdk_func.h" , [HASHTAG]#include[/HASHTAG]"ws2812.h"
Код:
#ifndef _WS2812_H
#define _WS2812_H
#include "ets_sys.h"
void ws2812_strip( uint8_t * buffer, uint16_t length ) ICACHE_FLASH_ATTR;
void ws2812_init() ICACHE_FLASH_ATTR;
#endif
New: http://esp8266.ru/forum/threads/raz...go-webservera-na-esp8266.56/page-26#post-5855
Compilation was correctly but the code does not work at ws2812 not light, output OPIO0 not any signal. :(
 

pvvx

Активный участник сообщества
@folny Web_Base_WS2812.zip
tmp2net.gif
Задержки у драйвера WS2812 сделаны на fifo шины к GPIO-ports. Это не всегда работает правильно.
 

folny

New member
@folny Web_Base_WS2812.zip
Посмотреть вложение 478
Задержки у драйвера WS2812 сделаны на fifo шины к GPIO-ports. Это не всегда работает правильно.
Hi pvvx

Great job code works perfectly :) fit the control handle up to 1024 pixels ws2812 thank you very much. Will you help me please even modify the code for protocol ArtNet ? I modified the code for a 4 Universe and worked well but I would also like to use it to your code.

here is the original code: https://github.com/sfranzyshen/EspLightNode/blob/master/user/input_protocols/artnet.c

my code for a 4 Universe

[HASHTAG]#include[/HASHTAG] "ets_sys.h"
[HASHTAG]#include[/HASHTAG] "osapi.h"
[HASHTAG]#include[/HASHTAG] "os_type.h"
[HASHTAG]#include[/HASHTAG] "user_interface.h"
[HASHTAG]#include[/HASHTAG] "espconn.h"
[HASHTAG]#include[/HASHTAG] "ws2812.h"

[HASHTAG]#define[/HASHTAG] ARTNET_Port 0x1936

uint8_t artnet_enabled = 1;
char artnet_shortname[18] = "Pixel Controller";
char artnet_longname[64] = "ArtNet LED Pixel Controller";
uint8_t artnet_net = 0;
uint8_t artnet_subnet= 0;
uint8_t artnet_universe1= 0;
uint8_t artnet_universe2= 1;
uint8_t artnet_universe3= 2;
uint8_t artnet_universe4= 3;

static void ICACHE_FLASH_ATTR artnet_recv_opoutput(unsigned char *packet, unsigned short packetlen)
{
uint8_t SubUni0 = packet[4];
uint8_t Net0 = packet[5];
if (Net0 == artnet_net && (SubUni0 >> 4) == artnet_subnet && (SubUni0 & 0xF) == artnet_universe1)
{
uint16_t Length = ((uint16_t)packet[6] << 8) | packet[7];
if (packetlen >= 8 + Length) {
uint8_t *data = &packet[8];
ws2812_strip1(data,Length);
}

}
uint8_t SubUni1 = packet[4];
uint8_t Net1 = packet[5];
if (Net1 == artnet_net && (SubUni1 >> 4) == artnet_subnet && (SubUni1 & 0xF) == artnet_universe2)
{
uint16_t Length = ((uint16_t)packet[6] << 8) | packet[7];
if (packetlen >= 8 + Length) {
uint8_t *data = &packet[8];
ws2812_strip2(data,Length);
}

}
uint8_t SubUni2 = packet[4];
uint8_t Net2 = packet[5];
if (Net2 == artnet_net && (SubUni2 >> 4) == artnet_subnet && (SubUni2 & 0xF) == artnet_universe3)
{
uint16_t Length = ((uint16_t)packet[6] << 8) | packet[7];
if (packetlen >= 8 + Length) {
uint8_t *data = &packet[8];
ws2812_strip3(data,Length);
}

}
uint8_t SubUni3 = packet[4];
uint8_t Net3 = packet[5];
if (Net3 == artnet_net && (SubUni3 >> 4) == artnet_subnet && (SubUni3 & 0xF) == artnet_universe4)
{
uint16_t Length = ((uint16_t)packet[6] << 8) | packet[7];
if (packetlen >= 8 + Length) {
uint8_t *data = &packet[8];
ws2812_strip4(data,Length);
}
}
}

[HASHTAG]#define[/HASHTAG] ARTNET_OpPoll 0x2000
[HASHTAG]#define[/HASHTAG] ARTNET_OpPollReply 0x2100
[HASHTAG]#define[/HASHTAG] ARTNET_OpOutput 0x5000

[HASHTAG]#define[/HASHTAG] TTM_REPLY_MASK 0

struct ArtNetPollReply {
uint8_t ID[8];
uint8_t OpCode[2]; //low-first
uint8_t IP[4];
uint8_t Port[2]; //Low-first
uint8_t VersInfo[2]; //High-first
uint8_t NetSwitch;
uint8_t SubSwitch;
uint8_t Oem[2]; //High-first
uint8_t Ubea_Version;
uint8_t Status1;
uint8_t EstaMan[2]; //Low-first
uint8_t ShortName[18];
uint8_t LongName[64];
uint8_t NodeReport[64];
uint8_t NumPorts[2]; //High-first
uint8_t PortTypes[4];
uint8_t GoodInput[4];
uint8_t GoodOutput[4];
uint8_t SwIn[4];
uint8_t SwOut[4];
uint8_t SwVideo;
uint8_t SwMacro;
uint8_t SwRemote;
uint8_t Spare[3];
uint8_t Style;
uint8_t MAC[6]; //High-byte first
uint8_t BindIp[4];
uint8_t BindIndex;
uint8_t Status2;
uint8_t Filler[26];
};

[HASHTAG]#define[/HASHTAG] ARTNET_SET_SHORT_LOFIRST(target,value) (target)[0] = (value) & 0xFF; (target)[1] = (value) >> 8;
[HASHTAG]#define[/HASHTAG] ARTNET_SET_SHORT_HIFIRST(target,value) (target)[0] = (value) >> 8; (target)[1] = (value) & 0xFF;

static void ICACHE_FLASH_ATTR artnet_recv_oppoll(struct espconn *conn, unsigned char *packet, unsigned short packetlen) {
if (packetlen >= 3) {
uint16_t ProtVer=((uint16_t)packet[0] << 8) | packet[1];
uint8_t TalkToMe=packet[2];
//TODO
if (TalkToMe & TTM_REPLY_MASK) {

} else {

}
struct ip_info ipconfig;
char hwaddr[6];

wifi_get_ip_info(STATION_IF, &ipconfig);
wifi_get_macaddr(STATION_IF, hwaddr);

struct ArtNetPollReply response;
memset(&response, 0, sizeof(struct ArtNetPollReply));
strcpy((char*)response.ID,"Art-Net");
ARTNET_SET_SHORT_LOFIRST(response.OpCode, ARTNET_OpPollReply);
memcpy(response.IP,&ipconfig.ip.addr,4);
ARTNET_SET_SHORT_LOFIRST(response.Port, ARTNET_Port);
ARTNET_SET_SHORT_HIFIRST(response.VersInfo, 0);
response.NetSwitch = artnet_net;
response.SubSwitch = artnet_subnet;
ARTNET_SET_SHORT_HIFIRST(response.Oem,0);
response.Ubea_Version = 0;
response.Status1 = 0;
ARTNET_SET_SHORT_LOFIRST(response.EstaMan,0);
memcpy(response.ShortName,artnet_shortname, sizeof(response.ShortName));
memcpy(response.LongName,artnet_longname, sizeof(response.LongName));
strcpy(response.NodeReport,"");
ARTNET_SET_SHORT_HIFIRST(response.NumPorts,4);
response.PortTypes[0]=0x80;
response.PortTypes[1]=0x80;
response.PortTypes[2]=0x80;
response.PortTypes[3]=0x80;
//Not set is set to 0
//response.GoodInput = 0;
//response.GoodOutput = 0;
response.SwOut[0] = artnet_universe1;
response.SwOut[1] = artnet_universe2;
response.SwOut[2] = artnet_universe3;
response.SwOut[3] = artnet_universe4;
//response.SwVideo
//response.SwMacro
//response.SwRemote
//response.Style
memcpy(response.MAC,hwaddr,6);
//response.BindIp
//response.BindIndex
//response.Status2
espconn_sent(conn,(char*)&response,sizeof(struct ArtNetPollReply));
} else {
//Invalid length
}
}

static void ICACHE_FLASH_ATTR artnet_recv(void *arg, char *pusrdata, unsigned short length) {
unsigned char *data =(unsigned char *)pusrdata;
if (data && length>=10) {
if (data[0]=='A' && data[1]=='r' && data[2]=='t' && data[3]=='-' && data[4]=='N' && data[5]=='e' && data[6]=='t' && data[7]==0) {
uint16_t OpCode=data[8] | ((uint16_t)data[9] << 8);
switch (OpCode) {
case ARTNET_OpOutput:
return artnet_recv_opoutput(&data[10],length-10);
case ARTNET_OpPoll:
return artnet_recv_oppoll((struct espconn *)arg,&data[10],length-10);
}
} else {
//Header invalid
}
} else {
//Package too small.
}

}

void artnet_init() {
static struct espconn artnetconn;
static esp_udp artnetudp;
artnetconn.type = ESPCONN_UDP;
artnetconn.state = ESPCONN_NONE;
artnetconn.proto.udp = &artnetudp;
artnetudp.local_port=ARTNET_Port;
artnetconn.reverse = NULL;
if (artnet_enabled) {
espconn_regist_recvcb(&artnetconn, artnet_recv);
espconn_create(&artnetconn);

}
}
 

porex

New member
Нашел непонятный момент в коде.
Файл web_init_vars.c, ниже кусок с 281 строки, версии 0.2.8
Код:
os_memset(wificonfig.st.config.ssid, 0, sizeof(wificonfig.st.config.ssid));
int len = os_strlen(pvar);
if(len > sizeof(wificonfig.st.config.ssid)) {
    len = sizeof(wificonfig.st.config.ssid);
}
else os_memset(&wificonfig.st.config.ssid[len], 0, sizeof(wificonfig.st.config.ssid) - len);
os_memcpy(wificonfig.st.config.ssid, pvar, len);
Для чего обнулять неиспользуемую часть массива с именем wi-fi (строка 6), если в первой строке уже обнулили весь массив? Видимо строка 6 лишняя? Такой же кусок кода и при сохранении имени AP.
Не подумайте, что придираюсь;)
 

pvvx

Активный участник сообщества
Нашел непонятный момент в коде.
...
Для чего обнулять неиспользуемую часть массива с именем wi-fi (строка 6), если в первой строке уже обнулили весь массив? Видимо строка 6 лишняя? Такой же кусок кода и при сохранении имени AP.
Не подумайте, что придираюсь;)
А вы думаете я помню, зачем. :) По мере роста SDK ошибок в ней было масса. Частично что-то переписывалось, менялось. А это осталось так :)
Для переменных web всё время хотелось изменить парсер, но так дело и не дошло. Ничего красивого пока не выдумал, но это вечное желание заменить дает эффект того, что проверять что там накоплено неохота...
 

pvvx

Активный участник сообщества
@sharikov - что вышло c "огрызком" "ни к селу не городу" RFC 2217? Не расскажите, как у вас работает RFC 2217, когда окно приема WIN TCP закрыто по причине заполнения буфера? :)
По моему RFC 2217 может использоваться только в случае блочной передачи, когда указано кол-во передаваемых байт и ответ что это пока не лезет в буфер, чего нету в RFC 2217. В Winsocket это есть и только туда можно встроить RFC 2217. Ведь требуется два канала/потока - один для передачи данных, а второй для управляющих сигналов и порт никогда не должен быть закрыт на прием (не должно использоваться ограничение приема по протоколу TCP, а требуется протокол над ним). Из-за этого все реализации удаленного COM порта на RFC 2217 и не работают :) И как итог - это уже специальный протокол, очень далекий от того, что сделано в текущей TCP2UART и называться он должен совсем по другому, т.к. такой протокол использует TCP только как средство доставки команд протокола выше уровнем...
 
Последнее редактирование:
Сверху Снизу