• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе 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 только как средство доставки команд протокола выше уровнем...
 
Последнее редактирование:
Сверху Снизу