2023-04-08 22:19:09 +02:00
|
|
|
#include "./tox_ipc_client.hpp"
|
|
|
|
|
|
|
|
#include "./zpp_rpc_cldev.hpp"
|
|
|
|
|
|
|
|
#include <span>
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
using namespace zpp::bits::literals;
|
|
|
|
|
|
|
|
ToxIPCClient::ToxIPCClient(void) {
|
|
|
|
}
|
|
|
|
|
|
|
|
ToxIPCClient::~ToxIPCClient(void) {
|
|
|
|
// TODO: add free (not close) to ipc api
|
|
|
|
#if 0 // they gone, so no
|
|
|
|
ipc_mem_close(&_mem_rpc);
|
|
|
|
ipc_sem_close(&_sem_rpc_c);
|
|
|
|
ipc_sem_close(&_sem_rpc_s);
|
|
|
|
|
|
|
|
ipc_mem_close(&_mem_events);
|
|
|
|
ipc_sem_close(&_sem_events_lock);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ToxIPCClient::connect(void) {
|
|
|
|
// TODO: more cleanup?
|
|
|
|
{ // rpc
|
|
|
|
ipc_mem_init(&_mem_rpc, "solana_toxI_rpc.shm", RPC_MEM_SIZE); // 2k prob enough for now
|
|
|
|
|
|
|
|
// client expects it to exist
|
|
|
|
if (ipc_mem_open_existing(&_mem_rpc) != 0) {
|
|
|
|
std::cerr << "rpc shared mem not open\n";
|
|
|
|
ipc_mem_close(&_mem_rpc);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// client write lock (server waits on this)
|
|
|
|
ipc_sem_init(&_sem_rpc_c, "solana_toxI_rpc_client.lock");
|
|
|
|
|
|
|
|
if (ipc_sem_create(&_sem_rpc_c, 0) != 0) {
|
|
|
|
std::cerr << "failed to create sem_rpc_c\n";
|
|
|
|
ipc_mem_close(&_mem_rpc);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// server write lock (client waits on this)
|
|
|
|
ipc_sem_init(&_sem_rpc_s, "solana_toxI_rpc_server.lock");
|
|
|
|
|
|
|
|
if (ipc_sem_create(&_sem_rpc_s, 0) != 0) {
|
|
|
|
std::cerr << "failed to create sem_rpc_s\n";
|
|
|
|
ipc_mem_close(&_mem_rpc);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// if no call is in progress, both sems are 0
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // events
|
|
|
|
ipc_mem_init(&_mem_events, "solana_toxEventsI_events.shm", EVENTS_MEM_SIZE);
|
|
|
|
// server creates
|
|
|
|
if (ipc_mem_open_existing(&_mem_events) != 0) {
|
|
|
|
std::cerr << "events shared mem not open\n";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// mutex
|
|
|
|
ipc_sem_init(&_sem_events_lock, "solana_toxEventsI_events.lock");
|
|
|
|
if (ipc_sem_create(&_sem_events_lock, 1) != 0) {
|
|
|
|
std::cerr << "failed to create sem_events_lock\n";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ToxIPCClient::iterate(void) {
|
|
|
|
Tox_Events* events = nullptr;
|
|
|
|
|
|
|
|
// grap mutex
|
|
|
|
ipc_sem_decrement(&_sem_events_lock);
|
|
|
|
|
|
|
|
// read first byte
|
|
|
|
const uint8_t zbyte = ipc_mem_access(&_mem_events)[0];
|
|
|
|
if (zbyte == EVENTS_WRITTEN) {
|
|
|
|
// if WRITTEN, serl, release mutex
|
|
|
|
events = tox_events_load(ipc_mem_access(&_mem_events)+1, EVENTS_MEM_SIZE-1);
|
|
|
|
|
|
|
|
ipc_mem_access(&_mem_events)[0] = EVENTS_READ;
|
|
|
|
ipc_sem_increment(&_sem_events_lock);
|
|
|
|
} else {
|
|
|
|
// if not, release mutex exit
|
|
|
|
ipc_sem_increment(&_sem_events_lock);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// handle events
|
|
|
|
if (events == nullptr) {
|
|
|
|
std::cerr << "error: read back empty events list?\n";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
dispatchEvents(events);
|
|
|
|
|
|
|
|
tox_events_free(events);
|
|
|
|
}
|
|
|
|
|
|
|
|
Tox_Connection ToxIPCClient::toxSelfGetConnectionStatus(void) {
|
|
|
|
// we assume we can write (warn)
|
|
|
|
|
|
|
|
zpp::bits::in in{std::span{ipc_mem_access(&_mem_rpc), RPC_MEM_SIZE}};
|
|
|
|
zpp::bits::out out{std::span{ipc_mem_access(&_mem_rpc), RPC_MEM_SIZE}};
|
|
|
|
|
|
|
|
// TODO: write magic on client and server to very
|
|
|
|
|
|
|
|
// serl call
|
|
|
|
ToxI_rpc::client cl{in, out}; // ephimeral, should be cheap
|
|
|
|
|
|
|
|
// TODO: no throw
|
|
|
|
|
|
|
|
// write to mem
|
|
|
|
cl.request<"ToxI::toxSelfGetConnectionStatus"_sha1_int>().or_throw();
|
|
|
|
|
|
|
|
// inc sem
|
|
|
|
ipc_sem_increment(&_sem_rpc_c);
|
|
|
|
|
|
|
|
// wait on sem (block)
|
|
|
|
ipc_sem_decrement(&_sem_rpc_s);
|
|
|
|
|
|
|
|
// deserl res and return
|
|
|
|
return cl.response<"ToxI::toxSelfGetConnectionStatus"_sha1_int>().or_throw();
|
|
|
|
}
|
|
|
|
|
|
|
|
#define CL_SETUP_BUFS \
|
|
|
|
zpp::bits::in in{std::span{ipc_mem_access(&_mem_rpc), RPC_MEM_SIZE}}; \
|
|
|
|
zpp::bits::out out{std::span{ipc_mem_access(&_mem_rpc), RPC_MEM_SIZE}}; \
|
|
|
|
ToxI_rpc::client cl{in, out};
|
|
|
|
|
|
|
|
#define CL_REQUEST(X, ...) cl.request<"ToxI::" #X##_sha1_int>(__VA_ARGS__).or_throw();
|
|
|
|
#define CL_REQUEST_STR(X, ...) cl.request<"ToxI::" #X "_str"_sha1_int>(__VA_ARGS__).or_throw();
|
|
|
|
|
|
|
|
#define CL_SEMWAIT \
|
|
|
|
ipc_sem_increment(&_sem_rpc_c); \
|
|
|
|
ipc_sem_decrement(&_sem_rpc_s);
|
|
|
|
|
|
|
|
#define CL_RESPONSE(X) return cl.response<"ToxI::" #X##_sha1_int>().or_throw();
|
|
|
|
#define CL_RESPONSE_STR(X) return cl.response<"ToxI::" #X "_str"_sha1_int>().or_throw();
|
|
|
|
// TODO: for real?
|
|
|
|
#define CL_RESPONSE_VOID(X) cl.response<"ToxI::" #X##_sha1_int>().or_throw();
|
|
|
|
|
|
|
|
#define CL_BODY(X, ...) \
|
|
|
|
CL_SETUP_BUFS \
|
|
|
|
CL_REQUEST(X, __VA_ARGS__) \
|
|
|
|
CL_SEMWAIT \
|
|
|
|
CL_RESPONSE(X)
|
|
|
|
|
|
|
|
#define CL_BODY_STR(X, ...) \
|
|
|
|
CL_SETUP_BUFS \
|
|
|
|
CL_REQUEST_STR(X, __VA_ARGS__) \
|
|
|
|
CL_SEMWAIT \
|
|
|
|
CL_RESPONSE_STR(X)
|
|
|
|
|
|
|
|
#define CL_BODY_VOID(X, ...) \
|
|
|
|
CL_SETUP_BUFS \
|
|
|
|
CL_REQUEST(X, __VA_ARGS__) \
|
|
|
|
CL_SEMWAIT
|
|
|
|
// TODO: response with void?
|
|
|
|
|
|
|
|
uint32_t ToxIPCClient::toxIterationInterval(void) {
|
|
|
|
CL_BODY(toxIterationInterval)
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<uint8_t> ToxIPCClient::toxSelfGetAddress(void) {
|
|
|
|
CL_BODY(toxSelfGetAddress)
|
|
|
|
}
|
|
|
|
|
|
|
|
void ToxIPCClient::toxSelfSetNospam(uint32_t nospam) {
|
|
|
|
CL_BODY_VOID(toxSelfSetNospam, nospam)
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t ToxIPCClient::toxSelfGetNospam(void) {
|
|
|
|
CL_BODY(toxSelfGetNospam)
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<uint8_t> ToxIPCClient::toxSelfGetPublicKey(void) {
|
|
|
|
CL_BODY(toxSelfGetPublicKey)
|
|
|
|
}
|
|
|
|
|
|
|
|
Tox_Err_Set_Info ToxIPCClient::toxSelfSetName(std::string_view name) {
|
|
|
|
CL_BODY(toxSelfSetName, std::string{name})
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string ToxIPCClient::toxSelfGetName(void) {
|
|
|
|
CL_BODY(toxSelfGetName)
|
|
|
|
}
|
|
|
|
|
|
|
|
Tox_Err_Set_Info ToxIPCClient::toxSelfSetStatusMessage(std::string_view status_message) {
|
|
|
|
CL_BODY(toxSelfSetStatusMessage, std::string{status_message})
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string ToxIPCClient::toxSelfGetStatusMessage(void) {
|
|
|
|
CL_BODY(toxSelfGetStatusMessage)
|
|
|
|
}
|
|
|
|
|
|
|
|
void ToxIPCClient::toxSelfSetStatus(Tox_User_Status status) {
|
|
|
|
CL_BODY_VOID(toxSelfSetStatus, status)
|
|
|
|
}
|
|
|
|
|
|
|
|
Tox_User_Status ToxIPCClient::toxSelfGetStatus(void) {
|
|
|
|
CL_BODY(toxSelfGetStatus)
|
|
|
|
}
|
|
|
|
|
|
|
|
std::tuple<std::optional<uint32_t>, Tox_Err_Friend_Add> ToxIPCClient::toxFriendAdd(const std::vector<uint8_t>& address, std::string_view message) {
|
|
|
|
CL_BODY(toxFriendAdd, address, std::string{message})
|
|
|
|
}
|
|
|
|
|
|
|
|
std::tuple<std::optional<uint32_t>, Tox_Err_Friend_Add> ToxIPCClient::toxFriendAddNorequest(const std::vector<uint8_t>& public_key) {
|
|
|
|
CL_BODY(toxFriendAddNorequest, public_key)
|
|
|
|
}
|
|
|
|
|
|
|
|
Tox_Err_Friend_Delete ToxIPCClient::toxFriendDelete(uint32_t friend_number) {
|
|
|
|
CL_BODY(toxFriendDelete, friend_number)
|
|
|
|
}
|
|
|
|
|
2023-04-18 17:32:54 +02:00
|
|
|
std::tuple<std::optional<uint32_t>, Tox_Err_Friend_By_Public_Key> ToxIPCClient::toxFriendByPublicKey(const std::vector<uint8_t>& public_key) {
|
|
|
|
CL_BODY(toxFriendByPublicKey, public_key)
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ToxIPCClient::toxFriendExists(uint32_t friend_number) {
|
|
|
|
CL_BODY(toxFriendExists, friend_number)
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<std::vector<uint8_t>> ToxIPCClient::toxFriendGetPublicKey(uint32_t friend_number) {
|
2023-04-08 22:19:09 +02:00
|
|
|
CL_BODY(toxFriendGetPublicKey, friend_number)
|
|
|
|
}
|
|
|
|
|
2023-04-18 17:32:54 +02:00
|
|
|
std::optional<uint64_t> ToxIPCClient::toxFriendGetLastOnline(uint32_t friend_number) {
|
|
|
|
CL_BODY(toxFriendGetLastOnline, friend_number)
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<std::string> ToxIPCClient::toxFriendGetName(uint32_t friend_number) {
|
|
|
|
CL_BODY(toxFriendGetName, friend_number)
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<std::string> ToxIPCClient::toxFriendGetStatusMessage(uint32_t friend_number) {
|
|
|
|
CL_BODY(toxFriendGetStatusMessage, friend_number)
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<Tox_User_Status> ToxIPCClient::toxFriendGetStatus(uint32_t friend_number) {
|
|
|
|
CL_BODY(toxFriendGetStatus, friend_number)
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<Tox_Connection> ToxIPCClient::toxFriendGetConnectionStatus(uint32_t friend_number) {
|
|
|
|
CL_BODY(toxFriendGetConnectionStatus, friend_number)
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<bool> ToxIPCClient::toxFriendGetTyping(uint32_t friend_number) {
|
|
|
|
CL_BODY(toxFriendGetTyping, friend_number)
|
|
|
|
}
|
|
|
|
|
|
|
|
Tox_Err_Set_Typing ToxIPCClient::toxSelfSetTyping(uint32_t friend_number, bool typing) {
|
|
|
|
CL_BODY(toxSelfSetTyping, friend_number, typing)
|
|
|
|
}
|
|
|
|
|
2023-04-08 22:19:09 +02:00
|
|
|
std::tuple<std::optional<uint32_t>, Tox_Err_Friend_Send_Message> ToxIPCClient::toxFriendSendMessage(uint32_t friend_number, Tox_Message_Type type, std::string_view message) {
|
|
|
|
CL_BODY(toxFriendSendMessage, friend_number, type, std::string{message})
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<uint8_t> ToxIPCClient::toxHash(const std::vector<uint8_t>& data) {
|
|
|
|
CL_BODY(toxHash, data)
|
|
|
|
}
|
|
|
|
|
2023-04-10 00:37:57 +02:00
|
|
|
Tox_Err_File_Control ToxIPCClient::toxFileControl(uint32_t friend_number, uint32_t file_number, Tox_File_Control control) {
|
|
|
|
CL_BODY(toxFileControl, friend_number, file_number, control)
|
|
|
|
}
|
|
|
|
|
|
|
|
Tox_Err_File_Seek ToxIPCClient::toxFileSeek(uint32_t friend_number, uint32_t file_number, uint64_t position) {
|
|
|
|
CL_BODY(toxFileSeek, friend_number, file_number, position)
|
|
|
|
}
|
|
|
|
|
|
|
|
std::tuple<std::optional<std::vector<uint8_t>>, Tox_Err_File_Get> ToxIPCClient::toxFileGetFileID(uint32_t friend_number, uint32_t file_number) {
|
|
|
|
CL_BODY(toxFileGetFileID, friend_number, file_number)
|
|
|
|
}
|
|
|
|
|
|
|
|
std::tuple<std::optional<uint32_t>, Tox_Err_File_Send> ToxIPCClient::toxFileSend(uint32_t friend_number, uint32_t kind, uint64_t file_size, const std::vector<uint8_t>& file_id, std::string_view filename) {
|
|
|
|
CL_BODY(toxFileSend, friend_number, kind, file_size, file_id, std::string{filename})
|
|
|
|
}
|
|
|
|
|
|
|
|
Tox_Err_File_Send_Chunk ToxIPCClient::toxFileSendChunk(uint32_t friend_number, uint32_t file_number, uint64_t position, const std::vector<uint8_t>& data) {
|
|
|
|
CL_BODY(toxFileSendChunk, friend_number, file_number, position, data)
|
|
|
|
}
|
|
|
|
|
2023-04-08 23:24:58 +02:00
|
|
|
std::tuple<std::optional<uint32_t>, Tox_Err_Conference_Join> ToxIPCClient::toxConferenceJoin(uint32_t friend_number, const std::vector<uint8_t>& cookie) {
|
|
|
|
CL_BODY(toxConferenceJoin, friend_number, cookie)
|
|
|
|
}
|
|
|
|
|
2023-04-08 22:19:09 +02:00
|
|
|
Tox_Err_Conference_Send_Message ToxIPCClient::toxConferenceSendMessage(uint32_t conference_number, Tox_Message_Type type, std::string_view message) {
|
|
|
|
CL_BODY(toxConferenceSendMessage, conference_number, type, std::string{message})
|
|
|
|
}
|
|
|
|
|
|
|
|
Tox_Err_Friend_Custom_Packet ToxIPCClient::toxFriendSendLossyPacket(uint32_t friend_number, const std::vector<uint8_t>& data) {
|
|
|
|
CL_BODY(toxFriendSendLossyPacket, friend_number, data)
|
|
|
|
}
|
|
|
|
|
|
|
|
Tox_Err_Friend_Custom_Packet ToxIPCClient::toxFriendSendLosslessPacket(uint32_t friend_number, const std::vector<uint8_t>& data) {
|
|
|
|
CL_BODY(toxFriendSendLosslessPacket, friend_number, data)
|
|
|
|
}
|
|
|
|
|
|
|
|
std::tuple<std::optional<uint32_t>, Tox_Err_Group_New> ToxIPCClient::toxGroupNew(Tox_Group_Privacy_State privacy_state, std::string_view group_name, std::string_view name) {
|
|
|
|
CL_BODY(toxGroupNew, privacy_state, std::string{group_name}, std::string{name})
|
|
|
|
}
|
|
|
|
|
|
|
|
std::tuple<std::optional<uint32_t>, Tox_Err_Group_Join> ToxIPCClient::toxGroupJoin(const std::vector<uint8_t>& chat_id, std::string_view name, std::string_view password) {
|
|
|
|
CL_BODY(toxGroupJoin, chat_id, std::string{name}, std::string{password})
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<bool> ToxIPCClient::toxGroupIsConnected(uint32_t group_number) {
|
|
|
|
CL_BODY(toxGroupIsConnected, group_number)
|
|
|
|
}
|
|
|
|
|
|
|
|
Tox_Err_Group_Reconnect ToxIPCClient::toxGroupReconnect(uint32_t group_number) {
|
|
|
|
CL_BODY(toxGroupReconnect, group_number)
|
|
|
|
}
|
|
|
|
|
|
|
|
Tox_Err_Group_Leave ToxIPCClient::toxGroupLeave(uint32_t group_number, std::string_view part_message) {
|
|
|
|
CL_BODY(toxGroupLeave, group_number, std::string{part_message})
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<std::string> ToxIPCClient::toxGroupSelfGetName(uint32_t group_number) {
|
|
|
|
CL_BODY(toxGroupSelfGetName, group_number)
|
|
|
|
}
|
|
|
|
|
|
|
|
std::tuple<std::optional<std::string>, Tox_Err_Group_Peer_Query> ToxIPCClient::toxGroupPeerGetName(uint32_t group_number, uint32_t peer_id) {
|
|
|
|
CL_BODY(toxGroupPeerGetName, group_number, peer_id)
|
|
|
|
}
|
|
|
|
|
|
|
|
std::tuple<std::optional<Tox_Connection>, Tox_Err_Group_Peer_Query> ToxIPCClient::toxGroupPeerGetConnectionStatus(uint32_t group_number, uint32_t peer_id) {
|
|
|
|
CL_BODY(toxGroupPeerGetConnectionStatus, group_number, peer_id)
|
|
|
|
}
|
|
|
|
|
|
|
|
Tox_Err_Group_Topic_Set ToxIPCClient::toxGroupSetTopic(uint32_t group_number, std::string_view topic) {
|
|
|
|
CL_BODY(toxGroupSetTopic, group_number, std::string{topic})
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<std::string> ToxIPCClient::toxGroupGetTopic(uint32_t group_number) {
|
|
|
|
CL_BODY(toxGroupGetTopic, group_number)
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<std::string> ToxIPCClient::toxGroupGetName(uint32_t group_number) {
|
|
|
|
CL_BODY(toxGroupGetName, group_number)
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<std::vector<uint8_t>> ToxIPCClient::toxGroupGetChatId(uint32_t group_number) {
|
|
|
|
CL_BODY(toxGroupGetChatId, group_number)
|
|
|
|
}
|
|
|
|
|
|
|
|
std::tuple<std::optional<uint32_t>, Tox_Err_Group_Send_Message> ToxIPCClient::toxGroupSendMessage(uint32_t group_number, Tox_Message_Type type, std::string_view message) {
|
|
|
|
CL_BODY(toxGroupSendMessage, group_number, type, std::string{message})
|
|
|
|
}
|
|
|
|
|
|
|
|
Tox_Err_Group_Send_Private_Message ToxIPCClient::toxGroupSendPrivateMessage(uint32_t group_number, uint32_t peer_id, Tox_Message_Type type, std::string_view message) {
|
|
|
|
CL_BODY(toxGroupSendPrivateMessage, group_number, peer_id, type, std::string{message})
|
|
|
|
}
|
|
|
|
|
|
|
|
Tox_Err_Group_Send_Custom_Packet ToxIPCClient::toxGroupSendCustomPacket(uint32_t group_number, bool lossless, const std::vector<uint8_t>& data) {
|
|
|
|
CL_BODY(toxGroupSendCustomPacket, group_number, lossless, data)
|
|
|
|
}
|
|
|
|
|
|
|
|
Tox_Err_Group_Send_Custom_Private_Packet ToxIPCClient::toxGroupSendCustomPrivatePacket(uint32_t group_number, uint32_t peer_id, bool lossless, const std::vector<uint8_t>& data) {
|
|
|
|
CL_BODY(toxGroupSendCustomPrivatePacket, group_number, peer_id, lossless, data)
|
|
|
|
}
|
|
|
|
|
|
|
|
Tox_Err_Group_Invite_Friend ToxIPCClient::toxGroupInviteFriend(uint32_t group_number, uint32_t friend_number) {
|
|
|
|
CL_BODY(toxGroupInviteFriend, group_number, friend_number)
|
|
|
|
}
|
|
|
|
|
|
|
|
std::tuple<std::optional<uint32_t>, Tox_Err_Group_Invite_Accept> ToxIPCClient::toxGroupInviteAccept(uint32_t friend_number, const std::vector<uint8_t>& invite_data, std::string_view name, std::string_view password) {
|
|
|
|
CL_BODY(toxGroupInviteAccept, friend_number, invite_data, std::string{name}, std::string{password})
|
|
|
|
}
|
|
|
|
|