Bemanitools v5.26 release

This commit is contained in:
icex2
2019-09-27 22:36:50 +02:00
commit cbd7720349
718 changed files with 62731 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
dlls += eamio
libs_eamio := geninput util
src_eamio := \
eam-api.c \
eam-impl.c \
eam-s11n.c \
+258
View File
@@ -0,0 +1,258 @@
#include <windows.h>
#include <dbt.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "bemanitools/eamio.h"
#include "bemanitools/input.h"
#include "eamio/eam-config.h"
#include "eamio/eam-impl.h"
#include "eamio/eam-s11n.h"
#include "util/fs.h"
#include "util/log.h"
#include "util/msg-thread.h"
#include "util/thread.h"
static void eam_handle_hotplug_msg(WPARAM wparam,
const DEV_BROADCAST_HDR *hdr);
static FILE *eam_io_config_open(const char *mode);
static void eam_io_config_load(void);
static void eam_io_config_save(void);
static bool eam_io_get_autogen(void);
static void eam_io_set_autogen(bool autogen);
static bool eam_io_get_alt_10k(void);
static void eam_io_set_alt_10k(bool alt_10k);
static struct hid_stub *eam_io_get_keypad_device(uint8_t unit_no);
static void eam_io_set_keypad_device(uint8_t unit_no, struct hid_stub *hid);
static const char *eam_io_get_card_path(uint8_t unit_no);
static void eam_io_set_card_path(uint8_t unit_no, const char *path);
static HANDLE eam_hinst;
static struct eam *eam_inst;
static const struct eam_io_config_api eam_io_config_api = {
.config_save = eam_io_config_save,
.get_autogen = eam_io_get_autogen,
.set_autogen = eam_io_set_autogen,
.get_alt_10k = eam_io_get_alt_10k,
.set_alt_10k = eam_io_set_alt_10k,
.get_keypad_device = eam_io_get_keypad_device,
.set_keypad_device = eam_io_set_keypad_device,
.get_card_path = eam_io_get_card_path,
.set_card_path = eam_io_set_card_path,
};
void msg_window_setup(HWND hwnd)
{
log_info("Drive insertion listener ready, thread id = %d",
(int) GetCurrentThreadId());
}
LRESULT WINAPI msg_window_proc(HWND hwnd, UINT msg, WPARAM wparam,
LPARAM lparam)
{
switch (msg) {
case WM_DEVICECHANGE:
eam_handle_hotplug_msg(wparam, (DEV_BROADCAST_HDR *) lparam);
return TRUE;
default:
return DefWindowProc(hwnd, msg, wparam, lparam);
}
}
static void eam_handle_hotplug_msg(WPARAM wparam, const DEV_BROADCAST_HDR *hdr)
{
uint32_t drives;
unsigned long bit;
const DEV_BROADCAST_VOLUME *vol;
if (wparam != DBT_DEVICEARRIVAL) {
return;
}
if (hdr->dbch_devicetype != DBT_DEVTYP_VOLUME) {
return;
}
vol = (const DEV_BROADCAST_VOLUME *) hdr;
drives = vol->dbcv_unitmask;
while (_BitScanForward(&bit, drives)) {
drives &= ~(1 << bit);
eam_impl_notify_hotplug(eam_inst, (uint8_t) bit);
}
}
void msg_window_teardown(HWND hwnd)
{
log_info("Volume insertion listener shutting down");
}
static FILE *eam_io_config_open(const char *mode)
{
return fopen_appdata("DJHACKERS", "eam_v4_22.bin", mode);
}
void eam_io_set_loggers(log_formatter_t misc, log_formatter_t info,
log_formatter_t warning, log_formatter_t fatal)
{
log_to_external(misc, info, warning, fatal);
}
bool eam_io_init(thread_create_t create, thread_join_t join,
thread_destroy_t destroy)
{
input_init(create, join, destroy);
thread_api_init(create, join, destroy);
eam_io_config_load();
msg_thread_init(eam_hinst);
return true;
}
static void eam_io_config_load(void)
{
struct eam *eam;
FILE *f;
f = eam_io_config_open("rb");
if (f == NULL) {
log_warning("Failed to open eam config, using defaults");
goto open_fail;
}
eam = eam_impl_config_load(f);
if (eam == NULL) {
log_warning("eam config is corrupted, using defaults");
goto read_fail;
}
eam_inst = eam;
fclose(f);
return;
read_fail:
fclose(f);
open_fail:
eam_inst = eam_impl_create();
}
void eam_io_fini(void)
{
msg_thread_fini();
eam_impl_destroy(eam_inst);
input_fini();
}
const struct eam_io_config_api *eam_io_get_config_api(void)
{
return &eam_io_config_api;
}
static void eam_io_config_save(void)
{
FILE *f;
f = eam_io_config_open("wb");
if (f == NULL) {
return;
}
eam_impl_config_save(eam_inst, f);
fclose(f);
}
static bool eam_io_get_autogen(void)
{
return eam_impl_get_autogen(eam_inst);
}
static void eam_io_set_autogen(bool autogen)
{
eam_impl_set_autogen(eam_inst, autogen);
}
static bool eam_io_get_alt_10k(void)
{
return eam_impl_get_alt_10k(eam_inst);
}
static void eam_io_set_alt_10k(bool alt_10k)
{
eam_impl_set_alt_10k(eam_inst, alt_10k);
}
static struct hid_stub *eam_io_get_keypad_device(uint8_t unit_no)
{
return eam_impl_get_keypad_device(eam_inst, unit_no);
}
static void eam_io_set_keypad_device(uint8_t unit_no, struct hid_stub *hid)
{
eam_impl_set_keypad_device(eam_inst, unit_no, hid);
}
static const char *eam_io_get_card_path(uint8_t unit_no)
{
return eam_impl_get_card_path(eam_inst, unit_no);
}
static void eam_io_set_card_path(uint8_t unit_no, const char *path)
{
eam_impl_set_card_path(eam_inst, unit_no, path);
}
uint16_t eam_io_get_keypad_state(uint8_t unit_no)
{
return eam_impl_get_keypad_state(eam_inst, unit_no);
}
uint8_t eam_io_get_sensor_state(uint8_t unit_no)
{
if (eam_impl_get_sensor_state(eam_inst, unit_no)) {
return (1 << EAM_IO_SENSOR_FRONT) | (1 << EAM_IO_SENSOR_BACK);
} else {
return 0x00;
}
}
uint8_t eam_io_read_card(uint8_t unit_no, uint8_t *card_id, uint8_t nbytes)
{
return eam_impl_read_card(eam_inst, unit_no, card_id, nbytes);
}
bool eam_io_card_slot_cmd(uint8_t unit_no, uint8_t cmd)
{
// ignored
return true;
}
bool eam_io_poll(uint8_t unit_no)
{
// ignored
return true;
}
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *ctx)
{
if (reason == DLL_PROCESS_ATTACH) {
eam_hinst = hinst;
}
return TRUE;
}
+18
View File
@@ -0,0 +1,18 @@
#ifndef EAMIO_CONFIG_H
#define EAMIO_CONFIG_H
#include "bemanitools/eamio.h"
struct eam_io_config_api {
void (*config_save)(void);
bool (*get_autogen)(void);
void (*set_autogen)(bool autogen);
bool (*get_alt_10k)(void);
void (*set_alt_10k)(bool alt_10k);
struct hid_stub *(*get_keypad_device)(uint8_t unit_no);
void (*set_keypad_device)(uint8_t unit_no, struct hid_stub *hid);
const char *(*get_card_path)(uint8_t unit_no);
void (*set_card_path)(uint8_t unit_no, const char *path);
};
#endif
+504
View File
@@ -0,0 +1,504 @@
#include <windows.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bemanitools/eamio.h"
#include "eamio/eam-impl.h"
#include "geninput/hid-mgr.h"
#include "util/defs.h"
#include "util/fs.h"
#include "util/hex.h"
#include "util/log.h"
#include "util/mem.h"
#include "util/str.h"
#define EAM_SENSOR_COOLDOWN 1000
struct eam_unit {
char *card_path;
struct hid_stub *hid;
size_t keypad_ctls[EAM_IO_KEYPAD_COUNT];
size_t sensor_ctl;
bool bound_ctls;
uint8_t drive_no;
uint32_t sensor_time;
bool sensor_hot;
};
struct eam {
/* This lock protects drive_no and sensor_time, which get read/written
respectively by eam_impl_notify_hotplug, which gets called by the Win32
message pump thread. */
CRITICAL_SECTION lock;
struct eam_unit units[EAM_UNIT_COUNT];
bool autogen;
bool alt_10k;
bool mux;
};
static const uint32_t eam_keypad_usages[EAM_IO_KEYPAD_COUNT + 1] = {
/* [EAM_KEYPAD_0] = */ 0x00070062,
/* [EAM_KEYPAD_1] = */ 0x00070059,
/* [EAM_KEYPAD_4] = */ 0x0007005C,
/* [EAM_KEYPAD_7] = */ 0x0007005F,
/* [EAM_KEYPAD_00] = */ 0x00070058, /* Keypad ENTER */
/* [EAM_KEYPAD_2] = */ 0x0007005A,
/* [EAM_KEYPAD_5] = */ 0x0007005D,
/* [EAM_KEYPAD_8] = */ 0x00070060,
/* [EAM_KEYPAD_DECIMAL] = */ 0x00070063,
/* [EAM_KEYPAD_3] = */ 0x0007005B,
/* [EAM_KEYPAD_6] = */ 0x0007005E,
/* [EAM_KEYPAD_9] = */ 0x00070061,
/* Sensor = */ 0x00070057
};
static const uint32_t eam_keypad_usages_alt[EAM_IO_KEYPAD_COUNT + 1] = {
/* [EAM_KEYPAD_0] = */ 0x00070027,
/* [EAM_KEYPAD_1] = */ 0x0007001E,
/* [EAM_KEYPAD_4] = */ 0x00070021,
/* [EAM_KEYPAD_7] = */ 0x00070024,
/* [EAM_KEYPAD_00] = */ 0x0007002D, /* - and _ */
/* [EAM_KEYPAD_2] = */ 0x0007001F,
/* [EAM_KEYPAD_5] = */ 0x00070022,
/* [EAM_KEYPAD_8] = */ 0x00070025,
/* [EAM_KEYPAD_DECIMAL] = */ 0x0007002E, /* + and = */
/* [EAM_KEYPAD_3] = */ 0x00070020,
/* [EAM_KEYPAD_6] = */ 0x00070023,
/* [EAM_KEYPAD_9] = */ 0x00070026,
/* Sensor = */ 0x0007002A /* Backspace */
};
static uint8_t eam_impl_get_active_unit(void);
static void eam_impl_bind_keypad(struct eam *eam, uint8_t unit_no);
static bool eam_impl_autogen(struct eam_unit *unit, uint8_t *card_id);
struct eam *eam_impl_create(void)
{
struct eam *eam;
struct eam_unit *unit;
size_t btn_no;
uint8_t unit_no;
eam = xmalloc(sizeof(*eam));
InitializeCriticalSection(&eam->lock);
for (unit_no = 0 ; unit_no < lengthof(eam->units) ; unit_no++) {
unit = &eam->units[unit_no];
unit->card_path = NULL;
unit->hid = NULL;
for (btn_no = 0 ; btn_no < lengthof(unit->keypad_ctls) ; btn_no++) {
unit->keypad_ctls[btn_no] = (size_t) -1;
}
unit->sensor_ctl = (size_t) -1;
unit->bound_ctls = false;
unit->drive_no = (uint8_t) -1;
unit->sensor_time = 0;
}
eam->autogen = false;
eam->alt_10k = false;
eam->mux = false;
return eam;
}
static uint8_t eam_impl_get_active_unit(void)
{
return GetKeyState(VK_NUMLOCK) & 0x0001;
}
bool eam_impl_get_autogen(struct eam *eam)
{
return eam->autogen;
}
void eam_impl_set_autogen(struct eam *eam, bool autogen)
{
eam->autogen = autogen != false;
}
bool eam_impl_get_alt_10k(struct eam *eam)
{
return eam->alt_10k;
}
void eam_impl_set_alt_10k(struct eam *eam, bool alt_10k)
{
int i;
for (i = 0 ; i < lengthof(eam->units) ; i++) {
eam->units[i].bound_ctls = false;
}
eam->alt_10k = alt_10k != false;
}
struct hid_stub *eam_impl_get_keypad_device(struct eam *eam, uint8_t unit_no)
{
log_assert(unit_no < lengthof(eam->units));
return eam->units[unit_no].hid;
}
void eam_impl_set_keypad_device(struct eam *eam, uint8_t unit_no,
struct hid_stub *hid)
{
log_assert(unit_no < lengthof(eam->units));
eam->units[unit_no].hid = hid;
eam->units[unit_no].bound_ctls = false;
eam->mux = hid != NULL && eam->units[0].hid == eam->units[1].hid;
}
const char *eam_impl_get_card_path(struct eam *eam, uint8_t unit_no)
{
log_assert(unit_no < lengthof(eam->units));
return eam->units[unit_no].card_path;
}
void eam_impl_set_card_path(struct eam *eam, uint8_t unit_no,
const char *path)
{
log_assert(unit_no < lengthof(eam->units));
EnterCriticalSection(&eam->lock);
free(eam->units[unit_no].card_path);
if (path != NULL) {
eam->units[unit_no].card_path = str_dup(path);
if (isalpha(path[0]) && path[1] == ':') {
eam->units[unit_no].drive_no = toupper(path[0]) - 'A';
} else {
eam->units[unit_no].drive_no = (uint8_t) -1;
}
} else {
eam->units[unit_no].card_path = NULL;
eam->units[unit_no].drive_no = (uint8_t) -1;
}
LeaveCriticalSection(&eam->lock);
}
uint16_t eam_impl_get_keypad_state(struct eam *eam, uint8_t unit_no)
{
struct eam_unit *unit;
uint16_t result;
int32_t value;
size_t i;
log_assert(unit_no < lengthof(eam->units));
if (eam->mux && eam_impl_get_active_unit() != unit_no) {
return 0;
}
eam_impl_bind_keypad(eam, unit_no);
unit = &eam->units[unit_no];
result = 0;
if (unit->bound_ctls) {
for (i = 0 ; i < lengthof(unit->keypad_ctls) ; i++) {
if (unit->keypad_ctls[i] == (size_t) -1) {
continue;
}
if (!hid_stub_get_value(unit->hid, unit->keypad_ctls[i], &value)) {
continue;
}
if (value) {
result |= 1 << i;
}
}
}
return result;
}
static void eam_impl_bind_keypad(struct eam *eam, uint8_t unit_no)
{
const uint32_t *usages;
struct hid_control *controls;
struct eam_unit *unit;
size_t ncontrols;
size_t control_no;
size_t btn_no;
unit = &eam->units[unit_no];
if (unit->bound_ctls
|| unit->hid == NULL
|| !hid_stub_is_attached(unit->hid)) {
return;
}
if (eam->alt_10k) {
usages = eam_keypad_usages_alt;
} else {
usages = eam_keypad_usages;
}
/* Set flag first: don't try again if this fails for whatever reason. */
unit->bound_ctls = true;
hid_mgr_lock();
if (!hid_stub_get_controls(unit->hid, NULL, &ncontrols)) {
goto size_fail;
}
controls = xmalloc(ncontrols * sizeof(*controls));
if (!hid_stub_get_controls(unit->hid, controls, &ncontrols)) {
goto content_fail;
}
for (control_no = 0 ; control_no < ncontrols ; control_no++) {
for (btn_no = 0 ; btn_no < EAM_IO_KEYPAD_COUNT ; btn_no++) {
if (controls[control_no].usage == usages[btn_no]) {
unit->keypad_ctls[btn_no] = control_no;
}
}
if (controls[control_no].usage == usages[EAM_IO_KEYPAD_COUNT]) {
unit->sensor_ctl = control_no;
}
}
free(controls);
hid_mgr_unlock();
return;
content_fail:
free(controls);
size_fail:
hid_mgr_unlock();
}
bool eam_impl_get_sensor_state(struct eam *eam, uint8_t unit_no)
{
struct eam_unit *unit;
uint32_t now;
int32_t value;
bool result;
log_assert(unit_no < lengthof(eam->units));
unit = &eam->units[unit_no];
result = false;
eam_impl_bind_keypad(eam, unit_no);
if (!unit->bound_ctls) {
return false;
}
if (unit->sensor_ctl == (size_t) -1) {
return false;
}
if (!hid_stub_get_value(unit->hid, unit->sensor_ctl, &value)) {
return false;
}
now = GetTickCount();
EnterCriticalSection(&eam->lock);
/* Bump cooldown as long as sensor button is held
(cooldown timer might also be set by a USB hotplug event) */
if (value != 0 && (!eam->mux || eam_impl_get_active_unit() == unit_no)) {
unit->sensor_time = now + EAM_SENSOR_COOLDOWN;
unit->sensor_hot = true;
}
if (unit->sensor_hot) {
if ((int32_t) (unit->sensor_time - now) > 0) {
result = true;
} else {
unit->sensor_time = 0;
unit->sensor_hot = false;
result = false;
}
}
LeaveCriticalSection(&eam->lock);
return result;
}
uint8_t eam_impl_read_card(struct eam *eam, uint8_t unit_no, uint8_t *card_id,
uint8_t nbytes)
{
char line[128];
struct eam_unit *unit;
size_t len;
FILE *f;
log_assert(unit_no < lengthof(eam->units));
log_assert(card_id != NULL);
log_assert(nbytes == EAM_CARD_NBYTES);
unit = &eam->units[unit_no];
if (unit->card_path == NULL) {
goto path_fail;
}
f = fopen(unit->card_path, "r");
if (f == NULL) {
if (eam->autogen) {
if (!eam_impl_autogen(unit, card_id)) {
log_warning("Unit %d: Failed to generate card ID into %s",
unit_no, unit->card_path);
goto fopen_fail;
}
return true;
} else {
log_warning("Unit %d: Card file at %s not present",
unit_no, unit->card_path);
goto fopen_fail;
}
}
if (fgets(line, sizeof(line), f) == NULL) {
log_warning("%s: fgets() failed", unit->card_path);
goto fgets_fail;
}
str_trim(line);
len = strlen(line);
if (len != 2 * EAM_CARD_NBYTES) {
log_warning("%s: Expected %u chars (got %u)",
unit->card_path, 2 * EAM_CARD_NBYTES, (unsigned int) len);
goto len_fail;
}
if (!hex_decode(card_id, nbytes, line, len)) {
log_warning("%s: Invalid hex [%s]", unit->card_path, card_id);
goto decode_fail;
}
log_misc("Unit %d: Loaded card ID [%s] from file %s",
unit_no, line, unit->card_path);
fclose(f);
if (card_id[0] == 0xe0 && card_id[1] == 0x04) {
return EAM_IO_CARD_ISO15696;
} else {
return EAM_IO_CARD_FELICA;
}
decode_fail:
len_fail:
fgets_fail:
fclose(f);
fopen_fail:
path_fail:
return EAM_IO_CARD_NONE;
}
static bool eam_impl_autogen(struct eam_unit *unit, uint8_t *card_id)
{
char hex[2 * EAM_CARD_NBYTES + 1];
FILE *f;
size_t i;
f = fopen(unit->card_path, "w");
if (f == NULL) {
return false;
}
srand(GetTickCount());
card_id[0] = 0xE0;
card_id[1] = 0x04;
card_id[2] = 0x01;
card_id[3] = 0x00;
for (i = 4 ; i < 8 ; i++) {
/* LSBit entropy of typical LFSR RNGs is usually poor */
card_id[i] = rand() >> 7;
}
hex_encode_uc(card_id, EAM_CARD_NBYTES, hex, sizeof(hex));
fwrite(hex, sizeof(hex) - 1, 1, f);
fclose(f);
log_info("Generated random card ID [%s] into file %s",
hex, unit->card_path);
return true;
}
void eam_impl_notify_hotplug(struct eam *eam, uint8_t drive_no)
{
struct eam_unit *unit;
uint8_t unit_no;
EnterCriticalSection(&eam->lock);
for (unit_no = 0 ; unit_no < lengthof(eam->units) ; unit_no++) {
if (eam->units[unit_no].drive_no == drive_no) {
/* MMSYSTEM timeGetTime() is overkill, we don't exactly need super
accurate timestamps here. */
unit = &eam->units[unit_no];
unit->sensor_time = GetTickCount() + EAM_SENSOR_COOLDOWN;
unit->sensor_hot = true;
}
}
LeaveCriticalSection(&eam->lock);
}
void eam_impl_destroy(struct eam *eam)
{
int8_t unit_no;
for (unit_no = lengthof(eam->units) - 1 ; unit_no >= 0 ; unit_no--) {
free(eam->units[unit_no].card_path);
}
DeleteCriticalSection(&eam->lock);
free(eam);
}
+35
View File
@@ -0,0 +1,35 @@
#ifndef EAMIO_EAM_IMPL_H
#define EAMIO_EAM_IMPL_H
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "bemanitools/eamio.h"
#include "geninput/hid-mgr.h"
#define EAM_CARD_NBYTES 8
#define EAM_UNIT_COUNT 2
struct eam;
struct eam *eam_impl_create(void);
bool eam_impl_get_autogen(struct eam *eam);
void eam_impl_set_autogen(struct eam *eam, bool autogen);
bool eam_impl_get_alt_10k(struct eam *eam);
void eam_impl_set_alt_10k(struct eam *eam, bool alt_10k);
struct hid_stub *eam_impl_get_keypad_device(struct eam *eam, uint8_t unit_no);
void eam_impl_set_keypad_device(struct eam *eam, uint8_t unit_no,
struct hid_stub *hid);
const char *eam_impl_get_card_path(struct eam *eam, uint8_t unit_no);
void eam_impl_set_card_path(struct eam *eam, uint8_t unit_no,
const char *path);
uint16_t eam_impl_get_keypad_state(struct eam *eam, uint8_t unit_no);
bool eam_impl_get_sensor_state(struct eam *eam, uint8_t unit_no);
uint8_t eam_impl_read_card(struct eam *eam, uint8_t unit_no, uint8_t *card_id,
uint8_t nbytes);
void eam_impl_notify_hotplug(struct eam *eam, uint8_t drive_no);
void eam_impl_destroy(struct eam *eam);
#endif
+122
View File
@@ -0,0 +1,122 @@
#include <stdio.h>
#include <stdlib.h>
#include "eamio/eam-impl.h"
#include "eamio/eam-s11n.h"
#include "util/fs.h"
struct eam *eam_impl_config_load(FILE *f)
{
struct eam *eam;
struct hid_stub *hid;
int8_t nunits;
int8_t unit_no;
char *card_path;
char *dev_node;
bool autogen;
bool alt_10k;
bool has_card_path;
bool has_hid;
eam = eam_impl_create();
if (!read_u8(f, &autogen)) {
goto early_fail;
}
if (!read_u8(f, &alt_10k)) {
goto early_fail;
}
eam_impl_set_autogen(eam, autogen);
eam_impl_set_alt_10k(eam, alt_10k);
if (!read_u8(f, &nunits) || nunits != EAM_UNIT_COUNT) {
goto early_fail;
}
hid_mgr_lock();
for (unit_no = 0 ; unit_no < EAM_UNIT_COUNT ; unit_no++) {
if (!read_u8(f, &has_card_path)) {
goto late_fail;
}
if (!read_u8(f, &has_hid)) {
goto late_fail;
}
if (has_card_path) {
if (!read_str(f, &card_path)) {
goto late_fail;
}
eam_impl_set_card_path(eam, unit_no, card_path);
free(card_path);
}
if (has_hid) {
if (!read_str(f, &dev_node)) {
goto late_fail;
}
hid = hid_mgr_get_named_stub(dev_node);
eam_impl_set_keypad_device(eam, unit_no, hid);
free(dev_node);
}
}
hid_mgr_unlock();
return eam;
late_fail:
hid_mgr_unlock();
early_fail:
eam_impl_destroy(eam);
return NULL;
}
void eam_impl_config_save(struct eam *eam, FILE *f)
{
const char *card_path;
struct hid_stub *hid;
uint8_t nunits;
uint8_t unit_no;
bool autogen;
bool alt_10k;
bool has_card_path;
bool has_hid;
autogen = eam_impl_get_autogen(eam);
alt_10k = eam_impl_get_alt_10k(eam);
nunits = EAM_UNIT_COUNT;
write_u8(f, &autogen);
write_u8(f, &alt_10k);
write_u8(f, &nunits);
for (unit_no = 0 ; unit_no < EAM_UNIT_COUNT ; unit_no++) {
card_path = eam_impl_get_card_path(eam, unit_no);
hid = eam_impl_get_keypad_device(eam, unit_no);
has_card_path = card_path != NULL;
has_hid = hid != NULL;
write_u8(f, &has_card_path);
write_u8(f, &has_hid);
if (has_card_path) {
write_str(f, card_path);
}
if (has_hid) {
write_str(f, hid_stub_get_dev_node(hid));
}
}
}
+11
View File
@@ -0,0 +1,11 @@
#ifndef GENINPUT_EAM_S11N_H
#define GENINPUT_EAM_S11N_H
#include <stdio.h>
#include "eamio/eam-impl.h"
struct eam *eam_impl_config_load(FILE *f);
void eam_impl_config_save(struct eam *eam, FILE *f);
#endif
+12
View File
@@ -0,0 +1,12 @@
LIBRARY eamio
EXPORTS
eam_io_fini
eam_io_init
eam_io_get_config_api
eam_io_get_keypad_state
eam_io_get_sensor_state
eam_io_read_card
eam_io_card_slot_cmd
eam_io_set_loggers
eam_io_poll