わいずふぁくとりいがプログラムの話題をウィキします。

(ファイルトランスポータプロトコル - 4)

 デバイス(ESP32)側(EspFileTransporter)の実装を掲載します。

FTReceive.ino

// FTReceive
//  2020.10.18 - 2020.11.03 ysfactory

using namespace std;

static const int FRAME_BUFFER_SIZE = 256;
static const int TOKEN_MAX = 8;

static unsigned char __frame_buffer[FRAME_BUFFER_SIZE];
static unsigned char* __frame_p = &__frame_buffer[0];
static unsigned char const* __frame_bottom = &__frame_buffer[FRAME_BUFFER_SIZE];

static char* __token[TOKEN_MAX];
static int __nof_token = 0;

static enum F_STATE
{
    F_IDLE,
    F_FRAME,
}
__f_state = F_IDLE;

static WiFiClient* __current_client = NULL;

static bool put_buffer(int c)
{
    if( (__frame_p + 2) >= __frame_bottom )
    {
        return false;
    }
    *__frame_p++ = c;
    return true;
}

static void on_receive_frame(ClientPath& client)
{
    char* s = (char*)&__frame_buffer[0];
    int nof = 0;
    char ** t = &__token[0];
    bool start = true;

    for( ; *s != '\0'; ++s )
    {
        if( start )
        {
            if( nof >= TOKEN_MAX )
            {
                break;
            }
            *t++ = s;
            ++nof;
            start = false;
        }
        if( *s == ',' )
        {
            *s = '\0';
            start = true;            
        }
    }

    //{
    //    //dump
    //    int i;
    //    for(i=0; i<nof; ++i)
    //    {
    //        Serial.println(__token[i]);
    //    }
    //}

    switch( *__token[0] )
    {
    case '#':
        OnReceivedCommand(&__frame_buffer[0], &__token[0], nof, client);
        break;
    case '$':
        OnReceivedResponse(&__frame_buffer[0], &__token[0], nof, client);
        break;
    }
}

void FTReceive_OnReceiveByte(int c, ClientPath& client)
{
    if( c == '#' || c == '$' )
    {
        __frame_p = &__frame_buffer[0];
        //put_buffer(c);
        __f_state = F_FRAME;
    }

    if( __f_state == F_FRAME )
    {
        if( c == '\r' )
        {
            *__frame_p = '\0';
            //Serial.println((char*)__frame_buffer);
            on_receive_frame(client);
            __f_state = F_IDLE;
        }
        else
        {
            put_buffer(c);
        }
    }
    //Serial.print(c);
}

FTSender.ino

// FTSender
//  2020.10.30 - 2020.12.05 ysfactory

void FTSender_SendResponse(const char* command, const char* status, ClientPath& client)
{
    client.client.printf("%s,%s\r", command, status);
}

void FTSender_SendCommand(const char* command, const char* arg_0, ClientPath& client)
{
    client.client.printf("%s,%s\r", command, arg_0);
}

void FTSender_SendBinary(const unsigned char* data, unsigned size, ClientPath& client)
{
    client.client.printf("%%%u;", size);
    client.client.write(data, size);
}

FTCommand.ino

// FTCommand
//  2020.10.24 - 2020.10.31 ysfactory

typedef void (*ON_COMMAND)(unsigned char* frame, char** tokens, int nof_token, ClientPath& client);

typedef struct
{
    const char* cmd;
    ON_COMMAND  func;
}
TABLE;
static TABLE __table[] =
{
    "#path", OnReceivedPath,
    NULL,   NULL
    
};

static void OnReceivedPath(unsigned char* frame, char** tokens, int nof_token, ClientPath& client)
{
    if( nof_token != 2 )
    {
        FTSender_SendResponse("$path", "ERROR", client);
        return;
    }
    client.path = *(tokens+1);
    //Serial.print("OnReceivedPath() : ");
    //Serial.println(client.path.c_str());
    FTSender_SendResponse("$path", "OK", client);
}

static void OnReceivedCommand(unsigned char* frame, char** tokens, int nof_token, ClientPath& client)
{
    //Serial.println("OnReceivedCommand()");
    if( nof_token <= 0 )
    {
        return;
    }
    TABLE* t = &__table[0];
    for( ; t->cmd != NULL; ++t, ++tokens )
    {
        //Serial.println(*tokens);
        //Serial.println(t->cmd);
        if( strcmp(*tokens, t->cmd) == 0 )
        {
            (t->func)(frame, tokens, nof_token, client);
        }
    }
}

Timer.h

// Timer.h
//  2020.11.03 - 2020.11.06 ysfactory

#pragma once

enum
{
    TIMER_DEMO,
    TIMER_SESSION,
    NOF_TIMER
};
extern volatile int Timer100ms[NOF_TIMER];

Timer.h

// Timer
//  2020.11.03 - 2020.11.03 ysfactory

static const unsigned TIMER_CYCLE = 100; //ms
static unsigned long timer_last;

volatile int Timer100ms[NOF_TIMER];

static unsigned elapse(unsigned long now, unsigned long last)
{
    if( last > now )
    {
        return ULONG_MAX - timer_last + now + 1;    
    }
    else
    {
        return now - timer_last;
    }
}

static void c100ms_timer(void)
{
    volatile int* timer = &Timer100ms[0];
    for(int i=0; i<NOF_TIMER; ++i, ++timer)
    {
        if( *timer > 0 )
        {
            --(*timer);
        }
    }
}

void timer_setup(void)
{
    timer_last = millis();
}

void timer_loop(void)
{
    unsigned long now;
    now = millis();
    for( ; elapse(now, timer_last) >= TIMER_CYCLE; timer_last += TIMER_CYCLE )
    {
        c100ms_timer();
    }
}

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu

管理人/副管理人のみ編集できます