pdcomm_modbus_call
함수
엔드포인트에서 JSON 명령 하나를 실행하고 JSON 응답을 반환합니다.
int32_t pdcomm_modbus_call(pdcomm_modbus_handle endpoint, const uint8_t *input, size_t size, pdcomm_modbus_handle *out)입력은 action 멤버로 명령을 선택하는 UTF-8 JSON 객체 하나입니다. 응답은 #PDCOMM_MODBUS_OK와 함께 {"ok":true,"result":...}이거나, #PDCOMM_MODBUS_SERVICE_ERROR와 함께 {"error":"...","ok":false}입니다.
명령:
capabilities,state: 각각 빌드 기능, 그리고 구성과 연결 상태입니다.config를 포함한configure: 연결되지 않은 동안 구성을 교체합니다. 멤버는transport("tcp","rtu","ascii"),role("client","server","gateway"),address(127.0.0.1:502나[::1]:502같은 TCP 소켓 주소IP:port이며, 호스트 이름은 해석하지 않습니다),port(시리얼 장치),unit(1부터 247까지),baud,parity("even","odd","none"),stop_bits(1 또는 2이며"none"패리티에는 2가 필요합니다),timeout_ms(1부터 60000까지), 선택 항목인ascii_timeout_ms,turnaround_ms,routes(게이트웨이 유닛 맵),security입니다.security는 Modbus/TCP Security를 켭니다.chain,private_key,trust는 PEM 파일 경로이고,mode는"encrypted"(기본값) 또는"authentication_only"입니다.roles는 피어 인증서의 역할 이름을 허용된 기능 코드(function code)에 대응시키고,null_role은 역할 없이 허용되는 코드를 나열하며,crls,require_revocation,hostname은 인증서 검증을 제어합니다.connect,disconnect: 소켓, 리스너 또는 시리얼 포트를 열거나 닫습니다. 포트 0에 바인딩한 서버는 실제 주소를config.address에 보고합니다. TCP 클라이언트는 요청 시간 초과, 상대의 연결 종료, I/O 오류가 나면 연결을 닫습니다. 그 뒤에는"connected":false를 보고하고, 다시 연결할 때까지 요청은Closed로 실패합니다.poll: 서버나 게이트웨이의 대기 중인 요청을 한 번 처리하고{"handled":N}을 반환합니다. 백그라운드에서는 아무것도 실행되지 않으므로 주기적으로 호출합니다.pdu와 선택 항목unit을 포함한request: 클라이언트가 요청 하나를 보내고 회선에서 응답을 기다립니다.pdu와 선택 항목unit을 포함한execute: I/O 없이 엔드포인트 자체의 데이터 모델로 요청을 처리합니다.data_get,data_set(table,address,values),model_set: 데이터 모델을 읽거나 변경합니다. 테이블은coils,discrete_inputs,holding_registers,input_registers입니다.diagnostics,diagnostics_set(register,busy): Diagnostics(기능 코드 08) 레지스터, 수신 전용(listen-only) 상태, 카운터를 다룹니다.trace,trace_clear: 최근 1000개의 트레이스된 요청과 회선 프레임을 다룹니다.project_export,project_import(project): 구성과 데이터 모델을 하나의pdcomm.modbus.project버전 1 문서로 다룹니다.fault(bytes, 선택 항목transport,gap_us): I/O 없이 TCP, RTU 또는 ASCII 프레임 디코더로 합성 회선 바이트를 디코딩합니다.serial_ports는 호스트의 시리얼 장치를 나열합니다.logging_configure(config),logging_status,logging_flush:pdcomm_modbus_logging_*함수와 같은 제어를 제공합니다.text를 포함한license_install: 이 라이브러리(모든 엔드포인트)에 PDComm 라이선스 텍스트를 설치하고, 이전에 설치한 텍스트를 교체합니다. 빈 문자열을 넘기면 제거합니다. 결과는 서명이 검증된 라이선스 블록 수인{"installed":N}입니다. 그런 블록이 없는 텍스트는"code":"license_invalid"로 실패하며 이전 텍스트를 유지합니다.license_status: 라이선스 상태 객체(schema_version1)입니다.build_date,host_id,program, 찾은sources,verification이 붙은 모든 라이선스 블록licenses, 그리고 모듈 ID마다state(licensed,evaluation,missing,expired,not-yet-valid,updates-expired,program-mismatch,host-mismatch중 하나),granted,days_left를 대응시키는modules가 들어 있습니다.host_id: 호스트에 묶인 라이선스가 지정하는 ID인{"host_id":"PDH1-XXXX-XXXX-XXXX-XXXX"}입니다. 머신 ID를 읽을 수 없으면"code":"host_id_unavailable"로 실패합니다.
라이선스 검사의 오류 응답에는 error 외에 code 멤버가 들어 있습니다. 거부된 connect는 {"code":"license_required","error":"PDComm license required for module 'modbus' (missing): ...","license":{"license_id":null,"module":"modbus", "state":"missing"},"ok":false}를 반환합니다.
pdu는 Modbus 애플리케이션 프로토콜(Modbus Application Protocol) PDU이며, 바이트 배열 또는 16진수 문자열로 나타냅니다. PDU는 기능 코드 뒤에 데이터가 오며 유닛 식별자, MBAP 헤더, CRC, LRC는 들어 있지 않습니다. request와 execute의 결과는 {"response":[...]|null,"status":"success"|"exception"|"no_response","source":"wire"|"local"}입니다. 예외 응답은 비트 0x80이 설정된 기능 코드 뒤에 예외 코드가 옵니다.
pdcomm_modbus_handle endpoint = 0, buffer = 0;
size_t size = 0;
assert(pdcomm_modbus_endpoint_create(&endpoint) == 0);
const char *request = "{\"action\":\"execute\",\"pdu\":[6,0,0,0,9]}";
assert(pdcomm_modbus_call(endpoint, (const uint8_t *)request, strlen(request),
&buffer) == 0);
assert(pdcomm_modbus_buffer_copy(buffer, NULL, 0, &size) ==
PDCOMM_MODBUS_BUFFER_TOO_SMALL);
char *text = (char *)malloc(size + 1);
assert(text);
assert(pdcomm_modbus_buffer_copy(buffer, (uint8_t *)text, size, &size) == 0);
text[size] = 0;
assert(strstr(text, "\"response\":[6,0,0,0,9]"));
free(text);
assert(pdcomm_modbus_release(buffer) == 0);
assert(pdcomm_modbus_release(endpoint) == 0);매개변수
| 이름 | 설명 |
|---|---|
endpoint | 엔드포인트 핸들입니다. |
input | UTF-8 JSON 명령입니다. 호출 중에 복사됩니다. |
size | input의 크기(바이트)이며 1부터 16 MiB까지입니다. |
out | 소유된 응답 버퍼를 받습니다. 포인터와 크기 검사를 통과하면 0이 기록됩니다. |
반환값
결과 버퍼와 함께 #PDCOMM_MODBUS_OK를 반환하거나, 오류 버퍼와 함께 #PDCOMM_MODBUS_SERVICE_ERROR를 반환합니다. 포인터가 null이거나, 크기가 0이거나 너무 크거나, JSON이 잘못되었으면 #PDCOMM_MODBUS_INVALID_INPUT을 반환합니다(버퍼 없음). 그 밖에 #PDCOMM_MODBUS_INVALID_HANDLE 또는 #PDCOMM_MODBUS_INTERNAL_ERROR(버퍼 없음)를 반환합니다.
참고
- 다른 스레드가 같은 엔드포인트에서 명령을 실행하는 동안 블로킹되며, 클라이언트
request는 응답이 오거나timeout_ms가 지날 때까지 블로킹됩니다. 반환된 버퍼는 pdcomm_modbus_release()로 해제합니다.