817 lines
29 KiB
C
817 lines
29 KiB
C
#include "pcpa.h"
|
|
|
|
e_pcpa_t _pcpaGetErrorFromPcpp(e_pcpp_t err) {
|
|
switch (err) {
|
|
case e_pcpp_ok:
|
|
return e_pcpa_ok;
|
|
case e_pcpp_to:
|
|
return e_pcpa_to;
|
|
case e_pcpp_closed:
|
|
return e_pcpa_closed;
|
|
case e_pcpp_no_client:
|
|
return e_pcpa_no_client;
|
|
case e_pcpp_wsa_noinit:
|
|
return e_pcpa_wsa_noinit;
|
|
case e_pcpp_inval_addr:
|
|
return e_pcpa_inval_addr;
|
|
case -14:
|
|
return (e_pcpa_t)-16;
|
|
case -13:
|
|
return (e_pcpa_t)-15;
|
|
case e_pcpp_timeout_open:
|
|
return e_pcpa_timeout_open;
|
|
case e_pcpp_no_server:
|
|
return e_pcpa_no_server;
|
|
case e_pcpp_recv_unset:
|
|
return e_pcpa_cb_table_full;
|
|
case -9:
|
|
return (e_pcpa_t)-7;
|
|
case -8:
|
|
return (e_pcpa_t)-6;
|
|
case -7:
|
|
return (e_pcpa_t)-3;
|
|
case e_pcpp_timeout_closed:
|
|
return e_pcpa_timeout_closed;
|
|
case e_pcpp_param_invalid:
|
|
return e_pcpa_param_invalid;
|
|
case -4:
|
|
return (e_pcpa_t)-8;
|
|
case e_pcpp_already_open:
|
|
return e_pcpa_already_open;
|
|
case e_pcpp_cannot_open:
|
|
return e_pcpa_cannot_open;
|
|
case e_pcpp_not_open:
|
|
return e_pcpa_not_open;
|
|
default:
|
|
return e_pcpa_closed;
|
|
}
|
|
}
|
|
|
|
void pcpaCloseBinary(pcpa_t *stream) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPA stream isn't set");
|
|
return;
|
|
}
|
|
stream->binary_mode = binary_mode_none;
|
|
|
|
pcppCloseBinary(&stream->pcpp);
|
|
}
|
|
|
|
void pcpaClose(pcpa_t *stream) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPA stream isn't set");
|
|
return;
|
|
}
|
|
pcppClose(&stream->pcpp);
|
|
stream->err = e_pcpa_unknown;
|
|
stream->state = pcpa_state_none;
|
|
stream->callback_table = NULL;
|
|
stream->callback_max = 0;
|
|
stream->callback_count = 0;
|
|
stream->recv_buffer = NULL;
|
|
stream->recv_buffer_len = 0;
|
|
stream->send_buffer = NULL;
|
|
stream->send_buffer_len = 0;
|
|
stream->binary_mode = binary_mode_none;
|
|
stream->binary_mode_before_cb = NULL;
|
|
stream->binary_mode_after_cb = NULL;
|
|
stream->binary_mode_before_data = NULL;
|
|
stream->binary_mode_after_data = NULL;
|
|
memset(&stream->send_data, 0, sizeof stream->send_data);
|
|
(stream->send_data).length = 0;
|
|
}
|
|
|
|
e_pcpa_t pcpaInitStream(pcpa_t *stream) {
|
|
if (LIBPCP_VERSION == NULL) {
|
|
amiDebugLog("error PCPA version isn't set");
|
|
return e_pcpa_generic;
|
|
}
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPA stream isn't set");
|
|
return e_pcpa_stream_unset;
|
|
}
|
|
|
|
e_pcpp_t err = pcppInitStream(&stream->pcpp);
|
|
if (err != e_pcpp_ok) {
|
|
return err == e_pcpp_wsa_noinit ? e_pcpa_wsa_noinit : e_pcpa_param_invalid;
|
|
}
|
|
|
|
stream->err = e_pcpa_unknown;
|
|
stream->state = pcpa_state_none;
|
|
stream->callback_table = NULL;
|
|
stream->callback_max = 0;
|
|
stream->callback_count = 0;
|
|
stream->recv_buffer = NULL;
|
|
stream->recv_buffer_len = 0;
|
|
stream->send_buffer = NULL;
|
|
stream->send_buffer_len = 0;
|
|
stream->binary_mode = binary_mode_none;
|
|
stream->binary_mode_before_cb = NULL;
|
|
stream->binary_mode_after_cb = NULL;
|
|
stream->binary_mode_before_data = NULL;
|
|
stream->binary_mode_after_data = NULL;
|
|
stream->before_cb = NULL;
|
|
ZERO(stream->recv_data);
|
|
ZERO(stream->send_data);
|
|
return e_pcpa_ok;
|
|
}
|
|
|
|
e_pcpa_t pcpaOpenClient(pcpa_t *stream, char *ipAddr, ushort port, uint param_4,
|
|
timeout_t timeout) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPA stream isn't set");
|
|
return e_pcpa_stream_unset;
|
|
}
|
|
if (ipAddr == 0) {
|
|
amiDebugLog("error PCPA IpAddr isn't set");
|
|
return e_pcpa_param_invalid;
|
|
}
|
|
|
|
stream->state = pcpa_state_wait_prompt;
|
|
e_pcpa_t err =
|
|
_pcpaGetErrorFromPcpp(pcppOpenClient(&stream->pcpp, ipAddr, port, param_4, timeout));
|
|
stream->err = err;
|
|
if (err != e_pcpa_to) stream->state = pcpa_state_none;
|
|
|
|
return err;
|
|
}
|
|
|
|
e_pcpa_t pcpaOpenServerWithBinary(pcpa_t *stream, int open_mode, u_short port, u_short binary_port,
|
|
undefined4 param_5) {
|
|
e_pcpa_t err;
|
|
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPA stream isn't set");
|
|
return e_pcpa_stream_unset;
|
|
}
|
|
|
|
switch (open_mode) {
|
|
case 0:
|
|
stream->err = err = _errP2A(pcppOpenServer(&stream->pcpp, 0, port, param_5));
|
|
if (err != e_pcpa_ok) {
|
|
amiDebugLog("error pcppOpenServer");
|
|
return err;
|
|
}
|
|
stream->err = err = _errP2A(pcppOpenBinaryServer(&stream->pcpp, 0, binary_port));
|
|
if (err != e_pcpa_ok) {
|
|
amiDebugLog("error pcppOpenBinaryServer");
|
|
return err;
|
|
}
|
|
break;
|
|
case 1:
|
|
stream->err = err = _errP2A(pcppOpenServer(&stream->pcpp, 1, port, param_5));
|
|
if (err != e_pcpa_ok) {
|
|
amiDebugLog("error pcppOpenServer");
|
|
return err;
|
|
}
|
|
stream->err = err = _errP2A(pcppOpenBinaryServer(&stream->pcpp, 1, binary_port));
|
|
if (err != e_pcpa_ok) {
|
|
amiDebugLog("error pcppOpenBinaryServer");
|
|
return err;
|
|
}
|
|
break;
|
|
default:
|
|
amiDebugLog("error Open Mode isn't set");
|
|
return stream->err = e_pcpa_generic;
|
|
}
|
|
|
|
stream->state = pcpa_state_none;
|
|
return e_pcpa_ok;
|
|
}
|
|
|
|
e_pcpa_t pcpaSetCallbackFunc(pcpa_t *stream, char *keyword, pcpa_callback *callback, void *data) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPA stream isn't set");
|
|
return e_pcpa_stream_unset;
|
|
}
|
|
|
|
if (keyword == NULL) {
|
|
amiDebugLog("error keyword isn't set");
|
|
return e_pcpa_generic;
|
|
}
|
|
|
|
if (callback == NULL) {
|
|
amiDebugLog("error Callback func isn't set");
|
|
return e_pcpa_generic;
|
|
}
|
|
|
|
if (stream->callback_table == NULL) {
|
|
amiDebugLog("error Callback_table buffer isn't set");
|
|
return e_pcpa_cb_table_unset;
|
|
}
|
|
|
|
if (strnlen(keyword, PCP_KEYWORD_MAX + 1) > PCP_KEYWORD_MAX) {
|
|
amiDebugLog("error a keyword is too long");
|
|
return e_pcpa_generic;
|
|
}
|
|
|
|
if (stream->callback_count >= stream->callback_max) return e_pcpa_cb_table_full;
|
|
|
|
sprintf_s(stream->callback_table[stream->callback_count].keyword, PCP_KEYWORD_MAX, "%s",
|
|
keyword);
|
|
stream->callback_table[stream->callback_count].callback = callback;
|
|
stream->callback_table[stream->callback_count].data = data;
|
|
stream->callback_count++;
|
|
|
|
return stream->err = e_pcpa_ok;
|
|
}
|
|
|
|
e_pcpa_t pcpaSetCallbackFuncBuffer(pcpa_t *stream, pcpa_cb_table_t *callback_table,
|
|
uint callbacks_max) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPA stream isn't set");
|
|
return e_pcpa_stream_unset;
|
|
}
|
|
|
|
if (callback_table == NULL || callbacks_max == 0) return e_pcpa_no_table_space;
|
|
|
|
stream->callback_max = callbacks_max;
|
|
stream->callback_table = callback_table;
|
|
stream->callback_count = 0;
|
|
stream->err = e_pcpa_ok;
|
|
return e_pcpa_ok;
|
|
}
|
|
|
|
pcp_send_data_t *pcpaSetSendPacket(pcpa_t *stream, char *keyword, char *value) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPA stream isn't set");
|
|
return NULL;
|
|
}
|
|
return pcppSetSendPacket(&stream->send_data, keyword, value);
|
|
}
|
|
|
|
char *pcpaGetCommand(pcpa_t *pcpa, char *command) {
|
|
if (pcpa == NULL) {
|
|
amiDebugLog("error PCPA stream isn't set");
|
|
return NULL;
|
|
}
|
|
|
|
return pcppGetCommand(&pcpa->recv_data, command);
|
|
}
|
|
|
|
e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) {
|
|
byte bVar1;
|
|
pcpa_callback *callback;
|
|
char *pbVar3;
|
|
int iVar3;
|
|
e_pcpa_t eVar4;
|
|
char *pbVar4;
|
|
uint ms;
|
|
e_pcpp_t iVar5;
|
|
bool bVar6;
|
|
uint local_14;
|
|
amtime_t time;
|
|
amtime_t time_start;
|
|
int timeout;
|
|
|
|
local_14 = timeout_ms;
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPA stream isn't set");
|
|
return e_pcpa_stream_unset;
|
|
}
|
|
amiTimerGet(&time_start);
|
|
timeout = timeout_ms;
|
|
do {
|
|
ms = 0;
|
|
switch (stream->state) {
|
|
case pcpa_state_none:
|
|
amiTimerGet(&time);
|
|
ms = _amTimeDelta(time, time_start);
|
|
if (timeout_ms != TIMEOUT_NONE) {
|
|
if (ms < (uint)timeout_ms) {
|
|
timeout = timeout_ms - ms;
|
|
local_14 = timeout;
|
|
} else {
|
|
timeout = 0;
|
|
local_14 = timeout;
|
|
}
|
|
}
|
|
stream->state = pcpa_state_wait_request;
|
|
iVar5 = pcppRecvRequest(&stream->pcpp, &stream->recv_data, timeout);
|
|
eVar4 = _errP2A(iVar5);
|
|
stream->err = eVar4;
|
|
timeout = local_14;
|
|
if (eVar4 != e_pcpa_to) {
|
|
if (eVar4 == e_pcpa_ok) {
|
|
stream->state = 10;
|
|
amiTimerGet(&time);
|
|
if (timeout_ms != TIMEOUT_NONE &&
|
|
_amTimeDelta(time, time_start) >= timeout_ms) {
|
|
stream->err = e_pcpa_to;
|
|
return stream->err;
|
|
}
|
|
} else {
|
|
stream->state = pcpa_state_none;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
stream->err = e_pcpa_unknown;
|
|
goto LAB_00454d84;
|
|
case pcpa_state_wait_request:
|
|
case pcpa_state_send_response:
|
|
case 9:
|
|
amiTimerGet(&time);
|
|
ms = _amTimeDelta(time, time_start);
|
|
if (timeout_ms != TIMEOUT_NONE) {
|
|
if (ms < (uint)timeout_ms) {
|
|
timeout = timeout_ms - ms;
|
|
local_14 = timeout;
|
|
} else {
|
|
timeout = 0;
|
|
local_14 = timeout;
|
|
}
|
|
}
|
|
iVar5 = pcppIsBusy(&stream->pcpp, timeout);
|
|
eVar4 = _errP2A(iVar5);
|
|
stream->err = eVar4;
|
|
timeout = local_14;
|
|
if (eVar4 != e_pcpa_to) {
|
|
if (stream->state == pcpa_state_send_response) {
|
|
memset(&stream->send_data, 0, PCP_BUF_MAX);
|
|
(stream->send_data).length = 0;
|
|
}
|
|
if (stream->err == e_pcpa_ok) {
|
|
if (stream->binary_mode == binary_mode_none) {
|
|
stream->state = (stream->state != pcpa_state_wait_request) - 1 & 10;
|
|
amiTimerGet(&time);
|
|
if (timeout_ms != TIMEOUT_NONE &&
|
|
_amTimeDelta(time, time_start) >= timeout_ms) {
|
|
stream->err = e_pcpa_to;
|
|
return stream->err;
|
|
}
|
|
} else {
|
|
pcpaCloseBinary(stream);
|
|
stream->state = pcpa_state_none;
|
|
stream->binary_mode = binary_mode_none;
|
|
if (stream->binary_mode_after_cb != NULL) {
|
|
(*stream->binary_mode_after_cb)(stream,
|
|
stream->binary_mode_after_data);
|
|
stream->binary_mode_after_cb = NULL;
|
|
}
|
|
amiTimerGet(&time);
|
|
if (timeout_ms != TIMEOUT_NONE &&
|
|
_amTimeDelta(time, time_start) >= timeout_ms) {
|
|
stream->err = e_pcpa_to;
|
|
return stream->err;
|
|
}
|
|
}
|
|
} else {
|
|
if ((stream->state == 9) && (stream->binary_mode != binary_mode_none)) {
|
|
pcpaCloseBinary(stream);
|
|
if (stream->binary_mode_after_cb != NULL) {
|
|
(*stream->binary_mode_after_cb)(stream,
|
|
stream->binary_mode_after_data);
|
|
stream->binary_mode_after_cb = NULL;
|
|
}
|
|
stream->binary_mode = binary_mode_none;
|
|
}
|
|
stream->state = pcpa_state_none;
|
|
}
|
|
}
|
|
break;
|
|
case pcpa_state_send_request_binary:
|
|
callback = stream->binary_mode_before_cb;
|
|
(stream->pcpp).last_active = _amTimeMs(time_start);
|
|
if (callback != NULL) {
|
|
(*callback)(stream, stream->binary_mode_before_data);
|
|
stream->binary_mode_before_cb = NULL;
|
|
}
|
|
amiTimerGet(&time);
|
|
if (timeout_ms != TIMEOUT_NONE) {
|
|
if (_amTimeDelta(time, time_start) > timeout_ms) {
|
|
timeout = timeout_ms - ms;
|
|
local_14 = timeout;
|
|
} else {
|
|
timeout = 0;
|
|
local_14 = timeout;
|
|
}
|
|
}
|
|
eVar4 = pcpaSendBinary(stream, timeout);
|
|
stream->err = eVar4;
|
|
if (eVar4 == e_pcpa_to) {
|
|
stream->state = pcpa_state_wait_binary;
|
|
} else {
|
|
pcpaCloseBinary(stream);
|
|
if (stream->binary_mode_after_cb != NULL) {
|
|
(*stream->binary_mode_after_cb)(stream, stream->binary_mode_after_data);
|
|
stream->binary_mode_after_cb = NULL;
|
|
}
|
|
stream->binary_mode = binary_mode_none;
|
|
stream->state = pcpa_state_none;
|
|
if (stream->err == e_pcpa_ok) {
|
|
LAB_00454a1a:
|
|
amiTimerGet(&time);
|
|
if (timeout_ms != TIMEOUT_NONE &&
|
|
_amTimeDelta(time, time_start) >= timeout_ms) {
|
|
stream->err = e_pcpa_to;
|
|
return stream->err;
|
|
}
|
|
} else {
|
|
amiDebugLog("error pcpaSendBinary");
|
|
}
|
|
}
|
|
break;
|
|
case pcpa_state_wait_response_binary:
|
|
callback = stream->binary_mode_before_cb;
|
|
(stream->pcpp).last_active = _amTimeMs(time_start);
|
|
if (callback != NULL) {
|
|
(*callback)(stream, stream->binary_mode_before_data);
|
|
stream->binary_mode_before_cb = NULL;
|
|
}
|
|
amiTimerGet(&time);
|
|
ms = _amTimeDelta(time, time_start);
|
|
if (timeout_ms != TIMEOUT_NONE) {
|
|
if (ms < (uint)timeout_ms) {
|
|
timeout = timeout_ms - ms;
|
|
local_14 = timeout;
|
|
} else {
|
|
timeout = 0;
|
|
local_14 = timeout;
|
|
}
|
|
}
|
|
eVar4 = pcpaRecvBinary(stream, timeout);
|
|
stream->err = eVar4;
|
|
if (eVar4 == e_pcpa_to) {
|
|
stream->state = pcpa_state_wait_binary;
|
|
} else {
|
|
pcpaCloseBinary(stream);
|
|
if (stream->binary_mode_after_cb != NULL) {
|
|
(*stream->binary_mode_after_cb)(stream, stream->binary_mode_after_data);
|
|
stream->binary_mode_after_cb = NULL;
|
|
}
|
|
stream->binary_mode = binary_mode_none;
|
|
stream->state = pcpa_state_none;
|
|
if (stream->err == e_pcpa_ok) goto LAB_00454a1a;
|
|
amiDebugLog("error pcpaRecvBinary");
|
|
}
|
|
break;
|
|
case 10:
|
|
// TODO: Figure out why recv_buf is empty at this point in the FSM
|
|
if (stream->before_cb != NULL)
|
|
stream->before_cb(stream, stream->pcpp.sock.recv_buf);
|
|
|
|
if (stream->callback_table == NULL) {
|
|
amiDebugLog("error Callback_table buffer isn't set");
|
|
|
|
stream->err = e_pcpa_cb_table_unset;
|
|
return stream->err;
|
|
}
|
|
if (stream->callback_count != 0) {
|
|
iVar5 = 0;
|
|
do {
|
|
pbVar3 = pcppGetKeyword(&stream->recv_data, 0);
|
|
pbVar4 = stream->callback_table->keyword + iVar5;
|
|
do {
|
|
bVar1 = *pbVar3;
|
|
bVar6 = bVar1 < (byte)*pbVar4;
|
|
if (bVar1 != *pbVar4) {
|
|
LAB_004547c8:
|
|
iVar3 = (1 - (uint)bVar6) - (uint)(bVar6 != 0);
|
|
goto LAB_004547cd;
|
|
}
|
|
if (bVar1 == 0) break;
|
|
bVar1 = ((byte *)pbVar3)[1];
|
|
bVar6 = bVar1 < ((byte *)pbVar4)[1];
|
|
if (bVar1 != ((byte *)pbVar4)[1]) goto LAB_004547c8;
|
|
pbVar3 = (char *)((byte *)pbVar3 + 2);
|
|
pbVar4 = (char *)((byte *)pbVar4 + 2);
|
|
} while (bVar1 != 0);
|
|
iVar3 = 0;
|
|
LAB_004547cd:
|
|
if (iVar3 == 0) {
|
|
(stream->callback_table[ms].callback)(stream,
|
|
stream->callback_table[ms].data);
|
|
goto LAB_004547f1;
|
|
}
|
|
ms = ms + 1;
|
|
iVar5 = iVar5 + 40;
|
|
} while (ms < stream->callback_count);
|
|
}
|
|
pcppSetSendPacket(&stream->send_data, "?", 0);
|
|
LAB_004547f1:
|
|
amiTimerGet(&time);
|
|
ms = _amTimeDelta(time, time_start);
|
|
if (timeout_ms != TIMEOUT_NONE) {
|
|
if (ms < (uint)timeout_ms) {
|
|
local_14 = timeout_ms - ms;
|
|
} else {
|
|
local_14 = 0;
|
|
}
|
|
}
|
|
iVar5 = pcppSendResponseTable(&stream->pcpp, &stream->send_data, local_14);
|
|
eVar4 = _errP2A(iVar5);
|
|
stream->err = eVar4;
|
|
if (eVar4 == e_pcpa_to) {
|
|
stream->state = pcpa_state_send_response;
|
|
} else {
|
|
memset(&stream->send_data, 0, PCP_BUF_MAX);
|
|
(stream->send_data).length = 0;
|
|
stream->state = pcpa_state_none;
|
|
}
|
|
if (stream->binary_mode != binary_mode_none) {
|
|
stream->state = (stream->binary_mode == binary_mode_send) ? 7 : 8;
|
|
}
|
|
amiTimerGet(&time);
|
|
timeout = local_14;
|
|
if (timeout_ms != TIMEOUT_NONE && _amTimeDelta(time, time_start) >= timeout_ms) {
|
|
stream->err = e_pcpa_to;
|
|
return stream->err;
|
|
}
|
|
}
|
|
} while (stream->err == e_pcpa_ok);
|
|
LAB_00454d84:
|
|
return stream->err;
|
|
}
|
|
|
|
e_pcpa_t pcpaRecvBinary(pcpa_t *stream, uint something) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPA stream isn't set");
|
|
return e_pcpa_stream_unset;
|
|
}
|
|
if (stream->recv_buffer == NULL) {
|
|
amiDebugLog("error Recv buffer isn't set");
|
|
pcpaCloseBinary(stream);
|
|
pcpaClose(stream);
|
|
return stream->err = e_pcpa_cb_table_full;
|
|
}
|
|
|
|
stream->state = pcpa_state_wait_response_binary;
|
|
e_pcpa_t err;
|
|
stream->err = err = _errP2A(
|
|
pcppRecvBinary(&stream->pcpp, stream->recv_buffer, stream->recv_buffer_len, something));
|
|
if (err != e_pcpa_to) stream->state = pcpa_state_none;
|
|
|
|
return err;
|
|
}
|
|
|
|
e_pcpa_t pcpaSendBinary(pcpa_t *stream, uint param_2) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPA stream isn't set");
|
|
return e_pcpa_stream_unset;
|
|
}
|
|
if (stream->send_buffer == NULL) {
|
|
amiDebugLog("error Send buffer isn't set");
|
|
stream->err = e_pcpa_cb_table_full;
|
|
pcpaCloseBinary(stream);
|
|
pcpaClose(stream);
|
|
return stream->err;
|
|
}
|
|
|
|
stream->state = pcpa_state_send_request_binary;
|
|
e_pcpa_t err;
|
|
stream->err = err = _errP2A(
|
|
pcppSendBinary(&stream->pcpp, stream->send_buffer, stream->send_buffer_len, param_2));
|
|
if (err != e_pcpa_to) stream->state = pcpa_state_none;
|
|
|
|
return err;
|
|
}
|
|
|
|
e_pcpa_t pcpaSetSendBinaryBuffer(pcpa_t *stream, const unsigned char *send_buffer, size_t len) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPA stream isn't set");
|
|
return e_pcpa_stream_unset;
|
|
}
|
|
if (send_buffer == NULL) {
|
|
amiDebugLog("error Send Buffer isn't set");
|
|
return e_pcpa_timeout_closed;
|
|
}
|
|
stream->send_buffer = send_buffer;
|
|
stream->send_buffer_len = len;
|
|
stream->err = e_pcpa_ok;
|
|
return e_pcpa_ok;
|
|
}
|
|
|
|
e_pcpa_t pcpaSetBeforeBinaryModeCallBackFunc(pcpa_t *stream, pcpa_callback *callback, void *data) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error don't set stream");
|
|
return e_pcpa_stream_unset;
|
|
}
|
|
if (callback == NULL) {
|
|
amiDebugLog("error Binary mode callback func isn't set");
|
|
return e_pcpa_generic;
|
|
}
|
|
stream->binary_mode_before_cb = callback;
|
|
stream->binary_mode_before_data = data;
|
|
stream->err = e_pcpa_ok;
|
|
return e_pcpa_ok;
|
|
}
|
|
|
|
e_pcpa_t pcpaSetAfterBinaryModeCallBackFunc(pcpa_t *stream, pcpa_callback *callback, void *data) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error don't set stream");
|
|
return e_pcpa_stream_unset;
|
|
}
|
|
if (callback == NULL) {
|
|
amiDebugLog("error Binary mode callback func isn't set");
|
|
return e_pcpa_generic;
|
|
}
|
|
stream->binary_mode_after_cb = callback;
|
|
stream->binary_mode_after_data = data;
|
|
stream->err = e_pcpa_ok;
|
|
return e_pcpa_ok;
|
|
}
|
|
|
|
e_pcpa_t pcpaSetBinaryMode(pcpa_t *stream, binary_mode_t binary_mode) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPA stream isn't set");
|
|
return e_pcpa_stream_unset;
|
|
}
|
|
if (pcppGetServerSocket(&stream->pcpp, 1) == HANDLE_INVAL) {
|
|
return stream->err = -19;
|
|
}
|
|
stream->binary_mode = binary_mode;
|
|
stream->err = e_pcpa_ok;
|
|
return e_pcpa_ok;
|
|
}
|
|
|
|
e_pcpa_t pcpaSetRecvBinaryBuffer(pcpa_t *stream, unsigned char *recv_buffer, size_t len) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPA stream isn't set");
|
|
return e_pcpa_stream_unset;
|
|
}
|
|
if (recv_buffer == NULL) {
|
|
amiDebugLog("error Recv Buffer isn't set");
|
|
return e_pcpa_timeout_closed;
|
|
}
|
|
stream->recv_buffer = recv_buffer;
|
|
stream->recv_buffer_len = len;
|
|
stream->err = e_pcpa_ok;
|
|
return e_pcpa_ok;
|
|
}
|
|
|
|
pcp_send_data_t *pcpaAddSendPacket(pcpa_t *stream, char *keyword, char *value) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPA stream isn't set");
|
|
return NULL;
|
|
}
|
|
return pcppAddSendPacket(&stream->send_data, keyword, value);
|
|
}
|
|
|
|
char *pcpaGetKeyword(pcpa_t *stream, uint keyword_num) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPA stream isn't set");
|
|
return NULL;
|
|
}
|
|
return pcppGetKeyword(&stream->recv_data, keyword_num);
|
|
}
|
|
|
|
e_pcpa_t pcpaIsBusy(pcpa_t *pcpa, timeout_t timeout) {
|
|
amtime_t now;
|
|
amtime_t start;
|
|
|
|
if (pcpa == NULL) {
|
|
amiDebugLog("error PCPA stream isn't set");
|
|
return e_pcpa_stream_unset;
|
|
}
|
|
|
|
amiTimerGet(&start);
|
|
e_pcpa_t err = _pcpaGetErrorFromPcpp(pcppIsBusy(&pcpa->pcpp, timeout));
|
|
pcpa->err = err;
|
|
if (err == e_pcpa_to) return e_pcpa_to;
|
|
|
|
if (pcpa->state == pcpa_state_send_request)
|
|
memset(pcpa->send_data.data, 0, sizeof pcpa->send_data.data);
|
|
if (pcpa->err != e_pcpa_to) pcpa->state = pcpa_state_none;
|
|
|
|
if (pcpa->state == 11) {
|
|
pcpa->state = 12;
|
|
if (timeout != TIMEOUT_NONE) {
|
|
amiTimerGet(&now);
|
|
uint dt = _amTimeDelta(now, start);
|
|
if (dt < timeout) {
|
|
timeout -= dt;
|
|
} else {
|
|
timeout = 0;
|
|
}
|
|
}
|
|
err = _pcpaGetErrorFromPcpp(pcppRecvResponse(&pcpa->pcpp, &pcpa->recv_data, timeout));
|
|
pcpa->err = err;
|
|
if (err != e_pcpa_to) pcpa->state = pcpa_state_none;
|
|
} else if (pcpa->state == 13) {
|
|
pcpa->state = 14;
|
|
if (timeout != TIMEOUT_NONE) {
|
|
amiTimerGet(&now);
|
|
uint dt = _amTimeDelta(now, start);
|
|
if (dt < timeout) {
|
|
timeout -= dt;
|
|
} else {
|
|
timeout = 0;
|
|
}
|
|
}
|
|
|
|
e_pcpp_t pcpp_err;
|
|
if (pcpa->binary_mode == binary_mode_send) {
|
|
pcpp_err =
|
|
pcppSendBinary(&pcpa->pcpp, pcpa->send_buffer, pcpa->send_buffer_len, timeout);
|
|
} else {
|
|
pcpp_err =
|
|
pcppRecvBinary(&pcpa->pcpp, pcpa->recv_buffer, pcpa->recv_buffer_len, timeout);
|
|
}
|
|
err = _pcpaGetErrorFromPcpp(pcpp_err);
|
|
pcpa->err = err;
|
|
if (err != e_pcpa_to) {
|
|
pcppCloseBinary(&pcpa->pcpp);
|
|
return pcpa->err;
|
|
}
|
|
} else if (pcpa->state == 14 && pcpa->err != e_pcpa_to) {
|
|
pcppCloseBinary(&pcpa->pcpp);
|
|
return pcpa->err;
|
|
}
|
|
return pcpa->err;
|
|
}
|
|
|
|
e_pcpa_t pcpaSendRequest(pcpa_t *stream, timeout_t timeout) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPA stream isn't set");
|
|
return e_pcpa_stream_unset;
|
|
}
|
|
|
|
stream->state = pcpa_state_send_request;
|
|
e_pcpa_t err =
|
|
_pcpaGetErrorFromPcpp(pcppSendRequestTable(&stream->pcpp, &stream->send_data, timeout));
|
|
stream->err = err;
|
|
if (err != e_pcpa_to) {
|
|
if (err != e_pcpa_ok) amiDebugLog("Error : pcppSendRequestTable(%d)", err);
|
|
memset(&stream->send_data, 0, sizeof stream->send_data);
|
|
stream->state = pcpa_state_none;
|
|
}
|
|
return stream->err;
|
|
}
|
|
|
|
e_pcpa_t pcpaRecvResponse(pcpa_t *stream, timeout_t timeout) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPA stream isn't set");
|
|
return e_pcpa_stream_unset;
|
|
}
|
|
|
|
stream->state = pcpa_state_wait_response;
|
|
e_pcpa_t err =
|
|
_pcpaGetErrorFromPcpp(pcppRecvResponse(&stream->pcpp, &stream->recv_data, timeout));
|
|
stream->err = err;
|
|
if (err != e_pcpa_to) {
|
|
if (err != e_pcpa_ok) amiDebugLog("Error : pcppRecvResponse(%d)", err);
|
|
stream->state = pcpa_state_none;
|
|
}
|
|
return err;
|
|
}
|
|
|
|
e_pcpa_t pcpaOpenBinaryClient(pcpa_t *stream, ushort port, timeout_t timeout) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPA stream isn't set");
|
|
return e_pcpa_stream_unset;
|
|
}
|
|
|
|
SOCKADDR_IN *addr = (SOCKADDR_IN *)pcppGetSockAddr(&stream->pcpp, false);
|
|
stream->state = pcpa_state_open_binary;
|
|
char *ipAddr = inet_ntoa(addr->sin_addr);
|
|
|
|
e_pcpa_t pcpa_err =
|
|
_pcpaGetErrorFromPcpp(pcppOpenBinaryClient(&stream->pcpp, ipAddr, port, timeout));
|
|
stream->err = pcpa_err;
|
|
if (pcpa_err == e_pcpa_to) {
|
|
stream->state = pcpa_state_none;
|
|
}
|
|
return pcpa_err;
|
|
}
|
|
|
|
e_pcpa_t pcpaAccessClient(pcpa_t *stream, timeout_t timeout) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPA stream isn't set");
|
|
return e_pcpa_stream_unset;
|
|
}
|
|
|
|
amtime_t start, now;
|
|
e_pcpp_t pcpa_err;
|
|
|
|
amiTimerGet(&start);
|
|
stream->state = pcpa_state_send_request_table;
|
|
|
|
pcpa_err =
|
|
_pcpaGetErrorFromPcpp(pcppSendRequestTable(&stream->pcpp, &stream->send_data, timeout));
|
|
stream->err = pcpa_err;
|
|
if (pcpa_err != e_pcpa_to) stream->state = pcpa_state_none;
|
|
|
|
if (pcpa_err != e_pcpa_ok) return pcpa_err;
|
|
|
|
if (pcpa_err == 0) {
|
|
stream->state = pcpa_state_12;
|
|
|
|
if (timeout != TIMEOUT_NONE) {
|
|
amiTimerGet(&now);
|
|
uint delta = amiTimerDiffMsec(&start, &now);
|
|
if (delta < timeout) {
|
|
timeout -= delta;
|
|
} else {
|
|
timeout = 0;
|
|
}
|
|
}
|
|
|
|
pcpa_err =
|
|
_pcpaGetErrorFromPcpp(pcppRecvResponse(&stream->pcpp, &stream->recv_data, timeout));
|
|
stream->err = pcpa_err;
|
|
if (pcpa_err != e_pcpa_to) stream->state = pcpa_state_none;
|
|
}
|
|
return pcpa_err;
|
|
}
|