mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-19 21:13:12 -07:00
Feedback History working!
This commit is contained in:
parent
a0567b670c
commit
e37ac7bc77
9 changed files with 326 additions and 36 deletions
|
@ -117,6 +117,17 @@ void StreamSession::UpdateGamepads()
|
|||
connect(gamepad, &QGamepad::buttonBChanged, this, &StreamSession::SendFeedbackState);
|
||||
connect(gamepad, &QGamepad::buttonXChanged, this, &StreamSession::SendFeedbackState);
|
||||
connect(gamepad, &QGamepad::buttonYChanged, this, &StreamSession::SendFeedbackState);
|
||||
connect(gamepad, &QGamepad::buttonLeftChanged, this, &StreamSession::SendFeedbackState);
|
||||
connect(gamepad, &QGamepad::buttonRightChanged, this, &StreamSession::SendFeedbackState);
|
||||
connect(gamepad, &QGamepad::buttonUpChanged, this, &StreamSession::SendFeedbackState);
|
||||
connect(gamepad, &QGamepad::buttonDownChanged, this, &StreamSession::SendFeedbackState);
|
||||
connect(gamepad, &QGamepad::buttonL1Changed, this, &StreamSession::SendFeedbackState);
|
||||
connect(gamepad, &QGamepad::buttonR1Changed, this, &StreamSession::SendFeedbackState);
|
||||
connect(gamepad, &QGamepad::buttonL3Changed, this, &StreamSession::SendFeedbackState);
|
||||
connect(gamepad, &QGamepad::buttonR3Changed, this, &StreamSession::SendFeedbackState);
|
||||
connect(gamepad, &QGamepad::buttonStartChanged, this, &StreamSession::SendFeedbackState);
|
||||
connect(gamepad, &QGamepad::buttonSelectChanged, this, &StreamSession::SendFeedbackState);
|
||||
connect(gamepad, &QGamepad::buttonGuideChanged, this, &StreamSession::SendFeedbackState);
|
||||
connect(gamepad, &QGamepad::axisLeftXChanged, this, &StreamSession::SendFeedbackState);
|
||||
connect(gamepad, &QGamepad::axisLeftYChanged, this, &StreamSession::SendFeedbackState);
|
||||
connect(gamepad, &QGamepad::axisRightXChanged, this, &StreamSession::SendFeedbackState);
|
||||
|
@ -137,6 +148,17 @@ void StreamSession::SendFeedbackState()
|
|||
state.buttons |= gamepad->buttonB() ? CHIAKI_CONTROLLER_BUTTON_MOON : 0;
|
||||
state.buttons |= gamepad->buttonX() ? CHIAKI_CONTROLLER_BUTTON_BOX : 0;
|
||||
state.buttons |= gamepad->buttonY() ? CHIAKI_CONTROLLER_BUTTON_PYRAMID : 0;
|
||||
state.buttons |= gamepad->buttonLeft() ? CHIAKI_CONTROLLER_BUTTON_DPAD_LEFT : 0;
|
||||
state.buttons |= gamepad->buttonRight() ? CHIAKI_CONTROLLER_BUTTON_DPAD_RIGHT : 0;
|
||||
state.buttons |= gamepad->buttonUp() ? CHIAKI_CONTROLLER_BUTTON_DPAD_UP : 0;
|
||||
state.buttons |= gamepad->buttonDown() ? CHIAKI_CONTROLLER_BUTTON_DPAD_DOWN : 0;
|
||||
state.buttons |= gamepad->buttonL1() ? CHIAKI_CONTROLLER_BUTTON_L1 : 0;
|
||||
state.buttons |= gamepad->buttonR1() ? CHIAKI_CONTROLLER_BUTTON_R1 : 0;
|
||||
state.buttons |= gamepad->buttonL3() ? CHIAKI_CONTROLLER_BUTTON_L3 : 0;
|
||||
state.buttons |= gamepad->buttonR3() ? CHIAKI_CONTROLLER_BUTTON_R3 : 0;
|
||||
state.buttons |= gamepad->buttonStart() ? CHIAKI_CONTROLLER_BUTTON_OPTIONS : 0;
|
||||
state.buttons |= gamepad->buttonSelect() ? CHIAKI_CONTROLLER_BUTTON_SHARE : 0;
|
||||
state.buttons |= gamepad->buttonGuide() ? CHIAKI_CONTROLLER_BUTTON_PS : 0;
|
||||
state.left_x = static_cast<int16_t>(gamepad->axisLeftX() * 0x7fff);
|
||||
state.left_y = static_cast<int16_t>(gamepad->axisLeftY() * 0x7fff);
|
||||
state.right_x = static_cast<int16_t>(gamepad->axisRightX() * 0x7fff);
|
||||
|
|
|
@ -32,9 +32,23 @@ typedef enum chiaki_controller_button_t
|
|||
CHIAKI_CONTROLLER_BUTTON_CROSS = (1 << 0),
|
||||
CHIAKI_CONTROLLER_BUTTON_MOON = (1 << 1),
|
||||
CHIAKI_CONTROLLER_BUTTON_BOX = (1 << 2),
|
||||
CHIAKI_CONTROLLER_BUTTON_PYRAMID = (1 << 3)
|
||||
CHIAKI_CONTROLLER_BUTTON_PYRAMID = (1 << 3),
|
||||
CHIAKI_CONTROLLER_BUTTON_DPAD_LEFT = (1 << 4),
|
||||
CHIAKI_CONTROLLER_BUTTON_DPAD_RIGHT = (1 << 5),
|
||||
CHIAKI_CONTROLLER_BUTTON_DPAD_UP = (1 << 6),
|
||||
CHIAKI_CONTROLLER_BUTTON_DPAD_DOWN = (1 << 7),
|
||||
CHIAKI_CONTROLLER_BUTTON_L1 = (1 << 8),
|
||||
CHIAKI_CONTROLLER_BUTTON_R1 = (1 << 9),
|
||||
CHIAKI_CONTROLLER_BUTTON_L3 = (1 << 10),
|
||||
CHIAKI_CONTROLLER_BUTTON_R3 = (1 << 11),
|
||||
CHIAKI_CONTROLLER_BUTTON_OPTIONS = (1 << 12),
|
||||
CHIAKI_CONTROLLER_BUTTON_SHARE = (1 << 13),
|
||||
CHIAKI_CONTROLLER_BUTTON_TOUCHPAD = (1 << 14),
|
||||
CHIAKI_CONTROLLER_BUTTON_PS = (1 << 15)
|
||||
} ChiakiControllerButton;
|
||||
|
||||
#define CHIAKI_CONTROLLER_BUTTONS_COUNT 16
|
||||
|
||||
typedef struct chiaki_controller_state_t
|
||||
{
|
||||
/**
|
||||
|
@ -42,6 +56,9 @@ typedef struct chiaki_controller_state_t
|
|||
*/
|
||||
uint32_t buttons;
|
||||
|
||||
uint8_t l2_state;
|
||||
uint8_t r2_state;
|
||||
|
||||
int16_t left_x;
|
||||
int16_t left_y;
|
||||
int16_t right_x;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "common.h"
|
||||
#include "log.h"
|
||||
#include "controller.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
@ -29,7 +30,6 @@ extern "C" {
|
|||
|
||||
typedef struct chiaki_feedback_state_t
|
||||
{
|
||||
uint32_t buttons;
|
||||
int16_t left_x;
|
||||
int16_t left_y;
|
||||
int16_t right_x;
|
||||
|
@ -43,6 +43,44 @@ typedef struct chiaki_feedback_state_t
|
|||
*/
|
||||
CHIAKI_EXPORT void chiaki_feedback_state_format(uint8_t *buf, ChiakiFeedbackState *state);
|
||||
|
||||
|
||||
#define CHIAKI_HISTORY_EVENT_SIZE_MAX 0x3 // TODO: will be bigger later for touchpad at least
|
||||
|
||||
typedef struct chiaki_feedback_history_event_t
|
||||
{
|
||||
uint8_t buf[CHIAKI_HISTORY_EVENT_SIZE_MAX];
|
||||
size_t len;
|
||||
} ChiakiFeedbackHistoryEvent;
|
||||
|
||||
/**
|
||||
* @param state 0x0 for not pressed, 0xff for pressed, intermediate values for analog triggers
|
||||
*/
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_feedback_history_event_set_button(ChiakiFeedbackHistoryEvent *event, ChiakiControllerButton button, uint8_t state);
|
||||
|
||||
/**
|
||||
* Ring buffer of ChiakiFeedbackHistoryEvent
|
||||
*/
|
||||
typedef struct chiaki_feedback_history_buffer_t
|
||||
{
|
||||
ChiakiFeedbackHistoryEvent *events;
|
||||
size_t size;
|
||||
size_t begin;
|
||||
size_t len;
|
||||
} ChiakiFeedbackHistoryBuffer;
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_feedback_history_buffer_init(ChiakiFeedbackHistoryBuffer *feedback_history_buffer, size_t size);
|
||||
CHIAKI_EXPORT void chiaki_feedback_history_buffer_fini(ChiakiFeedbackHistoryBuffer *feedback_history_buffer);
|
||||
|
||||
/**
|
||||
* @param buf_size Pointer to the allocated size of buf, will contain the written size after a successful formatting.
|
||||
*/
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_feedback_history_buffer_format(ChiakiFeedbackHistoryBuffer *feedback_history_buffer, uint8_t *buf, size_t *buf_size);
|
||||
|
||||
/**
|
||||
* Push an event to the front of the buffer
|
||||
*/
|
||||
CHIAKI_EXPORT void chiaki_feedback_history_buffer_push(ChiakiFeedbackHistoryBuffer *feedback_history_buffer, ChiakiFeedbackHistoryEvent *event);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -35,6 +35,9 @@ typedef struct chiaki_feedback_sender_t
|
|||
|
||||
ChiakiSeqNum16 state_seq_num;
|
||||
|
||||
ChiakiSeqNum16 history_seq_num;
|
||||
ChiakiFeedbackHistoryBuffer history_buf;
|
||||
|
||||
bool should_stop;
|
||||
ChiakiControllerState controller_state_prev;
|
||||
ChiakiControllerState controller_state;
|
||||
|
|
|
@ -205,6 +205,10 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_congestion(ChiakiTakion *takion
|
|||
*/
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_feedback_state(ChiakiTakion *takion, ChiakiSeqNum16 seq_num, ChiakiFeedbackState *feedback_state);
|
||||
|
||||
/**
|
||||
* Thread-safe while Takion is running.
|
||||
*/
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_feedback_history(ChiakiTakion *takion, ChiakiSeqNum16 seq_num, uint8_t *payload, size_t payload_size);
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_av_packet_parse(ChiakiTakionAVPacket *packet, uint8_t base_type, uint8_t *buf, size_t buf_size);
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <chiaki/controller.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
|
||||
CHIAKI_EXPORT void chiaki_feedback_state_format(uint8_t *buf, ChiakiFeedbackState *state)
|
||||
{
|
||||
|
@ -44,3 +45,109 @@ CHIAKI_EXPORT void chiaki_feedback_state_format(uint8_t *buf, ChiakiFeedbackStat
|
|||
*((uint16_t *)(buf + 0x15)) = htons((uint16_t)state->right_x);
|
||||
*((uint16_t *)(buf + 0x17)) = htons((uint16_t)state->right_y);
|
||||
}
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_feedback_history_event_set_button(ChiakiFeedbackHistoryEvent *event, ChiakiControllerButton button, uint8_t state)
|
||||
{
|
||||
// some buttons use a third byte for the state, some don't
|
||||
event->buf[0] = 0x80;
|
||||
event->len = 2;
|
||||
switch(button)
|
||||
{
|
||||
case CHIAKI_CONTROLLER_BUTTON_CROSS:
|
||||
event->buf[1] = 0x88;
|
||||
break;
|
||||
case CHIAKI_CONTROLLER_BUTTON_MOON:
|
||||
event->buf[1] = 0x89;
|
||||
break;
|
||||
case CHIAKI_CONTROLLER_BUTTON_BOX:
|
||||
event->buf[1] = 0x8a;
|
||||
break;
|
||||
case CHIAKI_CONTROLLER_BUTTON_PYRAMID:
|
||||
event->buf[1] = 0x8b;
|
||||
break;
|
||||
case CHIAKI_CONTROLLER_BUTTON_DPAD_LEFT:
|
||||
event->buf[1] = 0x82;
|
||||
break;
|
||||
case CHIAKI_CONTROLLER_BUTTON_DPAD_RIGHT:
|
||||
event->buf[1] = 0x83;
|
||||
break;
|
||||
case CHIAKI_CONTROLLER_BUTTON_DPAD_UP:
|
||||
event->buf[1] = 0x80;
|
||||
break;
|
||||
case CHIAKI_CONTROLLER_BUTTON_DPAD_DOWN:
|
||||
event->buf[1] = 0x81;
|
||||
break;
|
||||
case CHIAKI_CONTROLLER_BUTTON_L1:
|
||||
event->buf[1] = 0x84;
|
||||
break;
|
||||
case CHIAKI_CONTROLLER_BUTTON_R1:
|
||||
event->buf[1] = 0x85;
|
||||
break;
|
||||
case CHIAKI_CONTROLLER_BUTTON_L3:
|
||||
event->buf[1] = state ? 0xaf : 0x8f;
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
case CHIAKI_CONTROLLER_BUTTON_R3:
|
||||
event->buf[1] = state ? 0xb0 : 0x90;
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
case CHIAKI_CONTROLLER_BUTTON_OPTIONS:
|
||||
event->buf[1] = state ? 0xac : 0x8c;
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
case CHIAKI_CONTROLLER_BUTTON_SHARE:
|
||||
event->buf[1] = state ? 0xad : 0x8d;
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
case CHIAKI_CONTROLLER_BUTTON_TOUCHPAD:
|
||||
event->buf[1] = state ? 0xb1 : 0x91;
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
case CHIAKI_CONTROLLER_BUTTON_PS:
|
||||
event->buf[1] = state ? 0xae : 0x8e;
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
default:
|
||||
return CHIAKI_ERR_INVALID_DATA;
|
||||
}
|
||||
event->buf[2] = state;
|
||||
event->len = 3;
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_feedback_history_buffer_init(ChiakiFeedbackHistoryBuffer *feedback_history_buffer, size_t size)
|
||||
{
|
||||
feedback_history_buffer->events = calloc(size, sizeof(ChiakiFeedbackHistoryEvent));
|
||||
if(!feedback_history_buffer->events)
|
||||
return CHIAKI_ERR_MEMORY;
|
||||
feedback_history_buffer->size = size;
|
||||
feedback_history_buffer->begin = 0;
|
||||
feedback_history_buffer->len = 0;
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
CHIAKI_EXPORT void chiaki_feedback_history_buffer_fini(ChiakiFeedbackHistoryBuffer *feedback_history_buffer)
|
||||
{
|
||||
free(feedback_history_buffer->events);
|
||||
}
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_feedback_history_buffer_format(ChiakiFeedbackHistoryBuffer *feedback_history_buffer, uint8_t *buf, size_t *buf_size)
|
||||
{
|
||||
size_t size_max = *buf_size;
|
||||
size_t written = 0;
|
||||
|
||||
for(size_t i=0; i<feedback_history_buffer->len; i++)
|
||||
{
|
||||
ChiakiFeedbackHistoryEvent *event = &feedback_history_buffer->events[(feedback_history_buffer->begin + i) % feedback_history_buffer->size];
|
||||
if(written + event->len > size_max)
|
||||
return CHIAKI_ERR_BUF_TOO_SMALL;
|
||||
memcpy(buf + written, event->buf, event->len);
|
||||
written += event->len;
|
||||
}
|
||||
|
||||
*buf_size = written;
|
||||
return CHIAKI_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
CHIAKI_EXPORT void chiaki_feedback_history_buffer_push(ChiakiFeedbackHistoryBuffer *feedback_history_buffer, ChiakiFeedbackHistoryEvent *event)
|
||||
{
|
||||
feedback_history_buffer->begin = (feedback_history_buffer->begin + feedback_history_buffer->size - 1) % feedback_history_buffer->size;
|
||||
feedback_history_buffer->len++;
|
||||
if(feedback_history_buffer->len >= feedback_history_buffer->size)
|
||||
feedback_history_buffer->len = feedback_history_buffer->size;
|
||||
feedback_history_buffer->events[feedback_history_buffer->begin] = *event;
|
||||
}
|
|
@ -20,6 +20,8 @@
|
|||
#define FEEDBACK_STATE_TIMEOUT_MIN_MS 8 // minimum time to wait between sending 2 packets
|
||||
#define FEEDBACK_STATE_TIMEOUT_MAX_MS 200 // maximum time to wait between sending 2 packets
|
||||
|
||||
#define FEEDBACK_HISTORY_BUFFER_SIZE 0x10
|
||||
|
||||
static void *feedback_sender_thread_func(void *user);
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_feedback_sender_init(ChiakiFeedbackSender *feedback_sender, ChiakiTakion *takion)
|
||||
|
@ -32,10 +34,15 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_feedback_sender_init(ChiakiFeedbackSender *
|
|||
|
||||
feedback_sender->state_seq_num = 0;
|
||||
|
||||
ChiakiErrorCode err = chiaki_mutex_init(&feedback_sender->state_mutex, false);
|
||||
feedback_sender->history_seq_num = 0;
|
||||
ChiakiErrorCode err = chiaki_feedback_history_buffer_init(&feedback_sender->history_buf, FEEDBACK_HISTORY_BUFFER_SIZE);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
return err;
|
||||
|
||||
err = chiaki_mutex_init(&feedback_sender->state_mutex, false);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
goto error_history_buffer;
|
||||
|
||||
err = chiaki_cond_init(&feedback_sender->state_cond);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
goto error_mutex;
|
||||
|
@ -49,6 +56,8 @@ error_cond:
|
|||
chiaki_cond_fini(&feedback_sender->state_cond);
|
||||
error_mutex:
|
||||
chiaki_mutex_fini(&feedback_sender->state_mutex);
|
||||
error_history_buffer:
|
||||
chiaki_feedback_history_buffer_fini(&feedback_sender->history_buf);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -61,6 +70,7 @@ CHIAKI_EXPORT void chiaki_feedback_sender_fini(ChiakiFeedbackSender *feedback_se
|
|||
chiaki_thread_join(&feedback_sender->thread, NULL);
|
||||
chiaki_cond_fini(&feedback_sender->state_cond);
|
||||
chiaki_mutex_fini(&feedback_sender->state_mutex);
|
||||
chiaki_feedback_history_buffer_fini(&feedback_sender->history_buf);
|
||||
}
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_feedback_sender_set_controller_state(ChiakiFeedbackSender *feedback_sender, ChiakiControllerState *state)
|
||||
|
@ -84,10 +94,17 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_feedback_sender_set_controller_state(Chiaki
|
|||
return CHIAKI_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
static bool controller_state_equals_for_feedback_state(ChiakiControllerState *a, ChiakiControllerState *b)
|
||||
{
|
||||
return a->left_x == b->left_x
|
||||
&& a->left_y == b->left_y
|
||||
&& a->right_x == b->right_x
|
||||
&& a->right_y == b->right_y;
|
||||
}
|
||||
|
||||
static void feedback_sender_send_state(ChiakiFeedbackSender *feedback_sender)
|
||||
{
|
||||
ChiakiFeedbackState state;
|
||||
state.buttons = feedback_sender->controller_state.buttons;
|
||||
state.left_x = feedback_sender->controller_state.left_x;
|
||||
state.left_y = feedback_sender->controller_state.left_y;
|
||||
state.right_x = feedback_sender->controller_state.right_x;
|
||||
|
@ -97,6 +114,53 @@ static void feedback_sender_send_state(ChiakiFeedbackSender *feedback_sender)
|
|||
CHIAKI_LOGE(feedback_sender->log, "FeedbackSender failed to send Feedback State\n");
|
||||
}
|
||||
|
||||
static bool controller_state_equals_for_feedback_history(ChiakiControllerState *a, ChiakiControllerState *b)
|
||||
{
|
||||
return a->buttons == b->buttons;
|
||||
}
|
||||
|
||||
static void feedback_sender_send_history(ChiakiFeedbackSender *feedback_sender)
|
||||
{
|
||||
// TODO: Is it legal to have more than one new event per packet?
|
||||
size_t new_events_count = 0;
|
||||
uint64_t buttons_prev = feedback_sender->controller_state_prev.buttons;
|
||||
uint64_t buttons_now = feedback_sender->controller_state.buttons;
|
||||
for(uint8_t i=0; i<CHIAKI_CONTROLLER_BUTTONS_COUNT; i++)
|
||||
{
|
||||
uint64_t button_id = 1 << i;
|
||||
bool prev = buttons_prev & button_id;
|
||||
bool now = buttons_now & button_id;
|
||||
if(prev != now)
|
||||
{
|
||||
ChiakiFeedbackHistoryEvent event;
|
||||
ChiakiErrorCode err = chiaki_feedback_history_event_set_button(&event, button_id, now ? 0xff : 0);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
{
|
||||
CHIAKI_LOGE(feedback_sender->log, "Feedback Sender failed to format button history event for button id %llu\n", (unsigned long long)button_id);
|
||||
continue;
|
||||
}
|
||||
chiaki_feedback_history_buffer_push(&feedback_sender->history_buf, &event);
|
||||
new_events_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if(!new_events_count) // TODO: also send on timeout sometimes?
|
||||
return;
|
||||
|
||||
uint8_t buf[0x300];
|
||||
size_t buf_size = sizeof(buf);
|
||||
ChiakiErrorCode err = chiaki_feedback_history_buffer_format(&feedback_sender->history_buf, buf, &buf_size);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
{
|
||||
CHIAKI_LOGE(feedback_sender->log, "Feedback Sender failed to format history buffer\n");
|
||||
return;
|
||||
}
|
||||
|
||||
CHIAKI_LOGD(feedback_sender->log, "Feedback History:\n");
|
||||
chiaki_log_hexdump(feedback_sender->log, CHIAKI_LOG_DEBUG, buf, buf_size);
|
||||
chiaki_takion_send_feedback_history(feedback_sender->takion, feedback_sender->history_seq_num++, buf, buf_size);
|
||||
}
|
||||
|
||||
static bool state_cond_check(void *user)
|
||||
{
|
||||
ChiakiFeedbackSender *feedback_sender = user;
|
||||
|
@ -121,14 +185,27 @@ static void *feedback_sender_thread_func(void *user)
|
|||
if(feedback_sender->should_stop)
|
||||
break;
|
||||
|
||||
bool send_feedback_state = true;
|
||||
bool send_feedback_history = false;
|
||||
|
||||
if(feedback_sender->controller_state_changed)
|
||||
{
|
||||
// TODO: FEEDBACK_STATE_TIMEOUT_MIN_MS
|
||||
feedback_sender->controller_state_changed = false;
|
||||
}
|
||||
|
||||
// don't need to send feedback state if nothing relevant changed
|
||||
if(controller_state_equals_for_feedback_state(&feedback_sender->controller_state, &feedback_sender->controller_state_prev))
|
||||
send_feedback_state = false;
|
||||
|
||||
send_feedback_history = !controller_state_equals_for_feedback_history(&feedback_sender->controller_state, &feedback_sender->controller_state_prev);
|
||||
} // else: timeout
|
||||
|
||||
if(send_feedback_state)
|
||||
feedback_sender_send_state(feedback_sender);
|
||||
|
||||
if(send_feedback_history)
|
||||
feedback_sender_send_history(feedback_sender);
|
||||
|
||||
feedback_sender->controller_state_prev = feedback_sender->controller_state;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_mirai_init(ChiakiMirai *mirai)
|
|||
{
|
||||
mirai->request = -1;
|
||||
mirai->response = -1;
|
||||
ChiakiErrorCode err = chiaki_mutex_init(&mirai->mutex);
|
||||
ChiakiErrorCode err = chiaki_mutex_init(&mirai->mutex, false);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
return err;
|
||||
err = chiaki_cond_init(&mirai->cond);
|
||||
|
|
|
@ -408,6 +408,38 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_congestion(ChiakiTakion *takion
|
|||
return chiaki_takion_send_raw(takion, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
static ChiakiErrorCode takion_send_feedback_packet(ChiakiTakion *takion, uint8_t *buf, size_t buf_size)
|
||||
{
|
||||
assert(buf_size >= 0xc);
|
||||
|
||||
size_t payload_size = buf_size - 0xc;
|
||||
|
||||
ChiakiErrorCode err = chiaki_mutex_lock(&takion->gkcrypt_local_mutex);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
return err;
|
||||
|
||||
size_t key_pos;
|
||||
err = chiaki_takion_crypt_advance_key_pos(takion, payload_size + CHIAKI_GKCRYPT_BLOCK_SIZE, &key_pos);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
goto beach;
|
||||
|
||||
err = chiaki_gkcrypt_encrypt(takion->gkcrypt_local, key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, buf + 0xc, payload_size);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
goto beach;
|
||||
|
||||
*((uint32_t *)(buf + 4)) = htonl((uint32_t)key_pos);
|
||||
|
||||
err = chiaki_gkcrypt_gmac(takion->gkcrypt_local, key_pos, buf, buf_size, buf + 8);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
goto beach;
|
||||
|
||||
chiaki_takion_send_raw(takion, buf, buf_size);
|
||||
|
||||
beach:
|
||||
chiaki_mutex_unlock(&takion->gkcrypt_local_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_feedback_state(ChiakiTakion *takion, ChiakiSeqNum16 seq_num, ChiakiFeedbackState *feedback_state)
|
||||
{
|
||||
uint8_t buf[0xc + CHIAKI_FEEDBACK_STATE_BUF_SIZE];
|
||||
|
@ -417,33 +449,23 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_feedback_state(ChiakiTakion *ta
|
|||
*((uint32_t *)(buf + 4)) = 0; // key pos
|
||||
*((uint32_t *)(buf + 8)) = 0; // gmac
|
||||
chiaki_feedback_state_format(buf + 0xc, feedback_state);
|
||||
return takion_send_feedback_packet(takion, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
//CHIAKI_LOGD(takion->log, "Takion sending Feedback State:\n");
|
||||
//chiaki_log_hexdump(takion->log, CHIAKI_LOG_DEBUG, buf, sizeof(buf));
|
||||
|
||||
ChiakiErrorCode err = chiaki_mutex_lock(&takion->gkcrypt_local_mutex);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
return err;
|
||||
|
||||
size_t key_pos;
|
||||
err = chiaki_takion_crypt_advance_key_pos(takion, CHIAKI_FEEDBACK_STATE_BUF_SIZE + CHIAKI_GKCRYPT_BLOCK_SIZE, &key_pos);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
goto beach;
|
||||
|
||||
err = chiaki_gkcrypt_encrypt(takion->gkcrypt_local, key_pos + CHIAKI_GKCRYPT_BLOCK_SIZE, buf + 0xc, CHIAKI_FEEDBACK_STATE_BUF_SIZE);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
goto beach;
|
||||
|
||||
*((uint32_t *)(buf + 4)) = htonl((uint32_t)key_pos);
|
||||
|
||||
err = chiaki_gkcrypt_gmac(takion->gkcrypt_local, key_pos, buf, sizeof(buf), buf + 8);
|
||||
if(err != CHIAKI_ERR_SUCCESS)
|
||||
goto beach;
|
||||
|
||||
chiaki_takion_send_raw(takion, buf, sizeof(buf));
|
||||
|
||||
beach:
|
||||
chiaki_mutex_unlock(&takion->gkcrypt_local_mutex);
|
||||
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_feedback_history(ChiakiTakion *takion, ChiakiSeqNum16 seq_num, uint8_t *payload, size_t payload_size)
|
||||
{
|
||||
size_t buf_size = 0xc + payload_size;
|
||||
uint8_t *buf = malloc(buf_size);
|
||||
if(!buf)
|
||||
return CHIAKI_ERR_MEMORY;
|
||||
buf[0] = TAKION_PACKET_TYPE_FEEDBACK_HISTORY;
|
||||
*((uint16_t *)(buf + 1)) = htons(seq_num);
|
||||
buf[3] = 0; // TODO
|
||||
*((uint32_t *)(buf + 4)) = 0; // key pos
|
||||
*((uint32_t *)(buf + 8)) = 0; // gmac
|
||||
memcpy(buf + 0xc, payload, payload_size);
|
||||
ChiakiErrorCode err = takion_send_feedback_packet(takion, buf, buf_size);
|
||||
free(buf);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue