Skip to content

L3_FSMmain.cpp 수정 #7

@woojin-devv

Description

@woojin-devv
#include "L3_FSMevent.h"
#include "L3_msg.h"
#include "L3_timer.h"
#include "L3_LLinterface.h"
#include "protocol_parameters.h"
#include "mbed.h"
#include "L3_Quiz.h"
#include "L3_2min_timer.h"
#include "L3_state.h"

L3_State l3_state = IDLE;
static L3_State prev_state = IDLE;

static uint8_t originalWord[1030];
static uint8_t wordLen = 0;
static uint8_t sdu[1030];

static Serial pc(USBTX, USBRX);
static uint8_t myDestId;

void L3service_processInputWord(void)
{
    char c = pc.getc();
    if (!L3_event_checkEventFlag(L3_event_dataToSend)) {
        if (c == '\n' || c == '\r') {
            originalWord[wordLen++] = '\0';
            L3_event_setEventFlag(L3_event_dataToSend);
            debug_if(DBGMSG_L3, "word is ready! ::: %s\n", originalWord);
        } else {
            originalWord[wordLen++] = c;
            if (wordLen >= L3_MAXDATASIZE - 1) {
                originalWord[wordLen++] = '\0';
                L3_event_setEventFlag(L3_event_dataToSend);
                pc.printf("\n max reached! word forced to be ready :::: %s\n", originalWord);
            }
        }
    }
}

void L3_initFSM(uint8_t destId)
{
    myDestId = destId;
    pc.attach(&L3service_processInputWord, Serial::RxIrq);
    pc.printf("Give a word to send : ");
}

void L3_FSMrun(void)
{
    if (prev_state != l3_state) {
        debug_if(DBGMSG_L3, "[L3] State transition from %s to %s\n",
                 L3_stateToStr(prev_state), L3_stateToStr(l3_state));
        prev_state = l3_state;
    }

    switch (l3_state) {
        case WAIT_ANSWER: {
            pc.printf(":: role: HOST\n");
            L3_quiz_showMenuToHost(pc);
            if (!L3_quiz_select(pc)) {
                pc.printf("[ERROR] Quiz selection failed. Terminating.\n");
                l3_state = TERMINATE;
                break;
            }
            // 퀴즈 전송
            char quizIndexMsg[8];
            sprintf(quizIndexMsg, "quiz%d", selected_quiz_index);
            L3_LLI_dataReqFunc((uint8_t*)quizIndexMsg, strlen(quizIndexMsg) + 1, myDestId);
            pc.printf("[L3] Quiz index %d sent to user.\n", selected_quiz_index);
            l3_state = CHAT_READY;
            break;
        }
        case WAIT_QUIZ: {
            pc.printf(":: role: USER\n");
            L3_quiz_showSelectedToUser(pc);

            const int maxAttempts = 3;
            Timer quizTimer;
            quizTimer.start();

            for (int attempt = 1; attempt <= maxAttempts; attempt++) {
                float elapsed = quizTimer.read();
                float remaining = 120.0f - elapsed;

                if (remaining <= 0.0f) {
                    pc.printf("[TIMEOUT] 2 minutes are over. Terminating.\n");
                    l3_state = TERMINATE;
                    break;
                }

                pc.printf("\n[Attempt %d/%d] Time left: %d seconds\n", attempt, maxAttempts, (int)remaining);
                pc.printf("Answer: ");

                char answerBuffer[MAX_PASSWORD_LEN] = {0};
                bool gotInput = getInputWithinTime(pc, answerBuffer, sizeof(answerBuffer), remaining);

                if (!gotInput) {
                    pc.printf("Incorrect answer. (No input detected)\n");
                    continue;
                }

                if (L3_quiz_isAnswerCorrect(answerBuffer)) {
                    pc.printf("Correct! Moving to CHAT_READY state.\n");
                    l3_state = CHAT_READY;
                    break;
                } else {
                    pc.printf("Incorrect answer.\n");
                }

                if (attempt == maxAttempts) {
                    pc.printf("You've used all attempts. Terminating session.\n");
                    l3_state = TERMINATE;
                }
            }
            break;
        }
        case IDLE: {
            if (L3_event_checkEventFlag(L3_event_msgRcvd)) {
                uint8_t* dataPtr = L3_LLI_getMsgPtr();
                uint8_t size = L3_LLI_getSize();

                char printBuf[1030] = {0};
                memcpy(printBuf, dataPtr, size);
                printBuf[size] = '\0';

                debug("\n -------------------------------------------------\n");
                debug("RCVD MSG : %s (length:%i)\n", printBuf, size);
                debug(" -------------------------------------------------\n");

                if (strncmp((char*)dataPtr, "quiz", 4) == 0) {
                    selected_quiz_index = dataPtr[4] - '0';
                    if (selected_quiz_index >= 0 && selected_quiz_index < QUIZ_TOTAL_COUNT) {
                        strncpy(selected_answer, quiz_answers[selected_quiz_index], MAX_PASSWORD_LEN);
                        pc.printf("[Quiz Received] Index: %d\n", selected_quiz_index);
                        l3_state = WAIT_QUIZ;
                    } else {
                        pc.printf("[Error] Invalid quiz index received.\n");
                        l3_state = TERMINATE;
                    }
                    L3_event_clearEventFlag(L3_event_msgRcvd);
                    return;
                }

                if (strncmp((char*)dataPtr, "quit", 4) == 0) {
                    pc.printf(":: 'quit' received from peer. Terminating chat...\n");
                    l3_state = TERMINATE;
                    L3_event_clearEventFlag(L3_event_msgRcvd);
                    return;
                }
                pc.printf("[Peer] %s\n", printBuf);
                pc.printf("Give a word to send : ");

                L3_event_clearEventFlag(L3_event_msgRcvd);
            } else if (L3_event_checkEventFlag(L3_event_dataToSend)) {
                if (strcmp((char*)originalWord, "quit") == 0) {
                    l3_state = TERMINATE;
                    pc.printf(":: Chat terminated by user input.\n");
                    wordLen = 0;
                    memset(originalWord, 0, sizeof(originalWord));
                    L3_event_clearEventFlag(L3_event_dataToSend);
                    break;
                }

                strcpy((char*)sdu, (char*)originalWord);
                debug("[L3] msg length : %i\n", wordLen);
                L3_LLI_dataReqFunc(sdu, wordLen, myDestId);

                pc.printf("[You] %s\n", sdu);

                wordLen = 0;
                pc.printf("Give a word to send : ");
                L3_event_clearEventFlag(L3_event_dataToSend);
            }
            break;
        }
        case CHAT_READY: {
            pc.printf(":: [L3] Entering CHAT_READY...\n");
            l3_state = IDLE;
            break;
        }
        case TERMINATE: {
            pc.printf(":: [L3] Entering TERMINATE. Chat session ended.\n");
            L3_event_clearAllEventFlag();
            pc.attach(NULL);
            while (1);
            break;
        }
        default:
            break;
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions