JZsdk_network.c 9.0 KB
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <termios.h>

#include "BaseConfig.h"
#include "version_choose.h"

#include "JZsdkLib.h"
#include "./JZsdk_network.h"

#include "../Hal_Recv/HalRecv.h"

#define LINUX_CMD_STR_MAX_SIZE (128)
#define LINUX_NETWORK_DEV           "eth0"

#define UDP_SERVER_PORT (23003)
#define TCP_SERVER_PORT (23004)
#define MAX_LISTEN_NUM (5)

#define MAX_SEND_FRAME_LENTH (60000)

#define JZSDK_UTIL_MIN(a, b)                                 (((a) < (b)) ? (a) : (b))

typedef struct T_JZsdk_network_Info
{
    //udp套接字
    int udp_socket;

    //udp服务器地址
    struct sockaddr_in udp_server_addr;

    //udp端口
    int udp_port;

    //tcp套接字
    int tcp_socket;

    //tcp服务器地址
    struct sockaddr_in tcp_server_addr;

    //tcp端口
    int tcp_port;
}T_JZsdk_network_Info;

T_JZsdk_network_Info g_JZsdk_network_Info;


static int NetworkMode = JZ_FLAGCODE_OFF; //网络模式

static T_JZsdkReturnCode JZsdk_NetWork_UdpInit()
{
    //创建UDP socket 套接字
    g_JZsdk_network_Info.udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
    if (g_JZsdk_network_Info.udp_socket == -1) {
        JZSDK_LOG_ERROR("网口套接字注册失败");
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }

    //配置udp服务器地址
    memset(&g_JZsdk_network_Info.udp_server_addr, 0, sizeof(g_JZsdk_network_Info.udp_server_addr));
    g_JZsdk_network_Info.udp_server_addr.sin_family = AF_INET;
    g_JZsdk_network_Info.udp_server_addr.sin_port = htons(g_JZsdk_network_Info.udp_port);
    if(inet_aton(NET_WORK_TARGET_IPADDR, &g_JZsdk_network_Info.udp_server_addr.sin_addr) == 0)
    {
        JZSDK_LOG_ERROR("udp服务器配置失败");
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }
}

