#include "broadcast.h"
#include "utils.h"
#include <QJsonDocument>

Broadcast::Broadcast(const int port, QObject *parent)
    : QObject{parent}
{
    init(port);
}
Broadcast::~Broadcast()
{
    close(sockfd);
}

int Broadcast::write(const QJsonObject &json)
{
    QJsonDocument doc(json);
    QByteArray byteArray = doc.toJson(QJsonDocument::Compact);
    return sendto(sockfd, byteArray.data(), byteArray.size(), 0, (struct sockaddr *)&broadcast_addr, sizeof(broadcast_addr));
}

bool Broadcast::init(const int port)
{
    // 1. 创建 UDP 套接字
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    // 2. 设置广播权限
    if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast_enable, sizeof(broadcast_enable)) < 0) {
        perror("setsockopt(SO_BROADCAST) failed");
        close(sockfd);
        exit(EXIT_FAILURE);
    }

    char *ip = NULL;
    char *mask = NULL;
    bool result = Utils::ipv4("eth0", &ip, &mask);
    if(!result) {
        close(sockfd);
        exit(EXIT_FAILURE);
    }

    QString addr = Utils::broadcast(ip, mask);
    free(ip);
    free(mask);

    // 3. 配置广播地址
    memset(&broadcast_addr, 0, sizeof(broadcast_addr));
    broadcast_addr.sin_family = AF_INET;
    broadcast_addr.sin_port = htons(port);
    broadcast_addr.sin_addr.s_addr = inet_addr(addr.toUtf8().data());  // 广播地址

    return true;
}