diff --git a/segatools/aimeio/aimeio.c b/segatools/aimeio/aimeio.c index f36755a..67e6881 100644 --- a/segatools/aimeio/aimeio.c +++ b/segatools/aimeio/aimeio.c @@ -26,7 +26,7 @@ static uint8_t aime_io_felica_id[8]; static bool aime_io_aime_id_present; static bool aime_io_felica_id_present; -struct IPCMemoryInfo +struct aime_io_ipc_memory_info { uint8_t airIoStatus[6]; uint8_t sliderIoStatus[32]; @@ -35,28 +35,31 @@ struct IPCMemoryInfo uint8_t serviceBtn; uint8_t coinInsertion; uint8_t cardRead; + uint8_t remoteCardRead; + uint8_t remoteCardType; + uint8_t remoteCardId[10]; }; -typedef struct IPCMemoryInfo IPCMemoryInfo; -static HANDLE FileMappingHandle; -IPCMemoryInfo* FileMapping; +typedef struct aime_io_ipc_memory_info aime_io_ipc_memory_info; +static HANDLE aime_io_file_mapping_handle; +aime_io_ipc_memory_info* aime_io_file_mapping; -void initSharedMemory() +void aime_io_init_shared_memory() { - if (FileMapping) + if (aime_io_file_mapping) { return; } - if ((FileMappingHandle = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, sizeof(IPCMemoryInfo), "Local\\BROKENITHM_SHARED_BUFFER")) == 0) + if ((aime_io_file_mapping_handle = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, sizeof(aime_io_ipc_memory_info), "Local\\BROKENITHM_SHARED_BUFFER")) == 0) { return; } - if ((FileMapping = (IPCMemoryInfo*)MapViewOfFile(FileMappingHandle, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(IPCMemoryInfo))) == 0) + if ((aime_io_file_mapping = (aime_io_ipc_memory_info*)MapViewOfFile(aime_io_file_mapping_handle, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(aime_io_ipc_memory_info))) == 0) { return; } - memset(FileMapping, 0, sizeof(IPCMemoryInfo)); + memset(aime_io_file_mapping, 0, sizeof(aime_io_ipc_memory_info)); SetThreadExecutionState(ES_DISPLAY_REQUIRED | ES_CONTINUOUS); } @@ -196,19 +199,20 @@ static HRESULT aime_io_generate_felica( return S_OK; } +uint16_t aime_io_get_api_version(void) +{ + return 0x0100; +} + HRESULT aime_io_init(void) { aime_io_config_read(&aime_io_cfg, L".\\segatools.ini"); - initSharedMemory(); + aime_io_init_shared_memory(); return S_OK; } -void aime_io_fini(void) -{ -} - HRESULT aime_io_nfc_poll(uint8_t unit_no) { bool sense; @@ -223,11 +227,27 @@ HRESULT aime_io_nfc_poll(uint8_t unit_no) aime_io_aime_id_present = false; aime_io_felica_id_present = false; + /* First check remote card status, if there is one report it */ + + if (aime_io_file_mapping && aime_io_file_mapping->remoteCardRead) { + switch (aime_io_file_mapping->remoteCardType) { + case 0: // Aime + memcpy(aime_io_aime_id, aime_io_file_mapping->remoteCardId, 10); + aime_io_aime_id_present = true; + break; + case 1: // FeliCa + memcpy(aime_io_felica_id, aime_io_file_mapping->remoteCardId, 8); + aime_io_felica_id_present = true; + break; + } + return S_OK; + } + /* Don't do anything more if the scan key is not held */ - if (FileMapping && FileMapping->cardRead) { + if (aime_io_file_mapping && aime_io_file_mapping->cardRead) { sense = true; - FileMapping->cardRead = 0; + aime_io_file_mapping->cardRead = 0; } else { sense = GetAsyncKeyState(aime_io_cfg.vk_scan) & 0x8000; } diff --git a/segatools/chuniio/chuniio.c b/segatools/chuniio/chuniio.c index ccb34c1..ce921e1 100644 --- a/segatools/chuniio/chuniio.c +++ b/segatools/chuniio/chuniio.c @@ -11,11 +11,12 @@ static unsigned int __stdcall chuni_io_slider_thread_proc(void *ctx); static bool chuni_io_coin; static uint16_t chuni_io_coins; +static uint8_t chuni_io_hand_pos; static HANDLE chuni_io_slider_thread; static bool chuni_io_slider_stop_flag; static struct chuni_io_config chuni_io_cfg; -struct IPCMemoryInfo +struct chuni_io_ipc_memory_info { uint8_t airIoStatus[6]; uint8_t sliderIoStatus[32]; @@ -24,36 +25,44 @@ struct IPCMemoryInfo uint8_t serviceBtn; uint8_t coinInsertion; uint8_t cardRead; + uint8_t remoteCardRead; + uint8_t remoteCardType; + uint8_t remoteCardId[10]; }; -typedef struct IPCMemoryInfo IPCMemoryInfo; -static HANDLE FileMappingHandle; -IPCMemoryInfo* FileMapping; +typedef struct chuni_io_ipc_memory_info chuni_io_ipc_memory_info; +static HANDLE chuni_io_file_mapping_handle; +chuni_io_ipc_memory_info* chuni_io_file_mapping; -void initSharedMemory() +void chuni_io_init_shared_memory() { - if (FileMapping) + if (chuni_io_file_mapping) { return; } - if ((FileMappingHandle = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, sizeof(IPCMemoryInfo), "Local\\BROKENITHM_SHARED_BUFFER")) == 0) + if ((chuni_io_file_mapping_handle = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, sizeof(chuni_io_ipc_memory_info), "Local\\BROKENITHM_SHARED_BUFFER")) == 0) { return; } - if ((FileMapping = (IPCMemoryInfo*)MapViewOfFile(FileMappingHandle, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(IPCMemoryInfo))) == 0) + if ((chuni_io_file_mapping = (chuni_io_ipc_memory_info*)MapViewOfFile(chuni_io_file_mapping_handle, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(chuni_io_ipc_memory_info))) == 0) { return; } - memset(FileMapping, 0, sizeof(IPCMemoryInfo)); + memset(chuni_io_file_mapping, 0, sizeof(chuni_io_ipc_memory_info)); SetThreadExecutionState(ES_DISPLAY_REQUIRED | ES_CONTINUOUS); } +uint16_t chuni_io_get_api_version(void) +{ + return 0x0101; +} + HRESULT chuni_io_jvs_init(void) { chuni_io_config_load(&chuni_io_cfg, L".\\segatools.ini"); - initSharedMemory(); + chuni_io_init_shared_memory(); return S_OK; } @@ -64,9 +73,9 @@ void chuni_io_jvs_read_coin_counter(uint16_t *out) return; } - if (FileMapping && FileMapping->coinInsertion) { + if (chuni_io_file_mapping && chuni_io_file_mapping->coinInsertion) { chuni_io_coins++; - FileMapping->coinInsertion = 0; + chuni_io_file_mapping->coinInsertion = 0; } else { if (GetAsyncKeyState(chuni_io_cfg.vk_coin)) { if (!chuni_io_coin) { @@ -85,24 +94,31 @@ void chuni_io_jvs_poll(uint8_t *opbtn, uint8_t *beams) { size_t i; - if ((FileMapping && FileMapping->testBtn) || GetAsyncKeyState(chuni_io_cfg.vk_test)) { + if ((chuni_io_file_mapping && chuni_io_file_mapping->testBtn) || GetAsyncKeyState(chuni_io_cfg.vk_test)) { *opbtn |= 0x01; /* Test */ } - if ((FileMapping && FileMapping->serviceBtn) || GetAsyncKeyState(chuni_io_cfg.vk_service)) { + if ((chuni_io_file_mapping && chuni_io_file_mapping->serviceBtn) || GetAsyncKeyState(chuni_io_cfg.vk_service)) { *opbtn |= 0x02; /* Service */ } + if (GetAsyncKeyState(chuni_io_cfg.vk_ir)) { + if (chuni_io_hand_pos < 6) { + chuni_io_hand_pos++; + } + } else { + if (chuni_io_hand_pos > 0) { + chuni_io_hand_pos--; + } + } + for (i = 0 ; i < 6 ; i++) { - if (FileMapping && FileMapping->airIoStatus[i]) { + if ((chuni_io_file_mapping && chuni_io_file_mapping->airIoStatus[i]) || chuni_io_hand_pos > i) { *beams |= (1 << i); } } } -void chuni_io_jvs_set_coin_blocker(bool open) -{} - HRESULT chuni_io_slider_init(void) { return S_OK; @@ -139,22 +155,21 @@ void chuni_io_slider_stop(void) void chuni_io_slider_set_leds(const uint8_t *rgb) { - if (FileMapping) - { - memcpy(FileMapping->ledRgbData, rgb, 32 * 3); + if (chuni_io_file_mapping) { + memcpy(chuni_io_file_mapping->ledRgbData, rgb, 32 * 3); } } static unsigned int __stdcall chuni_io_slider_thread_proc(void *ctx) { chuni_io_slider_callback_t callback; - uint8_t pressure[32] = { 0 }; + uint8_t pressure[32]; callback = ctx; while (!chuni_io_slider_stop_flag) { - if (FileMapping) { - memcpy(pressure, FileMapping->sliderIoStatus, 32); + if (chuni_io_file_mapping) { + memcpy(pressure, chuni_io_file_mapping->sliderIoStatus, 32); } callback(pressure); diff --git a/src/main.cpp b/src/main.cpp index 8b5b555..eae22f0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,6 +8,7 @@ #include "socket.h" #include "defer.h" #include "version.h" +#include "struct.h" #include std::string remote_address; @@ -96,7 +97,7 @@ void printErr(const char* format, Args... args) fprintf(stderr, format, args...); } -void UDPLEDBroadcast(SOCKET sHost, const char* memory) +void UDPLEDBroadcast(SOCKET sHost, const IPCMemoryInfo* memory) { static std::string previous_status; static int skip_count = 0; @@ -108,7 +109,7 @@ void UDPLEDBroadcast(SOCKET sHost, const char* memory) continue; } std::string current_status; - current_status.assign(reinterpret_cast(memory + 6 + 32), 32 * 3); + current_status.assign(reinterpret_cast(memory->ledRgbData), sizeof(memory->ledRgbData)); bool same = true; if(!previous_status.empty()) { @@ -153,7 +154,7 @@ void UDPLEDBroadcast(SOCKET sHost, const char* memory) } } -void TCPLEDBroadcast(SOCKET sHost, const char* memory) +void TCPLEDBroadcast(SOCKET sHost, const IPCMemoryInfo* memory) { static std::string previous_status; static int skip_count = 0; @@ -165,7 +166,7 @@ void TCPLEDBroadcast(SOCKET sHost, const char* memory) continue; } std::string current_status; - current_status.assign(reinterpret_cast(memory + 6 + 32), 32 * 3); + current_status.assign(reinterpret_cast(memory->ledRgbData), sizeof(memory->ledRgbData)); bool same = true; if(!previous_status.empty()) { @@ -234,23 +235,22 @@ enum FUNCTION_CARD }; -std::tuple getSocksAddress(const std::string &data) +void getSocksAddress(const PacketConnect* pkt, std::string &address, uint16_t &port) { char cAddr[128] = {}; - std::string retAddr, port_str = data.substr(1, 2); - int family = data[0]; - uint16_t port = ntohs(*(short*)port_str.data()); + std::string retAddr; + int family = pkt->addrType; + port = ntohs(pkt->port); switch(family) { case 1: //IPv4 - inet_ntop(AF_INET, data.data() + 3, cAddr, 127); + inet_ntop(AF_INET, pkt->addr.addr4.addr, cAddr, 127); break; case 2: //IPv6 - inet_ntop(AF_INET6, data.data() + 3, cAddr, 127); + inet_ntop(AF_INET6, pkt->addr.addr6, cAddr, 127); break; } - retAddr.assign(cAddr); - return std::make_tuple(retAddr, port); + address.assign(cAddr); } uint32_t last_input_packet_id = 0; @@ -272,7 +272,85 @@ void updatePacketId(uint32_t newPacketId) last_input_packet_id = newPacketId; } -void InputReceive(SOCKET sHost, char *memory) +template +void dprintf(const char* format, Args... args) +{ + fprintf(stderr, format, args...); +} + +void dump(const void *ptr, size_t nbytes, bool hex_string = false) +{ + const uint8_t *bytes; + uint8_t c; + size_t i; + size_t j; + + if (nbytes == 0) { + dprintf("\t--- Empty ---\n"); + } + + bytes = (const unsigned char*)ptr; + + if (hex_string) { + for (i = 0 ; i < nbytes ; i++) { + dprintf("%02x", bytes[i]); + } + dprintf("\n"); + return; + } + + for (i = 0 ; i < nbytes ; i += 16) { + dprintf(" %08x:", (int) i); + + for (j = 0 ; i + j < nbytes && j < 16 ; j++) { + dprintf(" %02x", bytes[i + j]); + } + + while (j < 16) { + dprintf(" "); + j++; + } + + dprintf(" "); + + for (j = 0 ; i + j < nbytes && j < 16 ; j++) { + c = bytes[i + j]; + + if (c < 0x20 || c >= 0x7F) { + c = '.'; + } + + dprintf("%c", c); + } + + dprintf("\n"); + } + + dprintf("\n"); +} + +enum +{ + CARD_AIME, + CARD_FELICA +}; + +void printCardInfo(uint8_t cardType, uint8_t *cardId) +{ + switch(cardType) + { + case CARD_AIME: + printErr("[INFO] Card Type: Aime\t\tID: "); + dump(cardId, 10, true); + break; + case CARD_FELICA: + printErr("[INFO] Card Type: FeliCa\tIDm: "); + dump(cardId, 8, true); + break; + } +} + +void InputReceive(SOCKET sHost, IPCMemoryInfo *memory) { char recv_buffer[tcp_buffer_size]; char buffer[BUFSIZ]; @@ -280,6 +358,7 @@ void InputReceive(SOCKET sHost, char *memory) while(!EXIT_FLAG) { int recv_len, real_len; + size_t packet_len; uint32_t current_packet_id; if(!tcp_mode) { @@ -293,6 +372,7 @@ void InputReceive(SOCKET sHost, char *memory) real_len = buffer[0]; if(real_len > recv_len) continue; + packet_len = real_len + 1; } else { @@ -311,54 +391,52 @@ void InputReceive(SOCKET sHost, char *memory) real_len = remains[0]; if(real_len > data_left) continue; - size_t data_copied = real_len + 1; - memcpy(buffer, remains.data(), data_copied); - remains.erase(0, data_copied); + packet_len = real_len + 1; + memcpy(buffer, remains.data(), packet_len); + remains.erase(0, packet_len); } - if(real_len >= 3 + 4 + 6 + 32 && buffer[1] == 'I' && buffer[2] == 'N' && buffer[3] == 'P') + if(packet_len >= sizeof(PacketInput) && buffer[1] == 'I' && buffer[2] == 'N' && buffer[3] == 'P') { - memcpy(memory, buffer + 4 + 4, 32 + 6); - if(real_len > 3 + 4 + 6 + 32) - { - memcpy(memory + 6 + 32 + 96, buffer + 4 + 4 + 6 + 32, real_len - (3 + 6 + 32 + 4)); - } - current_packet_id = ntohl(*(uint32_t*)(buffer + 4)); + PacketInput *pkt = reinterpret_cast(buffer); + memcpy(memory->airIoStatus, pkt->airIoStatus, sizeof(pkt->airIoStatus)); + memcpy(memory->sliderIoStatus, pkt->sliderIoStatus, sizeof(pkt->sliderIoStatus)); + memory->testBtn = pkt->testBtn; + memory->serviceBtn = pkt->serviceBtn; + current_packet_id = ntohl(pkt->packetId); updatePacketId(current_packet_id); } - else if(real_len >= 3 + 4 + 32 && buffer[1] == 'I' && buffer[2] == 'P' && buffer[3] == 'T') /// without air block + else if(packet_len >= sizeof(PacketInputNoAir) && buffer[1] == 'I' && buffer[2] == 'P' && buffer[3] == 'T') /// without air block { - memcpy(memory + 6, buffer + 4 + 4, 32); - if(real_len > 3 + 4 + 32) - { - memcpy(memory + 6 + 32 + 96, buffer + 4 + 4 + 32, real_len - (3 + 32 + 4)); - } - current_packet_id = ntohl(*(uint32_t*)(buffer + 4)); + PacketInputNoAir *pkt = reinterpret_cast(buffer); + memcpy(memory->sliderIoStatus, pkt->sliderIoStatus, sizeof(pkt->sliderIoStatus)); + memory->testBtn = pkt->testBtn; + memory->serviceBtn = pkt->serviceBtn; + current_packet_id = ntohl(pkt->packetId); updatePacketId(current_packet_id); } - else if(real_len >= 4 && buffer[1] == 'F' && buffer[2] == 'N' && buffer[3] == 'C') + else if(packet_len >= sizeof(PacketFunction) && buffer[1] == 'F' && buffer[2] == 'N' && buffer[3] == 'C') { - switch(buffer[4]) + PacketFunction *pkt = reinterpret_cast(buffer); + switch(pkt->funcBtn) { case FUNCTION_COIN: - *(memory + 6 + 32 + 96 + 2) = 1; + memory->coinInsertion = 1; break; case FUNCTION_CARD: - *(memory + 6 + 32 + 96 + 3) = 1; + memory->cardRead = 1; break; } } - else if(real_len >= 10 && buffer[1] == 'C' && buffer[2] == 'O' && buffer[3] == 'N') + else if(packet_len >= sizeof(PacketConnect) && buffer[1] == 'C' && buffer[2] == 'O' && buffer[3] == 'N') { last_input_packet_id = 0; - std::string data; - data.assign(buffer + 4, real_len - 3); - std::tie(remote_address, remote_port) = getSocksAddress(data); - //std::cout << "Device " << remote_address << ":" << remote_port << " connected." <(buffer); + getSocksAddress(pkt, remote_address, remote_port); printErr("[INFO] Device %s:%d connected.\n", remote_address.data(), remote_port); CONNECTED = true; } - else if(real_len >= 3 && buffer[1] == 'D' && buffer[2] == 'I' && buffer[3] == 'S') + else if(packet_len >= 4 && buffer[1] == 'D' && buffer[2] == 'I' && buffer[3] == 'S') { CONNECTED = false; if(tcp_mode) @@ -370,11 +448,10 @@ void InputReceive(SOCKET sHost, char *memory) if(!remote_address.empty()) { printErr("[INFO] Device %s:%d disconnected.\n", remote_address.data(), remote_port); - //std::cout << "Device " << remote_address << ":" << remote_port << " disconnected." << std::endl; remote_address.clear(); } } - else if(real_len >= 11 && buffer[1] == 'P' && buffer[2] == 'I' && buffer[3] == 'N') + else if(packet_len >= sizeof(PacketPing) && buffer[1] == 'P' && buffer[2] == 'I' && buffer[3] == 'N') { if(!CONNECTED) continue; @@ -383,6 +460,31 @@ void InputReceive(SOCKET sHost, char *memory) response.replace(2, 1, "O"); udp_send(sHost, remote_address, remote_port, response); } + else if(packet_len >= sizeof(PacketCard) && buffer[1] == 'C' && buffer[2] == 'R' && buffer[3] == 'D') + { + PacketCard *pkt = reinterpret_cast(buffer); + static uint8_t lastId[10] = {}; + if(pkt->remoteCardRead) + { + if(memcmp(lastId, pkt->remoteCardId, 10)) + { + printErr("[INFO] Got remote card.\n"); + printCardInfo(pkt->remoteCardType, pkt->remoteCardId); + memcpy(lastId, pkt->remoteCardId, 10); + } + } + else + { + if(memory->remoteCardRead) + { + printErr("[INFO] Remote card removed.\n"); + memset(lastId, 0, 10); + } + } + memory->remoteCardRead = pkt->remoteCardRead; + memory->remoteCardType = pkt->remoteCardType; + memcpy(memory->remoteCardId, pkt->remoteCardId, 10); + } } } @@ -443,7 +545,7 @@ int main(int argc, char* argv[]) } } defer(CloseHandle(hMapFile)) - char *memory = reinterpret_cast(MapViewOfFileEx(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 1024, NULL)); + IPCMemoryInfo *memory = reinterpret_cast(MapViewOfFileEx(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 1024, NULL)); if(memory == nullptr) { //std::cerr << "Cannot get view of memory map! Error " + std::to_string(GetLastError()); diff --git a/src/resources.rc b/src/resources.rc index 4b068f7..3cd792a 100644 --- a/src/resources.rc +++ b/src/resources.rc @@ -8,25 +8,11 @@ #ifdef RC_INVOKED -// -// Set up debug information -// -#if DBG -#define VER_DBG VS_FF_DEBUG -#else -#define VER_DBG 0 -#endif - // ------- version info ------------------------------------------------------- VS_VERSION_INFO VERSIONINFO FILEVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,0 PRODUCTVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,0 -FILEFLAGSMASK VS_FFI_FILEFLAGSMASK -FILEFLAGS VER_DBG -FILEOS VOS_NT -FILETYPE VFT_DRV -FILESUBTYPE VFT2_DRV_SYSTEM BEGIN BLOCK "StringFileInfo" BEGIN diff --git a/src/struct.h b/src/struct.h new file mode 100644 index 0000000..4198d24 --- /dev/null +++ b/src/struct.h @@ -0,0 +1,79 @@ +#ifndef STRUCT_H_INCLUDED +#define STRUCT_H_INCLUDED + +struct IPCMemoryInfo +{ + uint8_t airIoStatus[6]; + uint8_t sliderIoStatus[32]; + uint8_t ledRgbData[32 * 3]; + uint8_t testBtn; + uint8_t serviceBtn; + uint8_t coinInsertion; + uint8_t cardRead; + uint8_t remoteCardRead; + uint8_t remoteCardType; + uint8_t remoteCardId[10]; +}; + +struct PacketInput +{ + uint8_t packetSize; + uint8_t packetName[3]; + uint32_t packetId; + uint8_t airIoStatus[6]; + uint8_t sliderIoStatus[32]; + uint8_t testBtn; + uint8_t serviceBtn; +}; + +struct PacketInputNoAir +{ + uint8_t packetSize; + uint8_t packetName[3]; + uint32_t packetId; + uint8_t sliderIoStatus[32]; + uint8_t testBtn; + uint8_t serviceBtn; +}; + +struct PacketFunction +{ + uint8_t packetSize; + uint8_t packetName[3]; + uint8_t funcBtn; +}; + +struct PacketConnect +{ + uint8_t packetSize; + uint8_t packetName[3]; + uint8_t addrType; + uint16_t port; + union + { + struct + { + uint8_t addr[4]; + uint8_t padding[12]; + } addr4; + uint8_t addr6[16]; + } addr; +}; + +struct PacketCard +{ + uint8_t packetSize; + uint8_t packetName[3]; + uint8_t remoteCardRead; + uint8_t remoteCardType; + uint8_t remoteCardId[10]; +}; + +struct PacketPing +{ + uint8_t packetSize; + uint8_t packetName[3]; + uint64_t remotePingTime; +}; + +#endif // STRUCT_H_INCLUDED