2058 lines
73 KiB
C
2058 lines
73 KiB
C
#include "pcpp.h"
|
|
|
|
int FUN_00459d00(amtime_t* t1, amtime_t* t2) {
|
|
if (t1 == NULL || t2 == NULL) return -1;
|
|
return ((t2->seconds - t1->seconds) * 1000000 - t1->microseconds) +
|
|
t2->microseconds; // Swapped
|
|
}
|
|
|
|
// TODO: Invert these conditions to be clearer
|
|
int pcppIsValidDataChar(char chr) {
|
|
if (isalnum(chr) || chr == '.' || chr == '_' || chr == '-' || chr == ':' || chr == '@' ||
|
|
chr == '%' || chr == '/' || chr == '\\' || chr == '#' || chr == '{' || chr == '}') {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
e_pcpp_t _pcppGetErrorFromPcpt(int err) {
|
|
switch (err) {
|
|
case e_pcpt_ok:
|
|
return e_pcpp_ok;
|
|
case e_pcpt_to:
|
|
return e_pcpp_to;
|
|
case e_pcpt_closed:
|
|
return e_pcpp_closed;
|
|
case e_pcpt_no_client:
|
|
return e_pcpp_no_client;
|
|
case e_pcpt_wsa_noinit:
|
|
return e_pcpp_wsa_noinit;
|
|
case e_pcpt_recv_unset:
|
|
return e_pcpp_recv_unset;
|
|
case e_pcpt_NO_IDEA_WHAT_THIS_IS:
|
|
return (e_pcpp_t)-7;
|
|
case e_pcpt_inval_addr:
|
|
return e_pcpp_inval_addr;
|
|
case -11:
|
|
case e_pcpt_wsa2_generic:
|
|
case e_pcpt_nobufs:
|
|
case e_pcpt_cannot_open:
|
|
return e_pcpp_cannot_open;
|
|
case -7:
|
|
case e_pcpt_pointer_unset:
|
|
case e_pcpt_already_connected:
|
|
return e_pcpp_param_invalid;
|
|
case -6:
|
|
case e_pcpt_not_open:
|
|
return e_pcpp_not_open;
|
|
case -5:
|
|
case e_pcpt_already_open:
|
|
return e_pcpp_already_open;
|
|
default:
|
|
return e_pcpp_unknown;
|
|
}
|
|
}
|
|
|
|
bool pcppCheckPrompt(pcpp_t* stream) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return false;
|
|
}
|
|
|
|
uint max = stream->read_bytes_num;
|
|
bool found = false;
|
|
|
|
for (uint cursor = 0; cursor < max; cursor++) {
|
|
char* pos = stream->read_bytes_buf + cursor;
|
|
if (stream->read_bytes_buf[cursor] == '>') {
|
|
if (cursor < stream->read_bytes_num) {
|
|
do {
|
|
*pos = pos[1];
|
|
pos++;
|
|
} while (pos + (-204 - (int)stream) < (char*)stream->read_bytes_num);
|
|
}
|
|
|
|
stream->read_bytes_num--;
|
|
stream->read_bytes_size++;
|
|
found = true;
|
|
}
|
|
}
|
|
|
|
return found;
|
|
}
|
|
|
|
e_pcpp_t pcppCheckRecvMsg(char* recv_data, size_t buf_len, int param_3) {
|
|
bool bVar1 = true;
|
|
|
|
if (recv_data == NULL) {
|
|
amiDebugLog("pointer error");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
|
|
int check_offset = 0;
|
|
while (1) {
|
|
check_offset = buf_len - check_offset;
|
|
uint recv_err = pcppRecvCheck(recv_data, &check_offset);
|
|
|
|
if (recv_err == 1) return e_pcpp_param_invalid;
|
|
if (recv_err == 8) {
|
|
if (!bVar1) return e_pcpp_param_invalid;
|
|
if (param_3 != 0) return e_pcpp_param_invalid;
|
|
} else {
|
|
if (recv_err == 7 && !bVar1) return e_pcpp_param_invalid;
|
|
}
|
|
|
|
recv_data += check_offset;
|
|
check_offset++;
|
|
bVar1 = false;
|
|
|
|
if (recv_err == 0 || recv_err == 6 || recv_err == 7 || recv_err == 8) {
|
|
return e_pcpp_ok;
|
|
}
|
|
}
|
|
}
|
|
|
|
pcpp_char_type_t pcppCheckStr(char* recv_data, uint* found_at, int* is_qmark) {
|
|
bool end = false;
|
|
bool saw_data = false;
|
|
uint idx = 0;
|
|
|
|
if (recv_data == NULL || is_qmark == NULL || found_at == NULL) {
|
|
amiDebugLog("pointer error");
|
|
return pcpp_char_error;
|
|
}
|
|
|
|
*is_qmark = 0;
|
|
if (*found_at == 0) {
|
|
amiDebugLog("stream exhausted");
|
|
return pcpp_char_error;
|
|
}
|
|
|
|
do {
|
|
char chr = recv_data[idx];
|
|
if (PCP_WHITESPACE(chr)) {
|
|
if (saw_data) end = true;
|
|
} else if (pcppIsValidDataChar(chr)) {
|
|
if (end || *is_qmark != 0) {
|
|
*found_at = idx + 1;
|
|
return pcpp_char_error;
|
|
}
|
|
saw_data = true;
|
|
} else if (chr == PCP_CHAR_QMARK) {
|
|
if (saw_data || end) {
|
|
*found_at = idx + 1;
|
|
return pcpp_char_error;
|
|
}
|
|
|
|
*is_qmark = 1;
|
|
} else {
|
|
*found_at = idx + 1;
|
|
switch (chr) {
|
|
case PCP_CHAR_SEP:
|
|
return pcpp_char_sep;
|
|
case PCP_CHAR_CR:
|
|
if (recv_data[idx + 1] != '\n') return pcpp_char_crlf;
|
|
*found_at = idx + 2;
|
|
return pcpp_char_cr;
|
|
case PCP_CHAR_LF:
|
|
return pcpp_char_lf;
|
|
case PCP_CHAR_EQU:
|
|
return pcpp_char_equ;
|
|
default:
|
|
return pcpp_char_error;
|
|
}
|
|
}
|
|
|
|
idx++;
|
|
if (*found_at <= idx) return pcpp_char_error;
|
|
} while (true);
|
|
}
|
|
|
|
void pcppClose(pcpp_t* stream) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return;
|
|
}
|
|
|
|
pcptClose(&stream->sock);
|
|
pcptClose(&stream->data_sock);
|
|
|
|
stream->field_0xb8 = 0;
|
|
stream->last_active = 0;
|
|
stream->state = pcpp_state_none;
|
|
stream->err = e_pcpp_unknown;
|
|
stream->recv_data_buffer = NULL;
|
|
memset(stream->read_bytes_buf, 0, sizeof stream->read_bytes_buf);
|
|
stream->read_bytes_size = sizeof stream->read_bytes_buf;
|
|
stream->read_bytes_num = 0;
|
|
stream->resp_buffer = NULL;
|
|
ZERO(stream->send_buf);
|
|
stream->send_buf_len = PCP_SEND_BUF_MAX;
|
|
stream->field_0x1e8 = 0;
|
|
stream->send_binary_buf = NULL;
|
|
stream->field_0x1f0 = 0;
|
|
stream->recv_binary_buf = NULL;
|
|
stream->field_0x1f8 = 0;
|
|
stream->recv_binary_buf_len = 0;
|
|
stream->field_0x1fc = 0;
|
|
stream->open = 0;
|
|
stream->field_0x214 = 0;
|
|
}
|
|
|
|
void pcppCloseBinary(pcpp_t* stream) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return;
|
|
}
|
|
|
|
pcptCloseDataSock(&stream->data_sock);
|
|
stream->read_bytes_size = sizeof stream->read_bytes_buf;
|
|
stream->read_bytes_num = 0;
|
|
memset(stream->read_bytes_buf, 0, sizeof stream->read_bytes_buf);
|
|
stream->resp_buffer = NULL;
|
|
|
|
amtime_t time;
|
|
amiTimerGet(&time);
|
|
stream->last_active = _amTimeMs(time);
|
|
stream->state = pcpp_state_none;
|
|
}
|
|
|
|
e_pcpp_t pcppGetBlockingTime(uint param_1, timeout_t timeout, pcpp_t* stream, int param_4,
|
|
uint* blocking_time) {
|
|
byte bVar1;
|
|
uint uVar2;
|
|
uint uVar3;
|
|
amtime_t local_8;
|
|
|
|
if (stream == NULL || blocking_time == NULL) {
|
|
amiDebugLog("pointer error");
|
|
return 0;
|
|
}
|
|
|
|
amiTimerGet(&local_8);
|
|
uVar2 =
|
|
(local_8.seconds * 1000 - stream->last_active) + local_8.microseconds / 1000; // swapped
|
|
if (param_1 <= uVar2) {
|
|
*blocking_time = 0;
|
|
return 1;
|
|
}
|
|
if ((timeout == TIMEOUT_NONE) || (param_1 - uVar2 < (uint)timeout)) {
|
|
bVar1 = 1;
|
|
uVar2 = param_1 - uVar2;
|
|
} else {
|
|
bVar1 = 0;
|
|
uVar2 = timeout;
|
|
}
|
|
uVar3 = (local_8.seconds * 1000 - param_4) + local_8.microseconds / 1000; // Swapped
|
|
if (timeout != TIMEOUT_NONE) {
|
|
if ((uint)timeout <= uVar3) {
|
|
*blocking_time = 0;
|
|
return 0;
|
|
}
|
|
uVar3 = timeout - uVar3;
|
|
if (uVar3 < uVar2) {
|
|
*blocking_time = uVar3;
|
|
return 0;
|
|
}
|
|
}
|
|
*blocking_time = uVar2;
|
|
return (uint)bVar1;
|
|
}
|
|
|
|
char* pcppGetCommand(pcp_parse_data_t* recv_data, char* command) {
|
|
if (recv_data == NULL || command == NULL) {
|
|
amiDebugLog("error Recv Data isn't set");
|
|
return NULL;
|
|
}
|
|
|
|
for (uint cmd = 0; cmd < recv_data->cmd_count; cmd++) {
|
|
if (!strcmp(recv_data->strings + recv_data->keywords[cmd], command)) {
|
|
if (recv_data->values[cmd] == 0) return NULL;
|
|
return recv_data->strings + recv_data->values[cmd];
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
char* pcppGetKeyword(pcp_parse_data_t* recvData, uint keywordNum) {
|
|
if (recvData == NULL) {
|
|
amiDebugLog("error Recv Data isn't set");
|
|
return NULL;
|
|
}
|
|
|
|
if ((keywordNum >= PCP_CMDS_MAX) && (keywordNum > recvData->cmd_count)) {
|
|
amiDebugLog("error keywordNum over");
|
|
return NULL;
|
|
}
|
|
return recvData->strings + recvData->keywords[keywordNum];
|
|
}
|
|
|
|
SOCKET pcppGetServerSocket(pcpp_t* stream, int which) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return SOCKET_INVAL;
|
|
}
|
|
|
|
switch (which) {
|
|
case 0:
|
|
return (stream->sock).server_sock;
|
|
case 1:
|
|
return (stream->data_sock).server_sock;
|
|
default:
|
|
return SOCKET_INVAL;
|
|
}
|
|
}
|
|
|
|
e_pcpp_t pcppInitStream(pcpp_t* stream) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error don't set stream");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
|
|
e_pcpt_t err = pcptInitStream(&stream->sock);
|
|
if (err != e_pcpt_ok) return _errT2P(err);
|
|
|
|
err = pcptInitStream(&stream->data_sock);
|
|
if (err != e_pcpt_ok) return _errT2P(err);
|
|
|
|
pcptSetConfig(&stream->data_sock, PCPT_TCP_NODELAY, 1);
|
|
|
|
stream->field_0xb8 = 0;
|
|
stream->last_active = 0;
|
|
stream->state = pcpp_state_none;
|
|
stream->err = e_pcpp_unknown;
|
|
stream->recv_data_buffer = NULL;
|
|
ZERO(stream->read_bytes_buf);
|
|
// memset(stream->read_bytes_buf, 0, sizeof stream->read_bytes_buf);
|
|
stream->read_bytes_size = sizeof stream->read_bytes_buf;
|
|
stream->read_bytes_num = 0;
|
|
stream->resp_buffer = NULL;
|
|
ZERO(stream->send_buf);
|
|
stream->field_0x1e8 = 0;
|
|
stream->send_binary_buf = NULL;
|
|
stream->field_0x1f0 = 0;
|
|
stream->recv_binary_buf = NULL;
|
|
stream->field_0x1f8 = 0;
|
|
stream->recv_binary_buf_len = 0;
|
|
stream->field_0x1fc = 0;
|
|
stream->open = 0;
|
|
stream->field_0x214 = 0;
|
|
stream->field_0x20c = 10000;
|
|
stream->field_0x208 = 10000;
|
|
stream->send_buf_len = PCP_SEND_BUF_MAX;
|
|
stream->field_0x204 = 1000;
|
|
stream->field_0x210 = 60000;
|
|
return e_pcpp_ok;
|
|
}
|
|
|
|
e_pcpp_t pcppOpenClient(pcpp_t* stream, char* ipAddr, ushort port, uint param_4,
|
|
timeout_t timeout) {
|
|
e_pcpp_t iVar1;
|
|
uint uVar3;
|
|
amtime_t start;
|
|
amtime_t now;
|
|
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
if (ipAddr == NULL) {
|
|
amiDebugLog("error IpAddr isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
|
|
stream->state = pcpp_state_open;
|
|
stream->field_0xb8 = param_4;
|
|
stream->open = 0;
|
|
amiTimerGet(&start);
|
|
iVar1 = start.microseconds / 1000 + start.seconds * 1000;
|
|
stream->last_active = iVar1;
|
|
e_pcpp_t err = pcppGetBlockingTime(stream->field_0x210, timeout, stream, iVar1, &timeout);
|
|
e_pcpp_t err2 = _pcppGetErrorFromPcpt(pcptOpenClient(&stream->sock, ipAddr, port, timeout));
|
|
stream->err = err2;
|
|
if (err2 == e_pcpp_to) {
|
|
if (err == e_pcpp_ok) {
|
|
return e_pcpp_to;
|
|
}
|
|
stream->err = e_pcpp_no_server;
|
|
amiDebugLog("error Time out error");
|
|
}
|
|
if (stream->err == 0) {
|
|
amiTimerGet(&now);
|
|
stream->last_active = now.microseconds / 1000 + now.seconds * 1000;
|
|
if (timeout != TIMEOUT_NONE) {
|
|
uVar3 = (now.microseconds - start.microseconds) / 1000 +
|
|
(now.seconds - start.seconds) * 1000;
|
|
if (uVar3 < timeout) {
|
|
timeout -= uVar3;
|
|
} else {
|
|
timeout = 0;
|
|
}
|
|
}
|
|
stream->open = 1;
|
|
stream->state = pcpp_state_wait_prompt;
|
|
err = pcppRecvPrompt(stream, stream->field_0xb8, timeout);
|
|
stream->err = err;
|
|
if ((err == e_pcpp_to) || (stream->state = pcpp_state_none, err == e_pcpp_ok))
|
|
goto LAB_00a16a90;
|
|
pcptCloseDataSock(&stream->sock);
|
|
pcppResetRead(stream);
|
|
err = stream->err;
|
|
amiDebugLog("error pcppRecvPrompt error = %d", err);
|
|
} else {
|
|
pcptCloseDataSock(&stream->sock);
|
|
pcppResetRead(stream);
|
|
stream->state = pcpp_state_none;
|
|
err = stream->err;
|
|
amiDebugLog("error pcptOpenClient error = %d", err);
|
|
}
|
|
LAB_00a16a90:
|
|
return stream->err;
|
|
}
|
|
|
|
e_pcpp_t pcppOpenBinaryServer(pcpp_t* stream, int open_mode, ushort port) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
|
|
amtime_t time;
|
|
amiTimerGet(&time);
|
|
stream->last_active = _amTimeMs(time);
|
|
stream->state = pcpp_state_none;
|
|
if (open_mode != 0 && open_mode != 1) {
|
|
amiDebugLog("error Open Mode isn't set");
|
|
stream->state = pcpp_state_none;
|
|
return stream->err = e_pcpp_param_invalid;
|
|
}
|
|
|
|
e_pcpp_t err = _errT2P(pcptOpenServer(&stream->data_sock, open_mode, port));
|
|
stream->err = err;
|
|
if (err != e_pcpp_ok) {
|
|
amiDebugLog("error pcptOpenBinaryServer");
|
|
return err;
|
|
}
|
|
|
|
amiTimerGet(&time);
|
|
stream->last_active = _amTimeMs(time);
|
|
return e_pcpp_ok;
|
|
}
|
|
|
|
e_pcpp_t pcppOpenBinaryClient(pcpp_t* stream, char* ipAddr, ushort port, timeout_t timeout) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
if (ipAddr == NULL) {
|
|
amiDebugLog("error IpAddr isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
stream->state = pcpp_state_open_binary;
|
|
|
|
amtime_t time;
|
|
amiTimerGet(&time);
|
|
stream->last_active = _amTimeMs(time);
|
|
|
|
bool bVar1 = false;
|
|
if (timeout == TIMEOUT_NONE ||
|
|
(stream->field_0x210 <= timeout && timeout != stream->field_0x210)) {
|
|
bVar1 = true;
|
|
}
|
|
|
|
e_pcpp_t pcpp_err =
|
|
_pcppGetErrorFromPcpt(pcptOpenClient(&stream->data_sock, ipAddr, port, timeout));
|
|
stream->err = pcpp_err;
|
|
if (pcpp_err == e_pcpp_to && bVar1) {
|
|
stream->err = e_pcpp_no_server;
|
|
pcptCloseDataSock(&stream->sock);
|
|
pcppResetRead(stream);
|
|
}
|
|
|
|
if (stream->err != e_pcpp_to) stream->state = pcpp_state_none;
|
|
if (stream->err == e_pcpp_ok) {
|
|
amiTimerGet(&time);
|
|
stream->last_active = _amTimeMs(time);
|
|
}
|
|
return stream->err;
|
|
}
|
|
|
|
e_pcpp_t pcppOpenServer(pcpp_t* stream, int open_mode, u_short port, undefined4 param_4) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
stream->field_0xb8 = param_4;
|
|
if (open_mode != 0 && open_mode != 1) {
|
|
amiDebugLog("error Open Mode isn't set");
|
|
|
|
stream->err = e_pcpp_param_invalid;
|
|
stream->state = pcpp_state_none;
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
|
|
e_pcpp_t err = _errT2P(pcptOpenServer(&stream->sock, open_mode, port));
|
|
stream->err = err;
|
|
if (err != e_pcpp_ok) {
|
|
amiDebugLog("error pcppOpenServer error = %d", err);
|
|
return err;
|
|
}
|
|
stream->open = 1;
|
|
|
|
amtime_t time;
|
|
amiTimerGet(&time);
|
|
stream->last_active = _amTimeMs(time);
|
|
return e_pcpp_ok;
|
|
}
|
|
|
|
pcp_send_data_t* pcppSetSendPacket(pcp_send_data_t* send_data, char* keyword, char* value) {
|
|
if (send_data == NULL || keyword == NULL) {
|
|
amiDebugLog("error Send Data isn't set");
|
|
return NULL;
|
|
}
|
|
|
|
memset(send_data->data, 0, sizeof *send_data->data);
|
|
send_data->length = 0;
|
|
size_t kwLen = strlen(keyword);
|
|
|
|
if (value == NULL) {
|
|
if (kwLen + 2 < PCP_BUF_MAX) {
|
|
sprintf_s((char*)send_data->data, PCP_BUF_MAX, "%s\r\n", keyword);
|
|
send_data->length = kwLen & 0xff;
|
|
return send_data;
|
|
}
|
|
} else {
|
|
size_t valLen = strlen(value);
|
|
if (kwLen + 3 + valLen < PCP_BUF_MAX) {
|
|
sprintf_s((char*)send_data->data, PCP_BUF_MAX, "%s=%s\r\n", keyword, value);
|
|
send_data->length = kwLen + 1 + valLen;
|
|
return send_data;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
uint pcppRecvCheck(char* buf, int* offset) {
|
|
if (buf == NULL || offset == NULL) {
|
|
amiDebugLog("pointer error");
|
|
return 1;
|
|
}
|
|
|
|
uint total_length = *offset;
|
|
*offset = 0;
|
|
|
|
uint local_offset = 0;
|
|
|
|
/**
|
|
* The following are the patterns this function validates against:
|
|
*
|
|
* * ? [equ ] -> 1 NG eg ?=
|
|
* * . [sep ] -> 3 -> eg keychip.version&
|
|
* * ? [sep ] -> 5 -> eq ?&
|
|
* * . [crlf] -> 6 OK eg keychip.version\r\n
|
|
* * ? [crlf] -> 8 OK eg ?\r\n
|
|
* * . [equ ] -> continue \/ eg keychip.version=
|
|
*
|
|
* * . [equ ] . [crlf] -> 0 OK eg keychip.version=1\r\n
|
|
* * . [equ ] * [equ ] -> 1 NG eg keychip.version=1=
|
|
* * . [equ ] . [sep ] -> 2 -> eg keychip.version=1&
|
|
* * . [equ ] ? [sep ] -> 4 -> eg keychip.version=?&
|
|
* * . [equ ] ? [crlf] -> 7 OK eg keychip.version=?\r\n
|
|
*/
|
|
|
|
for (int is_value = 0; is_value < 2; is_value++) {
|
|
uint nbytes = total_length - local_offset;
|
|
int is_qmark = 0;
|
|
pcpp_char_type_t char_type = pcppCheckStr(&buf[local_offset], &nbytes, &is_qmark);
|
|
*offset += nbytes;
|
|
|
|
switch (char_type) {
|
|
case pcpp_char_error:
|
|
return 1;
|
|
|
|
case pcpp_char_equ:
|
|
if (is_value) return 1;
|
|
local_offset = nbytes;
|
|
if (is_qmark) return 1;
|
|
break;
|
|
|
|
case pcpp_char_lf:
|
|
case pcpp_char_crlf:
|
|
case pcpp_char_cr:
|
|
if (is_value) return is_qmark ? 7 : 0;
|
|
return is_qmark ? 8 : 6;
|
|
|
|
case pcpp_char_sep:
|
|
if (is_value) return is_qmark ? 4 : 2;
|
|
return is_qmark ? 5 : 3;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
e_pcpp_t pcppSendResponseTable(pcpp_t* stream, pcp_send_data_t* data, timeout_t timeout_ms) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
if (data == NULL) {
|
|
amiDebugLog("error Response buffer isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
|
|
return pcppSendResponse(stream, data, data->length + 2, timeout_ms);
|
|
}
|
|
|
|
e_pcpp_t pcppSendResponse(pcpp_t* stream, pcp_send_data_t* resp_buffer, size_t buf_len,
|
|
timeout_t timeout_ms)
|
|
|
|
{
|
|
e_pcpp_t err;
|
|
amtime_t time;
|
|
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
if (resp_buffer == NULL) {
|
|
amiDebugLog("error Response buffer isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
|
|
if (buf_len > PCP_BUF_MAX - 1) {
|
|
amiDebugLog("error Response buffer over");
|
|
return stream->err = e_pcpp_param_invalid;
|
|
}
|
|
|
|
amiTimerGet(&time);
|
|
stream->err = err = pcppCheckRecvMsg((char*)resp_buffer->data, buf_len, 0);
|
|
|
|
if (err != e_pcpp_ok) {
|
|
stream->state = pcpp_state_none;
|
|
pcppResetRead(stream);
|
|
amiDebugLog("error Send message format error");
|
|
printf("'%s'\n", resp_buffer->data);
|
|
return stream->err;
|
|
}
|
|
|
|
resp_buffer->length = buf_len;
|
|
stream->resp_buffer = resp_buffer;
|
|
stream->state = pcpp_state_send_response;
|
|
err = pcpp_something(&time, timeout_ms, stream, &stream->sock, resp_buffer->data,
|
|
&resp_buffer->length, stream->field_0x204, stream->field_0x210, -6);
|
|
stream->err = err;
|
|
if (err != e_pcpp_to) {
|
|
stream->state = pcpp_state_none;
|
|
if (err != e_pcpp_ok) {
|
|
pcptCloseDataSock(&stream->sock);
|
|
pcppResetRead(stream);
|
|
}
|
|
}
|
|
amiTimerGet(&time);
|
|
stream->last_active = _amTimeMs(time);
|
|
return stream->err;
|
|
}
|
|
|
|
void pcppResetRead(pcpp_t* stream) {
|
|
stream->read_bytes_size = PCP_BUF_MAX;
|
|
stream->read_bytes_num = 0;
|
|
ZERO_BUF(stream->read_bytes_buf);
|
|
stream->resp_buffer = NULL;
|
|
}
|
|
|
|
e_pcpp_t pcppRecvRequest(pcpp_t* stream, pcp_parse_data_t* recv_data, timeout_t timeout) {
|
|
e_pcpp_t err;
|
|
uint timeout_ms = timeout;
|
|
undefined4 uVar1;
|
|
amtime_t now;
|
|
amtime_t start;
|
|
amtime_t now2;
|
|
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
if (recv_data == NULL) {
|
|
amiDebugLog("error Request buffer isn't set");
|
|
return stream->err = e_pcpp_param_invalid;
|
|
}
|
|
|
|
if ((stream->sock).open == PCPT_LISTENING) {
|
|
uVar1 = stream->field_0x210;
|
|
} else {
|
|
uVar1 = stream->field_0xb8;
|
|
}
|
|
stream->recv_data_buffer = recv_data;
|
|
amiTimerGet(&start);
|
|
stream->state = pcpp_state_send_prompt;
|
|
err = pcppSendPrompt(stream, uVar1, timeout_ms);
|
|
stream->err = err;
|
|
if (err != e_pcpp_to) {
|
|
stream->state = pcpp_state_none;
|
|
}
|
|
if (err == e_pcpp_ok) {
|
|
stream->open = 0;
|
|
amiTimerGet(&now);
|
|
stream->last_active = _amTimeMs(now);
|
|
stream->state = pcpp_state_recv_request;
|
|
if (timeout_ms != TIMEOUT_NONE) {
|
|
uint elapsed = _amTimeDelta(now, start);
|
|
if (elapsed < timeout_ms) {
|
|
timeout_ms = timeout_ms - elapsed;
|
|
} else {
|
|
timeout_ms = 0;
|
|
}
|
|
}
|
|
|
|
bool bReRecv;
|
|
err = pcppRecvRequestMain(stream, &bReRecv, timeout_ms);
|
|
stream->err = err;
|
|
if (err == e_pcpp_to) {
|
|
if (bReRecv) {
|
|
stream->state = 14;
|
|
return e_pcpp_to;
|
|
}
|
|
} else {
|
|
stream->state = pcpp_state_none;
|
|
if (err == e_pcpp_ok) {
|
|
amiTimerGet(&now2);
|
|
stream->last_active = _amTimeMs(now2);
|
|
}
|
|
}
|
|
err = stream->err;
|
|
}
|
|
return err;
|
|
}
|
|
|
|
e_pcpp_t pcppRecvRequestMain(pcpp_t* stream, bool* bReRecv, undefined4 timeout) {
|
|
char* recv_data;
|
|
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
|
|
stream->field_0x214 = 0;
|
|
|
|
e_pcpp_t err = pcppRecvAllMsg(stream, timeout, bReRecv);
|
|
if (err != e_pcpp_ok) return err;
|
|
|
|
recv_data = stream->read_bytes_buf;
|
|
if (pcppCheckRecvMsg(recv_data, stream->read_bytes_num, 1) != e_pcpp_ok) {
|
|
pcppResetRead(stream);
|
|
return -9;
|
|
}
|
|
|
|
uint local_4 = 0;
|
|
pcppChangeRequest(stream, &local_4);
|
|
|
|
if (local_4 < stream->read_bytes_num)
|
|
memcpy(recv_data + local_4, recv_data, stream->read_bytes_num);
|
|
|
|
stream->read_bytes_num -= local_4;
|
|
stream->read_bytes_size += local_4;
|
|
stream->read_bytes_buf[stream->read_bytes_num] = '\0';
|
|
return e_pcpp_ok;
|
|
}
|
|
|
|
e_pcpp_t pcppSendPrompt(pcpp_t* stream, uint param_2, timeout_t timeout_ms) {
|
|
amtime_t now;
|
|
|
|
bool has_timeout = false;
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
|
|
amiTimerGet(&now);
|
|
uint since_open = _amTimeMs(now) - stream->last_active;
|
|
if (since_open > param_2) {
|
|
timeout_ms = 0;
|
|
} else {
|
|
if ((timeout_ms != -1) && ((uint)timeout_ms <= param_2 - since_open)) goto LAB_00456133;
|
|
timeout_ms = param_2 - since_open;
|
|
}
|
|
has_timeout = true;
|
|
LAB_00456133:
|
|
size_t* send_len = &stream->send_buf_len;
|
|
stream->send_buf[0] = '>';
|
|
*send_len = 1;
|
|
if ((stream->sock).open == PCPT_LISTENING) stream->open = 1;
|
|
|
|
e_pcpp_t err = _errT2P(pcptSend(&stream->sock, (unsigned char*)stream->send_buf, send_len,
|
|
stream->field_0x204, timeout_ms));
|
|
|
|
if (has_timeout && err == e_pcpp_to) {
|
|
err = stream->open ? -12 : -6;
|
|
pcptCloseDataSock(&stream->sock);
|
|
pcppResetRead(stream);
|
|
if (stream->open == 0) amiDebugLog("Error : Time out error");
|
|
}
|
|
amiTimerGet(&now);
|
|
stream->last_active = _amTimeMs(now);
|
|
return err;
|
|
}
|
|
|
|
e_pcpp_t pcppRecvAllMsg(pcpp_t* stream, uint param_1, bool* bReRecv) {
|
|
uint* recv_buf_len;
|
|
int iVar1;
|
|
e_pcpt_t err;
|
|
e_pcpp_t eVar2;
|
|
undefined4 uVar3;
|
|
uint local_14;
|
|
amtime_t local_10;
|
|
amtime_t local_8;
|
|
|
|
local_14 = param_1;
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
|
|
if (bReRecv == NULL) {
|
|
amiDebugLog("error bReRecv isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
*bReRecv = false;
|
|
amiTimerGet(&local_10);
|
|
if (stream->read_bytes_num != 0) {
|
|
for (size_t i = 0; i < stream->read_bytes_num; i++) {
|
|
if (stream->read_bytes_buf[i] == '\r' || stream->read_bytes_buf[i] == '\n') {
|
|
stream->field_0x214 = 0;
|
|
return e_pcpp_ok;
|
|
}
|
|
}
|
|
}
|
|
uVar3 = stream->field_0x214 == 0 ? stream->field_0xb8 : stream->field_0x204;
|
|
|
|
iVar1 = pcppGetBlockingTime(uVar3, param_1, stream, _amTimeMs(local_10), &local_14);
|
|
recv_buf_len = &stream->read_bytes_size;
|
|
*recv_buf_len = PCP_BUF_MAX - stream->read_bytes_num;
|
|
eVar2 = _errT2P(pcptRecv(&stream->sock,
|
|
(unsigned char*)(stream->read_bytes_buf + stream->read_bytes_num),
|
|
recv_buf_len, local_14));
|
|
if (eVar2 == e_pcpp_to) {
|
|
if (iVar1 == 0) return e_pcpp_to;
|
|
|
|
eVar2 = e_pcpp_timeout_closed - (uint)(stream->field_0x214 != 0);
|
|
pcptCloseDataSock(&stream->sock);
|
|
*recv_buf_len = PCP_BUF_MAX;
|
|
stream->read_bytes_num = 0;
|
|
ZERO_BUF(stream->read_bytes_buf);
|
|
stream->resp_buffer = NULL;
|
|
}
|
|
if (eVar2 != e_pcpp_ok) {
|
|
return eVar2;
|
|
}
|
|
stream->read_bytes_num = stream->read_bytes_num + *recv_buf_len;
|
|
*recv_buf_len = PCP_BUF_MAX - stream->read_bytes_num;
|
|
amiTimerGet(&local_8);
|
|
stream->last_active = _amTimeMs(local_8);
|
|
stream->field_0x214 = 1;
|
|
*bReRecv = true;
|
|
|
|
if (stream->read_bytes_num != 0) {
|
|
for (size_t i = 0; i < stream->read_bytes_num; i++) {
|
|
if (stream->read_bytes_buf[i] == '\r' || stream->read_bytes_buf[i] == '\n') {
|
|
*bReRecv = false;
|
|
stream->field_0x214 = 0;
|
|
return e_pcpp_ok;
|
|
}
|
|
}
|
|
}
|
|
return e_pcpp_to;
|
|
}
|
|
|
|
pcp_parse_data_t* pcppChangeRequest(pcpp_t* stream, uint* lenout) {
|
|
if (stream == NULL || lenout == NULL) {
|
|
amiDebugLog("pointer error");
|
|
return NULL;
|
|
}
|
|
|
|
if (stream->recv_data_buffer == NULL) {
|
|
amiDebugLog("don't set recvData buffer");
|
|
return NULL;
|
|
}
|
|
|
|
if (stream->read_bytes_num > PCP_BUF_MAX) {
|
|
amiDebugLog("Buffer size error");
|
|
return NULL;
|
|
}
|
|
|
|
ZERO_BUF(stream->recv_data_buffer->strings);
|
|
ZERO_BUF(stream->recv_data_buffer->keywords);
|
|
ZERO_BUF(stream->recv_data_buffer->values);
|
|
|
|
stream->recv_data_buffer->keywords[0] = 0;
|
|
stream->recv_data_buffer->cmd_count = 1;
|
|
|
|
if (stream->read_bytes_num == 0) {
|
|
*lenout = 1;
|
|
return stream->recv_data_buffer;
|
|
}
|
|
|
|
bool comment = false;
|
|
byte string_idx = 0;
|
|
size_t i;
|
|
for (i = 0; i < stream->read_bytes_num; i++) {
|
|
char chr = stream->read_bytes_buf[i];
|
|
|
|
if (chr == PCP_CHAR_CR || chr == PCP_CHAR_LF) {
|
|
stream->recv_data_buffer->strings[string_idx] = PCP_CHAR_EOF;
|
|
if (i + 1 < stream->read_bytes_num && stream->read_bytes_buf[i] == PCP_CHAR_CR &&
|
|
stream->read_bytes_buf[i + 1] == PCP_CHAR_LF)
|
|
i++;
|
|
|
|
*lenout = i + 1;
|
|
return stream->recv_data_buffer;
|
|
}
|
|
|
|
if (comment) {
|
|
if (chr == PCP_CHAR_HASH) comment = false;
|
|
continue;
|
|
}
|
|
|
|
switch (chr) {
|
|
case PCP_CHAR_QMARK:
|
|
stream->recv_data_buffer->strings[string_idx++] = PCP_CHAR_QMARK;
|
|
break;
|
|
case PCP_CHAR_SEP:
|
|
if (stream->recv_data_buffer->cmd_count > PCP_CMDS_MAX) {
|
|
amiDebugLog("Buffer size error");
|
|
return NULL;
|
|
}
|
|
stream->recv_data_buffer->strings[string_idx] = PCP_CHAR_EOF;
|
|
stream->recv_data_buffer->keywords[stream->recv_data_buffer->cmd_count] =
|
|
++string_idx;
|
|
stream->recv_data_buffer->cmd_count++;
|
|
break;
|
|
case PCP_CHAR_EQU:
|
|
if (stream->recv_data_buffer->cmd_count > PCP_CMDS_MAX) {
|
|
amiDebugLog("Buffer size error");
|
|
return NULL;
|
|
}
|
|
stream->recv_data_buffer->strings[string_idx] = PCP_CHAR_EOF;
|
|
stream->recv_data_buffer
|
|
->keywords[stream->recv_data_buffer->cmd_count + PCP_CMDS_MAX - 1] =
|
|
++string_idx;
|
|
break;
|
|
case PCP_CHAR_HASH:
|
|
comment = true;
|
|
break;
|
|
default:
|
|
if (pcppIsValidDataChar(chr))
|
|
stream->recv_data_buffer->strings[string_idx++] = stream->read_bytes_buf[i];
|
|
}
|
|
}
|
|
*lenout = i + 1;
|
|
return stream->recv_data_buffer;
|
|
}
|
|
|
|
int pcppRecvPrompt(pcpp_t* stream, undefined4 param_2, int param_3) {
|
|
uint* recv_buf_len;
|
|
int iVar1;
|
|
|
|
uint local_c = param_3;
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
|
|
e_pcpp_t err;
|
|
amtime_t start;
|
|
amiTimerGet(&start);
|
|
while (true) {
|
|
if (pcppCheckPrompt(stream)) {
|
|
amiTimerGet(&start);
|
|
stream->last_active = _amTimeMs(start);
|
|
return e_pcpp_ok;
|
|
}
|
|
|
|
iVar1 = pcppGetBlockingTime(param_2, param_3, stream, _amTimeMs(start), &local_c);
|
|
recv_buf_len = &stream->read_bytes_size;
|
|
err = _errT2P(pcptRecv(&stream->sock,
|
|
(unsigned char*)(stream->read_bytes_buf + stream->read_bytes_num),
|
|
recv_buf_len, local_c));
|
|
if (err == e_pcpp_to) break;
|
|
if (err != e_pcpp_ok) {
|
|
return err;
|
|
}
|
|
stream->read_bytes_num = stream->read_bytes_num + *recv_buf_len;
|
|
uint uVar3 = PCP_BUF_MAX - stream->read_bytes_num;
|
|
*recv_buf_len = uVar3;
|
|
if (uVar3 != 0) {
|
|
stream->read_bytes_buf[stream->read_bytes_num] = '\0';
|
|
}
|
|
}
|
|
|
|
if (iVar1 != 0) {
|
|
err = stream->open ? e_pcpp_timeout_open : e_pcpp_timeout_closed;
|
|
pcptCloseDataSock(&stream->sock);
|
|
pcppResetRead(stream);
|
|
return err;
|
|
}
|
|
return err;
|
|
}
|
|
|
|
e_pcpp_t pcppSendRequestMain(pcpp_t* stream, undefined4 param_2, timeout_t timeout_ms) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
|
|
if (stream->resp_buffer == NULL) {
|
|
amiDebugLog("error Request buffer isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
|
|
amtime_t now;
|
|
amiTimerGet(&now);
|
|
|
|
e_pcpp_t eVar1 =
|
|
pcpp_something(&now, timeout_ms, stream, &stream->sock, stream->resp_buffer->data,
|
|
&stream->resp_buffer->length, stream->field_0x204, param_2,
|
|
stream->open ? e_pcpp_timeout_open : e_pcpp_timeout_closed);
|
|
|
|
if (eVar1 != e_pcpp_to && eVar1 != e_pcpp_ok) {
|
|
pcptCloseDataSock(&stream->sock);
|
|
pcppResetRead(stream);
|
|
}
|
|
amiTimerGet(&now);
|
|
stream->last_active = _amTimeMs(now);
|
|
return eVar1;
|
|
}
|
|
|
|
// TODO: MINIMAL CLEANUP DONE HERE
|
|
|
|
e_pcpp_t pcppRecvBinary(pcpp_t* stream, unsigned char* recv_buf, size_t buf_len, uint param_4) {
|
|
size_t* psVar1;
|
|
int iVar2;
|
|
e_pcpt_t eVar3;
|
|
e_pcpp_t eVar4;
|
|
undefined4 uVar5;
|
|
bool bVar6;
|
|
uint recvb_local;
|
|
amtime_t now;
|
|
amtime_t local_10;
|
|
amtime_t local_8;
|
|
|
|
recvb_local = param_4;
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
if (recv_buf == NULL) {
|
|
amiDebugLog("error Recv Bninary Buffer isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
stream->field_0x214 = 0;
|
|
amiTimerGet(&now);
|
|
psVar1 = &stream->field_0x1f8;
|
|
stream->recv_binary_buf = recv_buf;
|
|
*psVar1 = buf_len;
|
|
stream->recv_binary_buf_len = buf_len;
|
|
stream->field_0x1fc = 0;
|
|
stream->state = pcpp_state_recv_binary;
|
|
memset(recv_buf, 0, buf_len);
|
|
do {
|
|
bVar6 = (stream->data_sock).open != PCPT_LISTENING;
|
|
if (bVar6) {
|
|
uVar5 = stream->field_0x208;
|
|
} else {
|
|
amiTimerGet(&local_8);
|
|
uVar5 = stream->field_0x210;
|
|
stream->last_active = _amTimeMs(local_8);
|
|
;
|
|
}
|
|
iVar2 = pcppGetBlockingTime(uVar5, param_4, stream, _amTimeMs(now), &recvb_local);
|
|
stream->field_0x214 = 1;
|
|
eVar3 = pcptRecv(&stream->data_sock, stream->recv_binary_buf + stream->field_0x1fc, psVar1,
|
|
recvb_local);
|
|
eVar4 = _errT2P(eVar3);
|
|
stream->err = eVar4;
|
|
if ((eVar4 == e_pcpp_to) && (iVar2 != 0)) {
|
|
stream->err = bVar6 ? -13 : e_pcpp_no_server;
|
|
pcptCloseDataSock(&stream->sock);
|
|
stream->read_bytes_size = PCP_BUF_MAX;
|
|
stream->read_bytes_num = 0;
|
|
memset(stream->read_bytes_buf, 0, PCP_BUF_MAX);
|
|
stream->resp_buffer = NULL;
|
|
}
|
|
eVar4 = stream->err;
|
|
if (eVar4 == e_pcpp_to) {
|
|
LAB_00455e91:
|
|
if (eVar4 != e_pcpp_ok) {
|
|
return eVar4;
|
|
}
|
|
} else {
|
|
if (eVar4 != e_pcpp_ok) {
|
|
stream->state = pcpp_state_none;
|
|
goto LAB_00455e91;
|
|
}
|
|
}
|
|
stream->field_0x1fc = stream->field_0x1fc + *psVar1;
|
|
*psVar1 = stream->recv_binary_buf_len - stream->field_0x1fc;
|
|
stream->field_0x214 = 0;
|
|
amiTimerGet(&local_10);
|
|
stream->last_active = _amTimeMs(local_10);
|
|
if (stream->recv_binary_buf_len < stream->field_0x1fc ||
|
|
stream->recv_binary_buf_len == stream->field_0x1fc) {
|
|
unsigned char* send_buf = (unsigned char*)stream->send_buf;
|
|
psVar1 = &stream->send_buf_len;
|
|
stream->state = pcpp_state_send_binary_ack;
|
|
send_buf[0] = PCP_CHAR_BINACK;
|
|
*psVar1 = 1;
|
|
iVar2 = pcppGetBlockingTime(stream->field_0x20c, param_4, stream, _amTimeMs(now),
|
|
&recvb_local);
|
|
eVar3 = pcptSend(&stream->sock, send_buf, psVar1, stream->field_0x208,
|
|
recvb_local);
|
|
eVar4 = _errT2P(eVar3);
|
|
stream->err = eVar4;
|
|
if ((eVar4 == e_pcpp_to) && (iVar2 != 0)) {
|
|
stream->err = -14;
|
|
pcptCloseDataSock(&stream->sock);
|
|
pcppResetRead(stream);
|
|
}
|
|
eVar4 = stream->err;
|
|
if (eVar4 != e_pcpp_to) {
|
|
stream->state = pcpp_state_none;
|
|
}
|
|
if (eVar4 == e_pcpp_ok) {
|
|
amiTimerGet(&local_10);
|
|
stream->last_active = _amTimeMs(local_10);
|
|
stream->state = pcpp_state_send_binary_ack_wait;
|
|
iVar2 = pcppGetBlockingTime(stream->field_0x208, param_4, stream, _amTimeMs(now),
|
|
&recvb_local);
|
|
*psVar1 = PCP_SEND_BUF_MAX;
|
|
ZERO(stream->send_buf);
|
|
eVar3 =
|
|
pcptRecv(&stream->data_sock, send_buf, psVar1, recvb_local);
|
|
eVar4 = _errT2P(eVar3);
|
|
stream->err = eVar4;
|
|
if ((iVar2 != 0) && (eVar4 == e_pcpp_to)) {
|
|
stream->err = -13;
|
|
}
|
|
if (stream->err != e_pcpp_to) {
|
|
stream->state = pcpp_state_none;
|
|
}
|
|
if (stream->err == e_pcpp_closed) {
|
|
stream->err = e_pcpp_ok;
|
|
}
|
|
eVar4 = stream->err;
|
|
}
|
|
return eVar4;
|
|
}
|
|
} while (true);
|
|
}
|
|
|
|
e_pcpp_t pcppSendBinary(pcpp_t* stream, unsigned char* send_binary_buffer, size_t param_3,
|
|
uint param_4)
|
|
|
|
{
|
|
size_t* psVar1;
|
|
uint pVar2;
|
|
e_pcpp_t eVar3;
|
|
int iVar4;
|
|
e_pcpt_t eVar5;
|
|
uint uVar6;
|
|
uint local_14;
|
|
amtime_t local_10;
|
|
amtime_t local_8;
|
|
|
|
local_14 = param_4;
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
if (send_binary_buffer == NULL) {
|
|
amiDebugLog("error Send Bninary Buffer isn't set");
|
|
return stream->err = e_pcpp_param_invalid;
|
|
}
|
|
amiTimerGet(&local_8);
|
|
pVar2 = (stream->data_sock).open;
|
|
psVar1 = &stream->field_0x1f0;
|
|
stream->state = pcpp_state_send_binary;
|
|
*psVar1 = param_3;
|
|
stream->send_binary_buf = send_binary_buffer;
|
|
if (pVar2 == PCPT_LISTENING) {
|
|
amiTimerGet(&local_10);
|
|
stream->last_active = _amTimeMs(local_10);
|
|
eVar3 =
|
|
pcpp_something(&local_8, param_4, stream, &stream->data_sock, stream->send_binary_buf,
|
|
psVar1, stream->field_0x208, stream->field_0x210, -11);
|
|
stream->err = eVar3;
|
|
} else {
|
|
eVar5 =
|
|
pcptSend(&stream->data_sock, send_binary_buffer, psVar1, stream->field_0x208, param_4);
|
|
eVar3 = _errT2P(eVar5);
|
|
iVar4 = (stream->data_sock).field_0x54;
|
|
stream->err = eVar3;
|
|
if (iVar4 != 0) {
|
|
amiTimerGet(&local_10);
|
|
stream->last_active = _amTimeMs(local_10);
|
|
}
|
|
}
|
|
eVar3 = stream->err;
|
|
if (eVar3 != e_pcpp_to) {
|
|
stream->state = pcpp_state_none;
|
|
}
|
|
if (eVar3 == e_pcpp_ok) {
|
|
amiTimerGet(&local_10);
|
|
stream->last_active = _amTimeMs(local_10);
|
|
stream->state = pcpp_state_send_binary_wait;
|
|
psVar1 = &stream->send_buf_len;
|
|
*psVar1 = 8;
|
|
ZERO(stream->send_buf);
|
|
stream->field_0x1e8 = 0;
|
|
iVar4 = pcppGetBlockingTime(stream->field_0x20c, param_4, stream, _amTimeMs(local_8),
|
|
&local_14);
|
|
eVar5 = pcptRecv(&stream->sock, (unsigned char*)stream->send_buf, psVar1, local_14);
|
|
eVar3 = _errT2P(eVar5);
|
|
stream->err = eVar3;
|
|
if ((iVar4 != 0) && (eVar3 == e_pcpp_to)) {
|
|
stream->err = -14;
|
|
pcptCloseDataSock(&stream->sock);
|
|
pcppResetRead(stream);
|
|
}
|
|
eVar3 = stream->err;
|
|
if (eVar3 != e_pcpp_to) {
|
|
stream->state = pcpp_state_none;
|
|
}
|
|
if (eVar3 == e_pcpp_ok) {
|
|
stream->field_0x1e8 = stream->field_0x1e8 + *psVar1;
|
|
uVar6 = 0;
|
|
*psVar1 = 8 - stream->field_0x1e8;
|
|
stream->state = pcpp_state_none;
|
|
stream->err = -9;
|
|
if (stream->field_0x1e8 != 0) {
|
|
while (*(char*)((int)&stream->send_buf + uVar6) != PCP_CHAR_BINACK) {
|
|
uVar6 = uVar6 + 1;
|
|
if (stream->field_0x1e8 <= uVar6) {
|
|
return stream->err;
|
|
}
|
|
}
|
|
stream->err = e_pcpp_ok;
|
|
}
|
|
eVar3 = stream->err;
|
|
}
|
|
}
|
|
return eVar3;
|
|
}
|
|
|
|
e_pcpp_t pcppIsBusy(pcpp_t* stream, timeout_t timeout) {
|
|
size_t* psVar1;
|
|
char** send_buf;
|
|
undefined4 uVar2;
|
|
int iVar3;
|
|
e_pcpt_t eVar4;
|
|
int iVar5;
|
|
uint uVar6;
|
|
e_pcpp_t eVar7;
|
|
char* pcVar8;
|
|
char* pcVar9;
|
|
uint uVar10;
|
|
uint uVar11;
|
|
bool bVar12;
|
|
bool local_24;
|
|
int local_20;
|
|
int local_1c;
|
|
amtime_t local_18;
|
|
amtime_t local_10;
|
|
amtime_t local_8;
|
|
pcpt_t* sock;
|
|
|
|
uVar11 = timeout;
|
|
bVar12 = false;
|
|
local_20 = 0;
|
|
local_1c = 0;
|
|
local_24 = 0;
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
amiTimerGet(&local_18);
|
|
|
|
switch (stream->state) {
|
|
case pcpp_state_none:
|
|
stream->err = e_pcpp_no_client;
|
|
break;
|
|
case pcpp_state_open:
|
|
case pcpp_state_open_binary:
|
|
if (stream->state == 1) {
|
|
if (stream->open == 0) {
|
|
uVar2 = stream->field_0x210;
|
|
} else {
|
|
uVar2 = stream->field_0xb8;
|
|
}
|
|
iVar3 = _amTimeMs(local_18);
|
|
} else {
|
|
iVar3 = _amTimeMs(local_18);
|
|
uVar2 = stream->field_0x210;
|
|
}
|
|
iVar3 = pcppGetBlockingTime(uVar2, uVar11, stream, iVar3, &timeout);
|
|
sock = &stream->sock;
|
|
if (stream->state != 1) {
|
|
sock = &stream->data_sock;
|
|
}
|
|
eVar4 = pcptIsBusy(sock, timeout);
|
|
eVar7 = _errT2P(eVar4);
|
|
stream->err = eVar7;
|
|
if (eVar7 != e_pcpp_to) {
|
|
if (eVar7 == e_pcpp_ok) {
|
|
amiTimerGet(&local_10);
|
|
stream->last_active = _amTimeMs(local_10);
|
|
if (stream->state != 8) {
|
|
if (stream->open != 0) {
|
|
stream->read_bytes_num =
|
|
stream->read_bytes_num + stream->read_bytes_size;
|
|
stream->read_bytes_size = PCP_BUF_MAX - stream->read_bytes_num;
|
|
iVar3 = pcppCheckPrompt(stream);
|
|
if (iVar3 != 0) goto LAB_00457676;
|
|
stream->err = ~e_pcpp_no_client;
|
|
goto LAB_00457660;
|
|
}
|
|
stream->state = pcpp_state_wait_prompt;
|
|
if (uVar11 != TIMEOUT_NONE) {
|
|
amiTimerGet(&local_8);
|
|
uVar6 = (local_8.microseconds - local_18.microseconds) / 1000 +
|
|
(local_8.seconds - local_18.seconds) * 1000;
|
|
if (uVar6 < uVar11) {
|
|
uVar11 = uVar11 - uVar6;
|
|
} else {
|
|
uVar11 = 0;
|
|
}
|
|
}
|
|
stream->open = 1;
|
|
eVar7 = pcppRecvPrompt(stream, stream->field_0xb8, uVar11);
|
|
stream->err = eVar7;
|
|
if (eVar7 != e_pcpp_to) {
|
|
amiTimerGet(&local_10);
|
|
stream->state = pcpp_state_none;
|
|
stream->last_active = _amTimeMs(local_10);
|
|
return stream->err;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
goto LAB_004577b4;
|
|
}
|
|
if (iVar3 == 0) break;
|
|
if (stream->state == 1) {
|
|
stream->err = 0xfffffff5 - (uint)(stream->open != 0);
|
|
} else {
|
|
stream->err = e_pcpp_no_server;
|
|
}
|
|
goto LAB_00457392;
|
|
case pcpp_state_send_prompt:
|
|
case pcpp_state_send_request:
|
|
case pcpp_state_send_response:
|
|
uVar6 = uVar11;
|
|
if ((stream->sock).field_0x54 != 0) {
|
|
bVar12 = (stream->sock).open != PCPT_LISTENING;
|
|
if (bVar12) {
|
|
uVar2 = stream->field_0xb8;
|
|
} else {
|
|
uVar2 = stream->field_0x210;
|
|
}
|
|
bVar12 = !bVar12;
|
|
local_20 =
|
|
pcppGetBlockingTime(uVar2, uVar11, stream, _amTimeMs(local_18), &timeout);
|
|
uVar6 = timeout;
|
|
}
|
|
eVar4 = pcptIsBusy(&stream->sock, uVar6);
|
|
eVar7 = _errT2P(eVar4);
|
|
stream->err = eVar7;
|
|
if (eVar7 != e_pcpp_to) {
|
|
if (eVar7 == e_pcpp_ok) {
|
|
amiTimerGet(&local_10);
|
|
stream->last_active = _amTimeMs(local_10);
|
|
if (stream->state != 2) goto LAB_004577b4;
|
|
stream->open = 0;
|
|
amiTimerGet(&local_8);
|
|
stream->state = pcpp_state_recv_request;
|
|
iVar3 = pcppGetBlockingTime(stream->field_0xb8, uVar11, stream,
|
|
_amTimeMs(local_18), &timeout);
|
|
eVar7 = pcppRecvRequestMain(stream, &local_24, timeout);
|
|
stream->err = eVar7;
|
|
if ((eVar7 == e_pcpp_to) && (iVar3 != 0)) {
|
|
stream->err = e_pcpp_timeout_closed;
|
|
pcptCloseDataSock(&stream->sock);
|
|
pcppResetRead(stream);
|
|
}
|
|
if (stream->err == e_pcpp_to) {
|
|
if (local_24 != 0) {
|
|
stream->state = 14;
|
|
}
|
|
} else {
|
|
stream->state = pcpp_state_none;
|
|
}
|
|
if (stream->err == e_pcpp_ok) goto LAB_004574b8;
|
|
break;
|
|
}
|
|
goto LAB_004577af;
|
|
}
|
|
if (local_20 == 0) break;
|
|
stream->err = bVar12 ? e_pcpp_no_server : e_pcpp_timeout_closed;
|
|
goto LAB_00457392;
|
|
case pcpp_state_wait_prompt:
|
|
case pcpp_state_recv_request:
|
|
case pcpp_state_recv_response:
|
|
if (stream->field_0x214 == 0) {
|
|
uVar2 = stream->field_0xb8;
|
|
} else {
|
|
uVar2 = stream->field_0x204;
|
|
}
|
|
iVar3 = pcppGetBlockingTime(uVar2, uVar11, stream, _amTimeMs(local_18), &timeout);
|
|
uVar6 = timeout;
|
|
eVar7 = _errT2P(pcptIsBusy(&stream->sock, timeout));
|
|
stream->err = eVar7;
|
|
if (eVar7 != e_pcpp_to) {
|
|
if (eVar7 != e_pcpp_ok) {
|
|
LAB_00457660:
|
|
stream->state = pcpp_state_none;
|
|
return stream->err;
|
|
}
|
|
stream->read_bytes_num = stream->read_bytes_num + stream->read_bytes_size;
|
|
stream->field_0x214 = 0;
|
|
stream->read_bytes_size = PCP_BUF_MAX - stream->read_bytes_num;
|
|
if (stream->state == pcpp_state_wait_prompt) {
|
|
uVar6 = uVar11;
|
|
if (uVar11 != TIMEOUT_NONE) {
|
|
amiTimerGet(&local_8);
|
|
uVar6 =
|
|
-(uint)((uint)((local_8.microseconds - local_18.microseconds) / 1000 +
|
|
(local_8.seconds - local_18.seconds) * 1000) < uVar11) &
|
|
uVar11;
|
|
}
|
|
eVar7 = pcppRecvPrompt(stream, stream->field_0xb8, uVar6);
|
|
stream->err = eVar7;
|
|
if (eVar7 != e_pcpp_to) {
|
|
if (eVar7 != e_pcpp_ok) goto LAB_00457660;
|
|
if (stream->open == 0) {
|
|
if (uVar11 != TIMEOUT_NONE) {
|
|
amiTimerGet(&local_8);
|
|
uVar11 =
|
|
-(uint)((uint)((local_8.microseconds - local_18.microseconds) /
|
|
1000 +
|
|
(local_8.seconds - local_18.seconds) * 1000) <
|
|
uVar11) &
|
|
uVar11;
|
|
}
|
|
stream->state = pcpp_state_send_request;
|
|
eVar7 = pcppSendRequestMain(stream, stream->field_0xb8, uVar11);
|
|
stream->err = eVar7;
|
|
if ((eVar7 != e_pcpp_to) && (eVar7 != e_pcpp_ok)) {
|
|
stream->state = pcpp_state_none;
|
|
return eVar7;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
if (stream->read_bytes_num == 0) {
|
|
LAB_0045848d:
|
|
amiTimerGet(&local_8);
|
|
stream->last_active = _amTimeMs(local_8);
|
|
uVar10 = _amTimeDelta(local_8, local_18);
|
|
stream->field_0x214 = 1;
|
|
if (uVar11 != TIMEOUT_NONE) {
|
|
if (uVar11 <= uVar10) {
|
|
stream->state = stream->state == 5 ? 14 : 15;
|
|
return stream->err = e_pcpp_to;
|
|
}
|
|
uVar6 = uVar11 - uVar10;
|
|
}
|
|
eVar7 = pcppRecvAllMsg(stream, uVar6, &local_24);
|
|
stream->err = eVar7;
|
|
if (eVar7 != e_pcpp_ok) {
|
|
if (eVar7 == e_pcpp_to) {
|
|
if (local_24 != 0) {
|
|
stream->state = stream->state == 5 ? 14 : 15;
|
|
return e_pcpp_to;
|
|
}
|
|
break;
|
|
}
|
|
goto LAB_0045739d;
|
|
}
|
|
} else {
|
|
uVar10 = stream->read_bytes_num;
|
|
pcVar8 = stream->read_bytes_buf;
|
|
iVar3 = local_1c;
|
|
do {
|
|
if ((*pcVar8 == '\r') || (*pcVar8 == '\n')) {
|
|
iVar3 = 1;
|
|
}
|
|
pcVar8 = pcVar8 + 1;
|
|
uVar10 = uVar10 - 1;
|
|
} while (uVar10 != 0);
|
|
if (iVar3 == 0) goto LAB_0045848d;
|
|
}
|
|
pcVar8 = stream->read_bytes_buf;
|
|
eVar7 =
|
|
pcppCheckRecvMsg(pcVar8, stream->read_bytes_num, (uint)(stream->state == 5));
|
|
stream->err = eVar7;
|
|
if (eVar7 == e_pcpp_ok) {
|
|
pcppChangeRequest(stream, &timeout);
|
|
uVar11 = timeout;
|
|
pcVar9 = pcVar8;
|
|
if (timeout < stream->read_bytes_num) {
|
|
do {
|
|
*pcVar9 = pcVar8[uVar11];
|
|
uVar11 = uVar11 + 1;
|
|
pcVar9 = pcVar9 + 1;
|
|
} while (uVar11 < stream->read_bytes_num);
|
|
}
|
|
LAB_00458226:
|
|
stream->read_bytes_num = stream->read_bytes_num - timeout;
|
|
stream->read_bytes_size = stream->read_bytes_size + timeout;
|
|
stream->state = pcpp_state_none;
|
|
amiTimerGet(&local_18);
|
|
stream->last_active = _amTimeMs(local_18);
|
|
return stream->err;
|
|
}
|
|
stream->state = pcpp_state_none;
|
|
pcppResetRead(stream);
|
|
amiDebugLog("error Response format error");
|
|
return stream->err;
|
|
}
|
|
if (iVar3 == 0) break;
|
|
if (stream->field_0x214 == 0) {
|
|
stream->err = (stream->open != 0) ? e_pcpp_timeout_open : e_pcpp_timeout_closed;
|
|
} else {
|
|
stream->err = -7;
|
|
}
|
|
LAB_00457392:
|
|
pcptCloseDataSock(&stream->sock);
|
|
pcppResetRead(stream);
|
|
LAB_0045739d:
|
|
stream->state = pcpp_state_none;
|
|
return stream->err;
|
|
case pcpp_state_send_binary:
|
|
bVar12 = (stream->data_sock).open != PCPT_LISTENING;
|
|
if (bVar12) {
|
|
uVar2 = stream->field_0x208;
|
|
} else {
|
|
uVar2 = stream->field_0x210;
|
|
}
|
|
iVar5 = pcppGetBlockingTime(uVar2, uVar11, stream, _amTimeMs(local_18), &timeout);
|
|
eVar4 = pcptIsBusy(&stream->data_sock, timeout);
|
|
eVar7 = _errT2P(eVar4);
|
|
iVar3 = (stream->data_sock).field_0x54;
|
|
stream->err = eVar7;
|
|
if (iVar3 == 0) {
|
|
if ((iVar5 != 0) && (eVar7 == e_pcpp_to)) {
|
|
stream->err = (uint)!bVar12 * 2 + -13;
|
|
pcptCloseDataSock(&stream->sock);
|
|
pcppResetRead(stream);
|
|
}
|
|
} else {
|
|
amiTimerGet(&local_10);
|
|
stream->last_active = _amTimeMs(local_10);
|
|
}
|
|
if (stream->err != e_pcpp_to) {
|
|
stream->state = pcpp_state_none;
|
|
}
|
|
if (stream->err == e_pcpp_ok) {
|
|
amiTimerGet(&local_10);
|
|
stream->last_active = _amTimeMs(local_10);
|
|
stream->state = pcpp_state_send_binary_wait;
|
|
psVar1 = &stream->send_buf_len;
|
|
*psVar1 = PCP_SEND_BUF_MAX;
|
|
ZERO(stream->send_buf);
|
|
stream->field_0x1e8 = 0;
|
|
iVar3 = pcppGetBlockingTime(stream->field_0x20c, uVar11, stream,
|
|
_amTimeMs(local_18), &timeout);
|
|
eVar4 = pcptRecv(&stream->sock, (unsigned char*)stream->send_buf, psVar1, timeout);
|
|
eVar7 = _errT2P(eVar4);
|
|
stream->err = eVar7;
|
|
if ((iVar3 != 0) && (eVar7 == e_pcpp_to)) {
|
|
stream->err = -14;
|
|
pcptCloseDataSock(&stream->sock);
|
|
pcppResetRead(stream);
|
|
}
|
|
if (stream->err != e_pcpp_to) {
|
|
stream->state = pcpp_state_none;
|
|
}
|
|
if (stream->err == e_pcpp_ok) {
|
|
stream->field_0x1e8 = stream->field_0x1e8 + *psVar1;
|
|
uVar11 = 0;
|
|
*psVar1 = PCP_SEND_BUF_MAX - stream->field_0x1e8;
|
|
stream->state = pcpp_state_none;
|
|
stream->err = -9;
|
|
if (stream->field_0x1e8 != 0) {
|
|
do {
|
|
if (*(char*)((int)&stream->send_buf + uVar11) == PCP_CHAR_BINACK) {
|
|
stream->err = e_pcpp_ok;
|
|
break;
|
|
}
|
|
uVar11 = uVar11 + 1;
|
|
} while (uVar11 < stream->field_0x1e8);
|
|
}
|
|
amiTimerGet(&local_10);
|
|
stream->last_active = _amTimeMs(local_10);
|
|
return stream->err;
|
|
}
|
|
}
|
|
break;
|
|
case pcpp_state_send_binary_wait:
|
|
iVar3 = pcppGetBlockingTime(stream->field_0x20c, uVar11, stream, _amTimeMs(local_18),
|
|
&timeout);
|
|
eVar4 = pcptIsBusy(&stream->sock, timeout);
|
|
eVar7 = _errT2P(eVar4);
|
|
stream->err = eVar7;
|
|
if ((iVar3 != 0) && (eVar7 == e_pcpp_to)) {
|
|
stream->err = -14;
|
|
pcptCloseDataSock(&stream->sock);
|
|
pcppResetRead(stream);
|
|
}
|
|
if (stream->err != e_pcpp_to) {
|
|
stream->state = pcpp_state_none;
|
|
}
|
|
if (stream->err == e_pcpp_ok) {
|
|
amiTimerGet(&local_10);
|
|
stream->field_0x1e8 = stream->field_0x1e8 + stream->send_buf_len;
|
|
stream->last_active = _amTimeMs(local_10);
|
|
;
|
|
uVar11 = 0;
|
|
stream->send_buf_len = PCP_SEND_BUF_MAX - stream->field_0x1e8;
|
|
stream->err = -9;
|
|
if (stream->field_0x1e8 != 0) {
|
|
while (*(char*)((int)&stream->send_buf + uVar11) != PCP_CHAR_BINACK) {
|
|
uVar11 = uVar11 + 1;
|
|
if (stream->field_0x1e8 <= uVar11) {
|
|
return stream->err;
|
|
}
|
|
}
|
|
LAB_00457676:
|
|
stream->err = e_pcpp_ok;
|
|
return e_pcpp_ok;
|
|
}
|
|
}
|
|
break;
|
|
case pcpp_state_recv_binary:
|
|
if (stream->field_0x214 != 0) {
|
|
bVar12 = (stream->data_sock).open != PCPT_LISTENING;
|
|
if (bVar12) {
|
|
uVar2 = stream->field_0x208;
|
|
} else {
|
|
uVar2 = stream->field_0x210;
|
|
}
|
|
iVar3 = pcppGetBlockingTime(uVar2, uVar11, stream, _amTimeMs(local_18), &timeout);
|
|
eVar4 = pcptIsBusy(&stream->data_sock, timeout);
|
|
eVar7 = _errT2P(eVar4);
|
|
stream->err = eVar7;
|
|
if ((eVar7 == e_pcpp_to) && (iVar3 != 0)) {
|
|
stream->err = (uint)!bVar12 * 2 + -13;
|
|
pcptCloseDataSock(&stream->sock);
|
|
pcppResetRead(stream);
|
|
}
|
|
eVar7 = stream->err;
|
|
if (eVar7 == e_pcpp_to) {
|
|
LAB_00457b2e:
|
|
if (eVar7 != e_pcpp_ok) {
|
|
return eVar7;
|
|
}
|
|
} else {
|
|
if (eVar7 != e_pcpp_ok) {
|
|
stream->field_0x214 = 0;
|
|
stream->state = pcpp_state_none;
|
|
goto LAB_00457b2e;
|
|
}
|
|
}
|
|
stream->field_0x1fc = stream->field_0x1fc + stream->field_0x1f8;
|
|
stream->field_0x214 = 0;
|
|
stream->field_0x1f8 = stream->recv_binary_buf_len - stream->field_0x1fc;
|
|
amiTimerGet(&local_10);
|
|
stream->last_active = _amTimeMs(local_10);
|
|
}
|
|
if (stream->field_0x1fc <= stream->recv_binary_buf_len &&
|
|
stream->recv_binary_buf_len != stream->field_0x1fc) {
|
|
psVar1 = &stream->field_0x1f8;
|
|
do {
|
|
iVar3 = pcppGetBlockingTime(stream->field_0x208, uVar11, stream,
|
|
_amTimeMs(local_18), &timeout);
|
|
stream->field_0x214 = 1;
|
|
eVar4 =
|
|
pcptRecv(&stream->data_sock, stream->recv_binary_buf + stream->field_0x1fc,
|
|
psVar1, timeout);
|
|
eVar7 = _errT2P(eVar4);
|
|
stream->err = eVar7;
|
|
if ((eVar7 == e_pcpp_to) && (iVar3 != 0)) {
|
|
stream->err = -13;
|
|
pcptCloseDataSock(&stream->sock);
|
|
pcppResetRead(stream);
|
|
}
|
|
eVar7 = stream->err;
|
|
if (eVar7 == e_pcpp_to) {
|
|
LAB_00457c47:
|
|
if (eVar7 != e_pcpp_ok) goto switchD_004572ff_caseD_10;
|
|
} else {
|
|
if (eVar7 != e_pcpp_ok) {
|
|
stream->state = pcpp_state_none;
|
|
goto LAB_00457c47;
|
|
}
|
|
}
|
|
stream->field_0x1fc = stream->field_0x1fc + *psVar1;
|
|
stream->field_0x214 = 0;
|
|
*psVar1 = stream->recv_binary_buf_len - stream->field_0x1fc;
|
|
amiTimerGet(&local_10);
|
|
stream->last_active = _amTimeMs(local_10);
|
|
} while (stream->field_0x1fc <= stream->recv_binary_buf_len &&
|
|
stream->recv_binary_buf_len != stream->field_0x1fc);
|
|
}
|
|
send_buf = (char**)&stream->send_buf;
|
|
psVar1 = &stream->send_buf_len;
|
|
stream->state = pcpp_state_send_binary_ack;
|
|
*send_buf[0] = PCP_CHAR_BINACK;
|
|
*psVar1 = 1;
|
|
local_20 = pcppGetBlockingTime(stream->field_0x20c, uVar11, stream, _amTimeMs(local_18),
|
|
&timeout);
|
|
eVar4 = pcptSend(&stream->sock, (unsigned char*)*send_buf, psVar1, stream->field_0x204,
|
|
timeout);
|
|
eVar7 = _errT2P(eVar4);
|
|
stream->err = eVar7;
|
|
if ((eVar7 == e_pcpp_to) && (local_20 != 0)) {
|
|
stream->err = -14;
|
|
pcptCloseDataSock(&stream->sock);
|
|
pcppResetRead(stream);
|
|
}
|
|
if (stream->err != e_pcpp_to) {
|
|
stream->state = pcpp_state_none;
|
|
}
|
|
if (stream->err == e_pcpp_ok) {
|
|
amiTimerGet(&local_10);
|
|
stream->last_active = _amTimeMs(local_10);
|
|
stream->state = pcpp_state_send_binary_ack_wait;
|
|
iVar3 = pcppGetBlockingTime(stream->field_0x208, uVar11, stream,
|
|
_amTimeMs(local_18), &timeout);
|
|
*psVar1 = PCP_SEND_BUF_MAX;
|
|
ZERO(stream->send_buf);
|
|
eVar4 = pcptRecv(&stream->data_sock, (unsigned char*)*send_buf, psVar1, timeout);
|
|
eVar7 = _errT2P(eVar4);
|
|
stream->err = eVar7;
|
|
if ((iVar3 != 0) && (eVar7 == e_pcpp_to)) {
|
|
stream->err = -13;
|
|
}
|
|
if (stream->err != e_pcpp_to) {
|
|
stream->state = pcpp_state_none;
|
|
}
|
|
if (stream->err == e_pcpp_closed) {
|
|
stream->err = e_pcpp_ok;
|
|
LAB_004574b8:
|
|
amiTimerGet(&local_10);
|
|
stream->last_active = _amTimeMs(local_10);
|
|
return stream->err;
|
|
}
|
|
}
|
|
break;
|
|
case pcpp_state_send_binary_ack:
|
|
iVar3 = pcppGetBlockingTime(stream->field_0x20c, uVar11, stream, _amTimeMs(local_18),
|
|
&timeout);
|
|
eVar4 = pcptIsBusy(&stream->sock, timeout);
|
|
eVar7 = _errT2P(eVar4);
|
|
stream->err = eVar7;
|
|
if ((iVar3 != 0) && (eVar7 == e_pcpp_to)) {
|
|
stream->err = -14;
|
|
pcptCloseDataSock(&stream->sock);
|
|
pcppResetRead(stream);
|
|
}
|
|
if (stream->err != e_pcpp_to) {
|
|
stream->state = pcpp_state_none;
|
|
}
|
|
if (stream->err != e_pcpp_ok) break;
|
|
stream->state = pcpp_state_send_binary_ack_wait;
|
|
amiTimerGet(&local_10);
|
|
stream->last_active = _amTimeMs(local_10);
|
|
iVar3 = pcppGetBlockingTime(stream->field_0x208, uVar11, stream, _amTimeMs(local_18),
|
|
&timeout);
|
|
stream->send_buf_len = PCP_SEND_BUF_MAX;
|
|
ZERO(stream->send_buf);
|
|
eVar4 = pcptRecv(&stream->data_sock, (unsigned char*)stream->send_buf,
|
|
&stream->send_buf_len, timeout);
|
|
eVar7 = _errT2P(eVar4);
|
|
stream->err = eVar7;
|
|
if ((iVar3 != 0) && (eVar7 == e_pcpp_to)) {
|
|
stream->err = -13;
|
|
pcptCloseDataSock(&stream->sock);
|
|
pcppResetRead(stream);
|
|
}
|
|
if (stream->err != e_pcpp_to) stream->state = pcpp_state_none;
|
|
|
|
if (stream->err != e_pcpp_closed) break;
|
|
stream->err = e_pcpp_ok;
|
|
goto LAB_004574b8;
|
|
case pcpp_state_send_binary_ack_wait:
|
|
iVar3 = pcppGetBlockingTime(stream->field_0x208, uVar11, stream, _amTimeMs(local_18),
|
|
&timeout);
|
|
eVar4 = pcptIsBusy(&stream->data_sock, timeout);
|
|
eVar7 = _errT2P(eVar4);
|
|
stream->err = eVar7;
|
|
if ((iVar3 == 0) || (eVar7 != e_pcpp_to)) {
|
|
if (eVar7 == e_pcpp_closed) {
|
|
stream->err = e_pcpp_ok;
|
|
amiTimerGet(&local_10);
|
|
stream->last_active = _amTimeMs(local_10);
|
|
return stream->err;
|
|
}
|
|
break;
|
|
}
|
|
stream->err = -13;
|
|
pcptCloseDataSock(&stream->sock);
|
|
LAB_004577af:
|
|
pcppResetRead(stream);
|
|
LAB_004577b4:
|
|
stream->state = pcpp_state_none;
|
|
return stream->err;
|
|
case 14:
|
|
case pcpp_state_wait_response:
|
|
amiTimerGet(&local_8);
|
|
uVar6 = _amTimeDelta(local_8, local_18);
|
|
stream->field_0x214 = 1;
|
|
if (uVar11 != TIMEOUT_NONE) {
|
|
if (uVar6 < uVar11) {
|
|
uVar11 = uVar11 - uVar6;
|
|
} else {
|
|
uVar11 = 0;
|
|
}
|
|
}
|
|
eVar7 = pcppRecvAllMsg(stream, uVar11, &local_24);
|
|
stream->err = eVar7;
|
|
if (eVar7 == e_pcpp_ok) {
|
|
pcVar8 = stream->read_bytes_buf;
|
|
eVar7 =
|
|
pcppCheckRecvMsg(pcVar8, stream->read_bytes_num, (uint)(stream->state == 14));
|
|
stream->err = eVar7;
|
|
if (eVar7 != e_pcpp_ok) {
|
|
stream->state = pcpp_state_none;
|
|
pcppResetRead(stream);
|
|
amiDebugLog("error Response format error");
|
|
return stream->err;
|
|
}
|
|
pcppChangeRequest(stream, &timeout);
|
|
uVar11 = timeout;
|
|
pcVar9 = pcVar8;
|
|
if (timeout < stream->read_bytes_num) {
|
|
do {
|
|
*pcVar9 = pcVar8[uVar11];
|
|
uVar11 = uVar11 + 1;
|
|
pcVar9 = pcVar9 + 1;
|
|
} while (uVar11 < stream->read_bytes_num);
|
|
}
|
|
goto LAB_00458226;
|
|
}
|
|
if (eVar7 == e_pcpp_to) {
|
|
if (local_24 == 0) {
|
|
stream->state = stream->state == 14 ? 5 : 7;
|
|
return stream->err;
|
|
}
|
|
break;
|
|
}
|
|
goto LAB_0045739d;
|
|
}
|
|
|
|
switchD_004572ff_caseD_10:
|
|
return stream->err;
|
|
}
|
|
|
|
int pcpp_something(amtime_t* time, timeout_t timeout, pcpp_t* stream, pcpt_t* sock,
|
|
unsigned char* send_buf, size_t* send_len, undefined4 param_7,
|
|
undefined4 param_8, int fallback_err) {
|
|
uint iVar1;
|
|
uint blocking_time;
|
|
amtime_t now;
|
|
e_pcpp_t err;
|
|
|
|
iVar1 = pcppGetBlockingTime(param_8, timeout, stream, _amTimeMs(*time), &blocking_time);
|
|
err = _errT2P(pcptSend(sock, send_buf, send_len, param_7, blocking_time));
|
|
if (err != e_pcpp_to) return err;
|
|
|
|
if (sock->field_0x54 != 0) {
|
|
if (timeout == TIMEOUT_NONE) return _errT2P(pcptIsBusy(sock, TIMEOUT_NONE));
|
|
|
|
amiTimerGet(&now);
|
|
iVar1 = FUN_00459d00(time, &now);
|
|
if ((iVar1 / 1000) < timeout) {
|
|
return _errT2P(pcptIsBusy(sock, timeout - iVar1 / 1000));
|
|
}
|
|
return _errT2P(pcptIsBusy(sock, 0));
|
|
}
|
|
|
|
if (iVar1 != 0) {
|
|
return fallback_err;
|
|
}
|
|
return err;
|
|
}
|
|
|
|
pcp_send_data_t* pcppAddSendPacket(pcp_send_data_t* send_data, char* keyword, char* value) {
|
|
if (send_data == NULL || keyword == NULL) {
|
|
amiDebugLog("error Send Data isn't set");
|
|
return NULL;
|
|
}
|
|
|
|
size_t existing_length = send_data->length;
|
|
if (existing_length == 0) return pcppSetSendPacket(send_data, keyword, value);
|
|
|
|
size_t kwLen = strlen(keyword);
|
|
if (value == NULL) {
|
|
if (existing_length + kwLen + 3 < PCP_BUF_MAX) {
|
|
sprintf_s((char*)&send_data->data[existing_length], PCP_BUF_MAX - existing_length,
|
|
"&%s\r\n", keyword);
|
|
send_data->length += kwLen + 1;
|
|
return send_data;
|
|
}
|
|
} else {
|
|
size_t valLen = strlen(value);
|
|
if (existing_length + kwLen + valLen + 4 < PCP_BUF_MAX) {
|
|
sprintf_s((char*)&send_data->data[existing_length], PCP_BUF_MAX - existing_length,
|
|
"&%s=%s\r\n", keyword, value);
|
|
send_data->length += valLen + kwLen + 2;
|
|
return send_data;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
e_pcpp_t pcppSendRequestTable(pcpp_t* stream, pcp_send_data_t* request_buffer, timeout_t timeout) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
|
|
if (request_buffer == NULL) {
|
|
amiDebugLog("error Request buffer isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
|
|
return pcppSendRequest(stream, request_buffer, request_buffer->length + 2, timeout);
|
|
}
|
|
|
|
e_pcpp_t pcppSendRequest(pcpp_t* stream, pcp_send_data_t* request_buffer, uint nbytes,
|
|
timeout_t timeout) {
|
|
amtime_t local_18;
|
|
amtime_t local_10;
|
|
amtime_t local_8;
|
|
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
if (request_buffer == NULL) {
|
|
amiDebugLog("error Request buffer isn't set");
|
|
return e_pcpp_param_invalid;
|
|
}
|
|
|
|
if (0x100 < nbytes) {
|
|
amiDebugLog("error Request buffer over");
|
|
return (stream->err = e_pcpp_param_invalid);
|
|
}
|
|
|
|
amiTimerGet(&local_10);
|
|
e_pcpp_t pcpp_err = pcppCheckRecvMsg((char*)&request_buffer->data, nbytes, 1);
|
|
stream->err = pcpp_err;
|
|
if (pcpp_err != e_pcpp_ok) {
|
|
stream->state = pcpp_state_none;
|
|
pcppResetRead(stream);
|
|
amiDebugLog("error Message format error");
|
|
return stream->err;
|
|
}
|
|
|
|
request_buffer->length = nbytes;
|
|
stream->resp_buffer = request_buffer;
|
|
|
|
*(uint*)stream->send_buf = nbytes;
|
|
if (stream->open == 0) {
|
|
stream->state = pcpp_state_wait_prompt;
|
|
pcpp_err = pcppRecvPrompt(stream, stream->field_0xb8, timeout);
|
|
stream->err = pcpp_err;
|
|
if (pcpp_err != e_pcpp_to) {
|
|
stream->state = pcpp_state_none;
|
|
}
|
|
if (pcpp_err != e_pcpp_ok) {
|
|
return pcpp_err;
|
|
}
|
|
}
|
|
|
|
amiTimerGet(&local_18);
|
|
stream->state = pcpp_state_send_request;
|
|
|
|
pcpp_err = pcppSendRequestMain(stream, stream->field_0xb8, timeout);
|
|
stream->err = pcpp_err;
|
|
if (pcpp_err != e_pcpp_to) {
|
|
stream->state = pcpp_state_none;
|
|
amiTimerGet(&local_8);
|
|
stream->last_active = local_8.microseconds / 1000 + local_8.seconds * 1000;
|
|
stream->open = 0;
|
|
}
|
|
return stream->err;
|
|
}
|
|
|
|
e_pcpp_t pcppRecvResponse(pcpp_t* stream, pcp_parse_data_t* buffer, timeout_t timeout) {
|
|
int iVar1;
|
|
amtime_t local_8;
|
|
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return -5;
|
|
}
|
|
|
|
if (buffer == NULL) {
|
|
amiDebugLog("error Response buffer isn't set");
|
|
return -5;
|
|
}
|
|
|
|
stream->recv_data_buffer = buffer;
|
|
stream->state = pcpp_state_recv_response;
|
|
stream->field_0x214 = 0;
|
|
bool bReRecv;
|
|
iVar1 = pcppRecvAllMsg(stream, timeout, &bReRecv);
|
|
stream->err = iVar1;
|
|
if (iVar1 != e_pcpp_ok) {
|
|
if (iVar1 != e_pcpp_to) {
|
|
stream->state = pcpp_state_none;
|
|
return iVar1;
|
|
}
|
|
if (stream != NULL) stream->state = pcpp_state_wait_response;
|
|
return e_pcpp_to;
|
|
}
|
|
|
|
char* pcVar5 = stream->read_bytes_buf;
|
|
iVar1 = pcppCheckRecvMsg(pcVar5, stream->read_bytes_num, 0);
|
|
stream->err = iVar1;
|
|
if (iVar1 == 0) {
|
|
uint lenout;
|
|
pcppChangeRequest(stream, &lenout);
|
|
uint ppVar2 = lenout;
|
|
char* pcVar3 = pcVar5;
|
|
if (lenout < stream->read_bytes_num) {
|
|
do {
|
|
*pcVar3 = pcVar5[ppVar2];
|
|
ppVar2++;
|
|
pcVar3++;
|
|
} while (ppVar2 < stream->read_bytes_num);
|
|
}
|
|
stream->read_bytes_num = stream->read_bytes_num - (int)lenout;
|
|
stream->read_bytes_size = (stream->read_bytes_size - 0x46) + lenout;
|
|
stream->state = pcpp_state_none;
|
|
stream->err = 0;
|
|
amiTimerGet(&local_8);
|
|
stream->last_active = local_8.microseconds / 1000 + local_8.seconds * 1000;
|
|
} else {
|
|
stream->state = pcpp_state_none;
|
|
pcppResetRead(stream);
|
|
amiDebugLog("error Response format error");
|
|
return stream->err;
|
|
}
|
|
|
|
return stream->err;
|
|
}
|
|
|
|
SOCKADDR* pcppGetSockAddr(pcpp_t* stream, bool is_data) {
|
|
if (stream == NULL) {
|
|
amiDebugLog("error PCPP stream isn't set");
|
|
return NULL;
|
|
}
|
|
|
|
if (is_data) {
|
|
return &(stream->data_sock).client_addr;
|
|
}
|
|
return &(stream->sock).client_addr;
|
|
} |