static T_JZsdkReturnCode handle_client(int client_socket, int port)
{
    char buffer[4096] = {0};  // 初始化接收缓冲区
    ssize_t bytes_read;

    // 读取客户端发送的数据
    bytes_read = read(client_socket, buffer, 4096 - 1);
    if (bytes_read > 0) 
    {
        //printf("%s\n", buffer);

        // 检查是否是 OPTIONS 请求
        if (strstr(buffer, "OPTIONS / HTTP/1.1") != NULL) {
            // 返回允许跨域的响应头
            const char *options_response = 
                "HTTP/1.1 200 OK\r\n"
                "Access-Control-Allow-Origin: *\r\n"
                "Access-Control-Allow-Methods: POST, OPTIONS\r\n"
                "Access-Control-Allow-Headers: Content-Type\r\n"
                "Content-Length: 0\r\n"
                "\r\n";
            write(client_socket, options_response, strlen(options_response));
            close(client_socket);
            return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
        }

        // 解析 HTTP 请求头中的 Content-Length
        char *content_length = strstr(buffer, "Content-Length: ");
        if (content_length) {
            int len = atoi(content_length + 16);  // 跳过 "Content-Length: " 的16个字符
            unsigned char *body = strstr(buffer, "\r\n\r\n") + 4;  // 定位消息体起始位置
            //JZSDK_LOG_INFO("[Port %d] Received: %d%s\n", port, len, body);  // 打印消息体内容

            HalRecv_type1_PreliminaryScreeningOfData(body, len, NET_DEV_1);
        }
    }
    
    // 发送固定 HTTP 响应
    const char *response = 
        "HTTP/1.1 200 OK\r\n"
        "Access-Control-Allow-Origin: *\r\n"
        "Content-Length: 19\r\n"
        "\r\n"
        "Data received successfully";
    write(client_socket, response, strlen(response));
    close(client_socket);  // 关闭客户端连接

    return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

static void *JZsdk_Tcp_RecvThread(void *arg)
{
    while (1)
    {
        struct sockaddr_in client_addr;
        socklen_t client_addr_len = sizeof(client_addr);
        int client_socket = accept(g_JZsdk_network_Info.tcp_socket, (struct sockaddr *)&client_addr, &client_addr_len);
        if(client_socket == -1)
        {
            JZSDK_LOG_ERROR("tcp服务器接收失败");
            continue;
        }

        handle_client(client_socket, g_JZsdk_network_Info.tcp_port);  // 处理客户端请求
    }
}

static T_JZsdkReturnCode JZsdk_NetWork_TcpInit()
{
    T_JZsdkOsalHandler *osal_handler = JZsdk_Platform_GetOsalHandler();
    if(osal_handler == NULL)
    {
        JZSDK_LOG_ERROR("osal_handler is NULL");
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }

    //创建tcp socket套接字
    g_JZsdk_network_Info.tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (g_JZsdk_network_Info.tcp_socket == -1) 
    {
        JZSDK_LOG_ERROR("网口套接字注册失败");
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }
    
    //配置tcp服务器
    memset(&g_JZsdk_network_Info.tcp_server_addr, 0, sizeof(g_JZsdk_network_Info.tcp_server_addr));
    g_JZsdk_network_Info.tcp_server_addr.sin_family = AF_INET;
    g_JZsdk_network_Info.tcp_server_addr.sin_port = htons(g_JZsdk_network_Info.tcp_port);
    g_JZsdk_network_Info.tcp_server_addr.sin_addr.s_addr = inet_addr("192.168.5.3");

    //把tcp套接字绑定到指定地址
    if(bind(g_JZsdk_network_Info.tcp_socket, (struct sockaddr *)&g_JZsdk_network_Info.tcp_server_addr, sizeof(g_JZsdk_network_Info.tcp_server_addr)) == -1)
    {
        JZSDK_LOG_ERROR("tcp服务器配置失败");
        close(g_JZsdk_network_Info.tcp_socket);
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }

    //进入监听状态
    if(listen(g_JZsdk_network_Info.tcp_socket, MAX_LISTEN_NUM) == -1)
    {
        JZSDK_LOG_ERROR("tcp服务器监听失败");
        close(g_JZsdk_network_Info.tcp_socket);
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }

    
    T_JZTaskHandle g_tcp_server_task = NULL;

    //创建监听线程
    osal_handler->TaskCreate("tcp_server", JZsdk_Tcp_RecvThread, 8192, NULL, &g_tcp_server_task);

    return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}


T_JZsdkReturnCode JZsdk_NetWork_Init()
{
    T_JZsdkReturnCode ret;
    char cmdStr[LINUX_CMD_STR_MAX_SIZE];

    if (NET_WORK_IPADDR == NULL || NET_WORK_NETMASK == NULL) 
    {
        JZSDK_LOG_ERROR("无网络参数配置");
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }

    g_JZsdk_network_Info.udp_port = UDP_SERVER_PORT;
    g_JZsdk_network_Info.tcp_port = TCP_SERVER_PORT;

    //1、打开网卡设备
    memset(cmdStr, 0, sizeof(cmdStr));
    snprintf(cmdStr, sizeof(cmdStr), "ifconfig %s up", LINUX_NETWORK_DEV);
    ret = system(cmdStr);
    if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
        JZSDK_LOG_ERROR("Can't open the network."
                       "Probably the program not execute with root permission."
                       "Please use the root permission to execute the program.");
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }

    //2、配置IP地址
    memset(cmdStr, 0, sizeof(cmdStr));
    snprintf(cmdStr, sizeof(cmdStr), "ifconfig %s %s netmask %s", LINUX_NETWORK_DEV, NET_WORK_IPADDR, NET_WORK_NETMASK);
    ret = system(cmdStr);
    if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
        JZSDK_LOG_ERROR("Can't config the ip address of network."
                       "Probably the program not execute with root permission."
                       "Please use the root permission to execute the program.");
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }

    //udp初始化
    JZsdk_NetWork_UdpInit();

    //tcp初始化
    JZsdk_NetWork_TcpInit();

    NetworkMode = JZ_FLAGCODE_ON;

    return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

T_JZsdkReturnCode JZsdk_NetWork_DeInit()
{
    NetworkMode = JZ_FLAGCODE_OFF;
    return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

static T_JZsdkReturnCode JZsdk_NetWork_Sent(const unsigned char *data, const int data_len)
{
    int bytes_sent = sendto(g_JZsdk_network_Info.udp_socket, data, data_len, 0,
                                (struct sockaddr *) &g_JZsdk_network_Info.udp_server_addr, sizeof(g_JZsdk_network_Info.udp_server_addr));

    if (bytes_sent == -1) 
    {
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }
    else
    {
        return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
    }
}

T_JZsdkReturnCode JZsdk_NetWork_SentData(const unsigned char *data, const int data_len)
{
    if (NetworkMode != JZ_FLAGCODE_ON)
    {
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }

    T_JZsdkReturnCode returnCode;
    
    int lengthOfDataHaveBeenSent = 0;
    int lengthOfDataToBeSent = 0;

    while (data_len - lengthOfDataHaveBeenSent) 
    {
        lengthOfDataToBeSent = JZSDK_UTIL_MIN(MAX_SEND_FRAME_LENTH,
                                                data_len - lengthOfDataHaveBeenSent);
        
        returnCode = JZsdk_NetWork_Sent((const uint8_t *) data + lengthOfDataHaveBeenSent,
                                                        lengthOfDataToBeSent);
        if (JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
        {
            JZSDK_LOG_ERROR("网口发送错误");
        }
        
        lengthOfDataHaveBeenSent += lengthOfDataToBeSent;
    }

    return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}