Trying to communicate with the ENC1-V3 encoder

EN1-V3 encoder is a video device . I have the following information :

My code is the following - generated with help of Copilot (IA) . It seems work up to pass the some part of digest authorization. But could not go to subsequent requests:

#include <SPI.h>
#include <Ethernet_W5500.h> // Incluindo a biblioteca apropriada para o W5500
#include <MD5.h> // Incluindo a biblioteca ArduinoMD5

// Defina as informações do servidor
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // Endereço MAC do Arduino
IPAddress ip(192, 168, 1, 117); // Endereço IP do Arduino
IPAddress gateway(192, 168, 1, 1); // Gateway padrão
IPAddress subnet(255, 255, 255, 0); // Máscara de sub-rede
IPAddress server(192, 168, 1, 217); // Endereço IP do servidor

// Inicializa o cliente Ethernet
EthernetClient client;

// Credenciais de login
const char* username = "admin";
const char* password = "admin";
const char* realm = "lph_http"; // Defina o realm apropriado
String nonce; // Variável para armazenar o nonce
String ha1Str; // Armazena o HA1
String ha2Str; // Armazena o HA2
String responseStr; // Armazena a resposta final

void setup() {
    Serial.begin(115200);
    Serial.println(F("executando teste linkpi"));
    Ethernet.begin(mac, ip, gateway, subnet); // Configura o Ethernet
    delay(1000);
    
    if (client.connect(server, 80)) {
        Serial.println(F("Conectado ao servidor."));
        login();
    } else {
        Serial.println(F("Falha ao conectar."));
    }
}

void loop() {
    // Aqui você pode implementar o que deseja fazer após a autenticação
}

// Função para gerenciar o login
void login() {
    Serial.println(F("Requisitando autenticação digest 1"));
    client.println(F("POST /link/user/lph_login HTTP/1.1"));
    client.println(F("Host: 192.168.1.217"));
    client.println(F("Content-Type: application/json"));
    client.println(F("Connection: keep-alive"));
    client.println(F("Content-Length: 0"));
    client.println();

    while (client.connected() || client.available()) {
        if (client.available()) {
            String line = client.readStringUntil('\n');
            Serial.println(line);
            if (line.startsWith("WWW-Authenticate:")) {
                nonce = extractNonce(line);
                Serial.print(F("Nonce: "));
                Serial.println(nonce);
                generateHashValues();
                sendAuthenticatedRequest();
                break;
            }
        }
    }
}

void generateHashValues() {
    // Cria os hashes MD5 necessários
    String ha1Input = String(username) + ":" + realm + ":" + password;
    unsigned char* ha1Hash = MD5::make_hash(ha1Input.c_str()); 
    ha1Str = MD5::make_digest(ha1Hash, 16);

    String ha2Input = "GET:/link/encoder/get_channels";
    unsigned char* ha2Hash = MD5::make_hash(ha2Input.c_str());
    ha2Str = MD5::make_digest(ha2Hash, 16);

    // Gerando a resposta final
    String responseInput = String(ha1Str) + ":" + nonce + ":" + ha2Str;
    unsigned char* responseHash = MD5::make_hash(responseInput.c_str());
    responseStr = MD5::make_digest(responseHash, 16);

    // Imprimindo para depuração
    Serial.print(F("HA1: "));
    Serial.println(ha1Str);
    Serial.print(F("HA2: "));
    Serial.println(ha2Str);
    Serial.print(F("Response: "));
    Serial.println(responseStr);

    // Liberar memória alocada
    free(ha1Hash);
    free(ha2Hash);
    free(responseHash);
}

void sendAuthenticatedRequest() {
    // Enviar solicitação com autenticação
    Serial.println(F("Requisitando autenticação digest 2"));
    String authHeader = "Digest username=\"" + String(username) + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", uri=\"/link/encoder/get_channels\", response=\"" + responseStr + "\"";
    Serial.print(F("Authorization Header: "));
    Serial.println(authHeader);

    client.println(F("GET /link/encoder/get_channels HTTP/1.1"));
    client.println(F("Host: 192.168.1.217"));
    client.println("Authorization: " + authHeader);
    client.println(F("Connection: close"));
    client.println();

    // Verificando a resposta do servidor
    bool authenticated = false;
    while (client.connected() || client.available()) {
        if (client.available()) {
            String line = client.readStringUntil('\n');
            Serial.println(line);
            // Verifique o status da resposta para sucesso ou falha na autenticação
            if (line.startsWith("HTTP/1.1 200 OK")) {
                authenticated = true; // Sucesso na autenticação
            } else if (line.startsWith("HTTP/1.1 401 Unauthorized")) {
                authenticated = false; // Falha na autenticação
                Serial.println(F("Autenticação falhou (401)."));
                break; // Saia do loop, pois a autenticação falhou
            }
        }
    }

    if (authenticated) {
        Serial.println(F("Autenticação bem-sucedida."));
        requestSystemState(); // Chama a função para obter o estado do sistema
    }
}

// Função para obter informações do estado do sistema
void requestSystemState() {
    Serial.println(F("Requisitando System State"));
    // Montar a solicitação GET para obter o estado do sistema
    String authHeader = "Digest username=\"" + String(username) + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", uri=\"/link/system/get_sys_state\", response=\"" + responseStr + "\"";
    Serial.print(F("Authorization Header: "));
    Serial.println(authHeader);

    client.println(F("GET /link/system/get_sys_state HTTP/1.1"));
    client.println(F("Host: 192.168.1.217"));
    client.println("Authorization: " + authHeader);
    client.println(F("Connection: close"));
    client.println();

    // Verificando a resposta do servidor
    String response = "";
    while (client.connected() || client.available()) {
        if (client.available()) {
            String line = client.readStringUntil('\n');
            Serial.println(line);
            response += line; // Acumula a resposta
        }
    }

    // Exibir a resposta final
    Serial.println(F("Resposta do estado do sistema:"));
    Serial.println(response);
}

// Função para extrair o nonce
String extractNonce(String header) {
    int start = header.indexOf("nonce=\"") + 7;
    int end = header.indexOf("\"", start);
    return header.substring(start, end);
}

It is my first time to program to communicate to network and I do not understand well the HTTP protocol then I would need a help from friends.

Did you ask it to fix its mistakes?

I did not see this until after posting... you should learn to program before using "AI" or you will never know if the generated code is valid or GIGO.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.