GetEndpoints (C)
前置 / 配套
- 拉到 Endpoint 后用 配置与创建 真正建立 Session.
- 跨服务发现请用 FindServers.
API
DARRA_OPCUA_API DarraUa_Status DARRA_OPCUA_CALL DarraUa_Discovery_GetEndpoints(
const char* endpoint_url,
uint32_t timeout_ms,
DarraUa_GetEndpointsResult** out_result);
DARRA_OPCUA_API uint32_t DARRA_OPCUA_CALL
DarraUa_GetEndpointsResult_GetCount(const DarraUa_GetEndpointsResult* r);
DARRA_OPCUA_API const DarraUa_EndpointDescription* DARRA_OPCUA_CALL
DarraUa_GetEndpointsResult_GetEndpoint(
const DarraUa_GetEndpointsResult* r, uint32_t index);
DARRA_OPCUA_API void DARRA_OPCUA_CALL
DarraUa_GetEndpointsResult_Delete(DarraUa_GetEndpointsResult* r);
通过临时 SecureChannel (None mode) 连服务端, 拉 Endpoint 列表后立即断开. 不需要 Session.
EndpointDescription 字段
typedef struct {
char* endpoint_url;
char* security_policy_uri;
int32_t security_mode; /* DarraUa_MessageSecurityMode */
char* server_application_uri;
char* server_product_uri;
char* server_application_name; /* LocalizedText.text */
int32_t server_application_type; /* 0=Server 1=Client 2=ClientAndServer 3=DiscoveryServer */
uint8_t* server_certificate; /* DER, 可为 NULL */
int32_t server_certificate_len;
char* transport_profile_uri;
uint8_t security_level;
uint8_t _pad[3];
int32_t user_token_count;
char** user_token_policy_ids;
int32_t* user_token_types; /* 0=Anonymous 1=Username 2=Certificate 3=IssuedToken */
} DarraUa_EndpointDescription;
所有指针字段由 Stack 在 GetEndpoints 内部分配, 由 DarraUa_GetEndpointsResult_Delete 统一释放, 调用方不要单独 free.
完整示例
#include <darra_opcua/darra_opcua.h>
#include <stdio.h>
int main(int argc, char** argv)
{
const char* url = (argc >= 2) ? argv[1] : "opc.tcp://localhost:4840";
DarraUa_Initialize();
DarraUa_GetEndpointsResult* res = NULL;
DarraUa_Status st = DarraUa_Discovery_GetEndpoints(url, 5000, &res);
if (!DARRA_UA_STATUS_IS_GOOD(st)) {
fprintf(stderr, "GetEndpoints failed: 0x%08X (%s)\n",
(unsigned)st, DarraUa_StatusName(st));
DarraUa_Shutdown();
return 1;
}
uint32_t n = DarraUa_GetEndpointsResult_GetCount(res);
printf("Server has %u endpoints:\n", (unsigned)n);
for (uint32_t i = 0; i < n; ++i) {
const DarraUa_EndpointDescription* ep =
DarraUa_GetEndpointsResult_GetEndpoint(res, i);
if (!ep) continue;
printf("\n URL: %s\n", ep->endpoint_url);
printf(" Mode: %d\n", ep->security_mode);
printf(" Policy: %s\n", ep->security_policy_uri);
printf(" Tokens: %d\n", ep->user_token_count);
for (int t = 0; t < ep->user_token_count; ++t) {
printf(" - type=%d policy_id=%s\n",
ep->user_token_types[t],
ep->user_token_policy_ids[t]);
}
}
DarraUa_GetEndpointsResult_Delete(res);
DarraUa_Shutdown();
return 0;
}
典型输出
Server has 4 endpoints:
URL: opc.tcp://server:4840
Mode: 1 (None)
Policy: http://opcfoundation.org/UA/SecurityPolicy#None
Tokens: 1
- type=0 policy_id=anonymous
URL: opc.tcp://server:4840
Mode: 3 (SignAndEncrypt)
Policy: http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256
Tokens: 2
- type=1 policy_id=username
- type=2 policy_id=certificate
服务端通常暴露多个组合 (None / Sign / SignAndEncrypt × Anonymous / Username / Certificate), 客户端按需求挑.
错误码
| 状态码 | 含义 |
|---|---|
DARRA_UA_STATUS_BAD_COMMUNICATION_ERROR | 网络 / 服务端不可达 |
DARRA_UA_STATUS_BAD_TIMEOUT | timeout_ms 内未收到响应 |
DARRA_UA_STATUS_BAD_TCP_ENDPOINT_URL_INVALID | URL 格式错 |
DARRA_UA_STATUS_BAD_SERVICE_UNSUPPORTED | 服务端不支持 (罕见) |