net.cpp 4.91 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdint.h>
#include "net.h"

namespace sccl {
namespace hardware {
namespace net {

/**
 * 打印套接字地址信息
 *
 * @param sock_addr 套接字地址结构体指针
 * @param prefix 输出信息的前缀字符串
 * @return scclResult_t 返回操作结果,scclSuccess表示成功
 *
 * @note 该函数会格式化输出套接字地址信息,包含在分隔线中以便阅读
 */
scclResult_t printSocketAddr(union net_socket::scclSocketAddress* sock_addr, const char* prefix) {
    char line[SOCKET_NAME_MAXLEN + MAX_IF_NAME_SIZE + 2];
    net::net_socket::scclSocketToString(sock_addr, line);
20
    printf("==========================================\n%s addr: %s"
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
           "\n==========================================\n",
           prefix,
           line);

    return scclSuccess;
}

/**
 * 打印套接字信息
 *
 * @param sock 指向scclSocket结构体的指针,包含套接字相关信息
 * @param prefix 输出信息的前缀字符串
 * @return 返回scclResult_t类型,成功时返回scclSuccess
 *
 * 该函数用于格式化输出套接字的详细信息,包括文件描述符、重试次数、
 * 地址信息、状态标志等调试信息。输出格式包含分隔线以便于阅读。
 */
scclResult_t printSocketInfo(struct net_socket::scclSocket* sock, const char* prefix) {
    char line[SOCKET_NAME_MAXLEN + MAX_IF_NAME_SIZE + 2];
    net::net_socket::scclSocketToString(&sock->addr, line);

    printf("\n==========================================\n%s: fd: %d, acceptFd: %d, timedOutRetries: %d, refusedRetries: %d, \naddr: %s, abortFlag=%u, "
           "asyncFlag=%d, state=%d, salen=%d, magic=%lu, type=%d"
           "\n==========================================\n",
           prefix,
           sock->fd,
           sock->acceptFd,
           sock->timedOutRetries,
           sock->refusedRetries,
           line,
           sock->abortFlag != NULL ? *sock->abortFlag : 0,
           sock->asyncFlag,
           int(sock->state),
           sock->salen,
           sock->magic,
           int(sock->type));

    return scclSuccess;
}

////////////////////////////////////////////////////////////////////////////////////////
// 定义网络状态的枚举类型
typedef enum scclNetState {
    scclNetStateInit     = 0, // 初始化状态
    scclNetStateEnabled  = 1, // 启用状态
    scclNetStateDisabled = 2  // 禁用状态
} scclNetState_t;

// 定义一个数组,存储每种网络类型的状态,初始值均为初始化状态
scclNetState_t scclNetStates[scclNetTypeNum] = {scclNetStateInit, scclNetStateInit, scclNetStateInit};

/**
 * 获取指定网络接口的状态
 *
 * @param i 网络接口索引
 * @param state 输出参数,用于存储获取到的网络状态
 * @return scclResult_t 返回操作结果,成功返回scclSuccess
 *
 * @note 该函数是线程安全的,内部使用互斥锁保护共享状态
 * @note 如果网络未初始化,会自动执行初始化并更新状态
 */
scclResult_t netGetState(int i, scclNetState_t* state) {
    pthread_mutex_lock(&netLock);
    if(scclNetStates[i] == scclNetStateInit) {
        int ndev;
        if(scclNets[i]->init() != scclSuccess)
            scclNetStates[i] = scclNetStateDisabled;
        else if(scclNets[i]->devices(&ndev) != scclSuccess || ndev <= 0)
            scclNetStates[i] = scclNetStateDisabled;
        else
            scclNetStates[i] = scclNetStateEnabled;
    }
    *state = scclNetStates[i];
    pthread_mutex_unlock(&netLock);
    return scclSuccess;
}

/**
 * @brief 初始化指定名称的网络
 *
 * 遍历所有可用的网络类型,查找与指定名称匹配且状态为启用的网络。
 * 如果找到匹配的网络,则将其赋值给scclNet参数。
 *
 * @param netName 要查找的网络名称,可为NULL表示匹配任意名称
 * @param scclNet 输出参数,用于返回找到的网络实例
 *
 * @return scclResult_t 返回操作结果:
 *         - scclSuccess 成功找到匹配网络
 *         - scclInvalidUsage 未找到匹配网络
 */
scclResult_t scclNetInit(const char* netName, scclNet_t*& scclNet) {
    // Initialize main communication network
    bool ok = false;
    for(int i = 0; i < scclNetTypeNum; i++) {
        if(scclNets[i] == nullptr)
            continue;

        enum scclNetState state;
        SCCLCHECK(netGetState(i, &state));
        if(state != scclNetStateEnabled)
            continue;
        if(netName && strcasecmp(netName, scclNets[i]->name) != 0)
            continue;

        scclNet = scclNets[i];
        ok      = true;

        // if(scclCollNets[i]) {
        //     SCCLCHECK(collNetGetState(i, &state));
        //     if(state == scclNetStateEnabled) {
        //         comm->scclCollNet = scclCollNets[i];
        //     }
        // }
        break;
    }

    if(!ok) {
        WARN("Error: network %s not found.", netName ? netName : "");
        return scclInvalidUsage;
    }
    return scclSuccess;
}

} // namespace net
} // namespace hardware
} // namespace sccl