mirror of
https://github.com/estkme-group/lpac
synced 2025-08-19 02:22:56 +02:00
Compare commits
12 commits
Author | SHA1 | Date | |
---|---|---|---|
b0157b5a66 | |||
283f081a03 | |||
f7fa2d912a | |||
af92e5d21f | |||
286f6e7160 | |||
4c03199ddd | |||
e81fc0e624 | |||
f73612e3bb | |||
467613c3a6 | |||
22dcc49329 | |||
|
5f941dcd88 | ||
3f0156a549 |
30 changed files with 203 additions and 170 deletions
3
.github/workflows/build.yaml
vendored
3
.github/workflows/build.yaml
vendored
|
@ -8,6 +8,9 @@ on:
|
|||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
env:
|
||||
CFLAGS: "-Werror"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build for ${{ matrix.build.name }}
|
||||
|
|
|
@ -48,7 +48,7 @@ static int at_expect(char **response, const char *expected) {
|
|||
while (1) {
|
||||
fgets(buffer, AT_BUFFER_SIZE, fuart);
|
||||
buffer[strcspn(buffer, "\r\n")] = 0;
|
||||
if (getenv_or_default(ENV_AT_DEBUG, false))
|
||||
if (getenv_or_default(ENV_AT_DEBUG, (bool)false))
|
||||
printf("AT_DEBUG: %s\n", buffer);
|
||||
if (strcmp(buffer, "ERROR") == 0) {
|
||||
return -1;
|
||||
|
@ -214,7 +214,7 @@ static int libapduinterface_init(struct euicc_apdu_interface *ifstruct) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int libapduinterface_main(const int argc, char **argv) {
|
||||
static int libapduinterface_main(const struct euicc_apdu_interface *ifstruct, int argc, char **argv) {
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s <list>\n", argv[0]);
|
||||
return -1;
|
||||
|
@ -242,6 +242,6 @@ const struct euicc_driver driver_apdu_at = {
|
|||
.type = DRIVER_APDU,
|
||||
.name = "at",
|
||||
.init = (int (*)(void *))libapduinterface_init,
|
||||
.main = libapduinterface_main,
|
||||
.main = (int (*)(void *, int, char **))libapduinterface_main,
|
||||
.fini = (void (*)(void *))libapduinterface_fini,
|
||||
};
|
||||
|
|
|
@ -35,40 +35,35 @@ static void enumerate_com_ports(cJSON *data) {
|
|||
SP_DEVINFO_DATA devInfoData;
|
||||
DWORD i;
|
||||
|
||||
hDevInfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_PORTS, 0, 0, DIGCF_PRESENT);
|
||||
hDevInfo = SetupDiGetClassDevsA(&GUID_DEVCLASS_PORTS, 0, 0, DIGCF_PRESENT);
|
||||
if (hDevInfo == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
|
||||
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
|
||||
for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &devInfoData); i++) {
|
||||
wchar_t portName[256] = {0};
|
||||
wchar_t friendlyName[256] = {0};
|
||||
char portNameMB[256] = {0};
|
||||
char friendlyNameMB[256] = {0};
|
||||
char portName[256] = {0};
|
||||
char friendlyName[256] = {0};
|
||||
DWORD size = sizeof(portName);
|
||||
|
||||
HKEY hKey = SetupDiOpenDevRegKey(hDevInfo, &devInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
|
||||
if (hKey != INVALID_HANDLE_VALUE) {
|
||||
DWORD type;
|
||||
if (RegQueryValueExW(hKey, L"PortName", NULL, &type, (LPBYTE)portName, &size) != ERROR_SUCCESS
|
||||
if (RegQueryValueExA(hKey, "PortName", NULL, &type, (LPBYTE)portName, &size) != ERROR_SUCCESS
|
||||
|| type != REG_SZ) {
|
||||
portName[0] = L'\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (!SetupDiGetDeviceRegistryPropertyW(hDevInfo, &devInfoData, SPDRP_FRIENDLYNAME, NULL, (PBYTE)friendlyName,
|
||||
if (!SetupDiGetDeviceRegistryPropertyA(hDevInfo, &devInfoData, SPDRP_FRIENDLYNAME, NULL, (PBYTE)friendlyName,
|
||||
sizeof(friendlyName), NULL)) {
|
||||
friendlyName[0] = L'\0';
|
||||
}
|
||||
|
||||
WideCharToMultiByte(CP_ACP, 0, portName, -1, portNameMB, sizeof(portNameMB), NULL, NULL);
|
||||
WideCharToMultiByte(CP_ACP, 0, friendlyName, -1, friendlyNameMB, sizeof(friendlyNameMB), NULL, NULL);
|
||||
|
||||
if (starts_with(portNameMB, "COM")) {
|
||||
if (starts_with(portName, "COM")) {
|
||||
cJSON *item = cJSON_CreateObject();
|
||||
if (item) {
|
||||
cJSON_AddStringToObject(item, "env", portNameMB);
|
||||
cJSON_AddStringToObject(item, "name", friendlyNameMB[0] ? friendlyNameMB : portNameMB);
|
||||
cJSON_AddStringToObject(item, "env", portName);
|
||||
cJSON_AddStringToObject(item, "name", friendlyName[0] ? friendlyName : portName);
|
||||
cJSON_AddItemToArray(data, item);
|
||||
} else {
|
||||
cJSON_Delete(item);
|
||||
|
@ -125,7 +120,7 @@ static int at_expect(char **response, const char *expected) {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (getenv_or_default(ENV_AT_DEBUG, false))
|
||||
if (getenv_or_default(ENV_AT_DEBUG, (bool)false))
|
||||
fprintf(stderr, "AT_DEBUG_RX: %s\n", line);
|
||||
|
||||
if (strcmp(line, "ERROR") == 0) {
|
||||
|
@ -155,7 +150,7 @@ end:
|
|||
|
||||
static int at_write_command(const char *cmd) {
|
||||
DWORD bytes_written;
|
||||
if (getenv_or_default(ENV_AT_DEBUG, false))
|
||||
if (getenv_or_default(ENV_AT_DEBUG, (bool)false))
|
||||
fprintf(stderr, "AT_DEBUG_TX: %s", cmd);
|
||||
|
||||
if (!WriteFile(hComm, cmd, strlen(cmd), &bytes_written, NULL)) {
|
||||
|
@ -171,16 +166,13 @@ static int apdu_interface_connect(struct euicc_ctx *ctx) {
|
|||
|
||||
logic_channel = 0;
|
||||
|
||||
char dev_ascii[64];
|
||||
snprintf(dev_ascii, sizeof(dev_ascii), "\\\\.\\%s", device);
|
||||
char devname[64];
|
||||
snprintf(devname, sizeof(devname), "\\\\.\\%s", device);
|
||||
|
||||
wchar_t devname[64];
|
||||
mbstowcs(devname, dev_ascii, sizeof(devname) / sizeof(wchar_t));
|
||||
|
||||
hComm = CreateFileW(devname, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
hComm = CreateFile(devname, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (hComm == INVALID_HANDLE_VALUE) {
|
||||
fprintf(stderr, "Failed to open device: %s, error: %lu\n", dev_ascii, GetLastError());
|
||||
fprintf(stderr, "Failed to open device: %s, error: %lu\n", devname, GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -350,7 +342,7 @@ static int libapduinterface_init(struct euicc_apdu_interface *ifstruct) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int libapduinterface_main(int argc, char **argv) {
|
||||
static int libapduinterface_main(const struct euicc_apdu_interface *ifstruct, int argc, char **argv) {
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s <list>\n", argv[0]);
|
||||
return -1;
|
||||
|
@ -380,6 +372,6 @@ const struct euicc_driver driver_apdu_at_win32 = {
|
|||
.type = DRIVER_APDU,
|
||||
.name = "at",
|
||||
.init = (int (*)(void *))libapduinterface_init,
|
||||
.main = libapduinterface_main,
|
||||
.main = (int (*)(void *, int, char **))libapduinterface_main,
|
||||
.fini = (void (*)(void *))libapduinterface_fini,
|
||||
};
|
||||
|
|
|
@ -224,7 +224,7 @@ static int apdu_interface_transmit(struct euicc_ctx *ctx, uint8_t **rx, uint32_t
|
|||
uint8_t tx_hex[4096] = {0};
|
||||
euicc_hexutil_bin2hex(tx_hex, 4096, &tx[5], tx_len - 5);
|
||||
|
||||
if (getenv_or_default(ENV_DEBUG, false))
|
||||
if (getenv_or_default(ENV_DEBUG, (bool)false))
|
||||
fprintf(stderr, "APDU req: %s\n", tx_hex);
|
||||
|
||||
struct sim_apdu apdu = {
|
||||
|
@ -256,7 +256,7 @@ static int apdu_interface_transmit(struct euicc_ctx *ctx, uint8_t **rx, uint32_t
|
|||
return -lastRadioErr;
|
||||
}
|
||||
|
||||
if (getenv_or_default(ENV_DEBUG, false))
|
||||
if (getenv_or_default(ENV_DEBUG, (bool)false))
|
||||
fprintf(stderr, "APDU resp: %d%d %d %s\n", lastIccIoResult.sw1, lastIccIoResult.sw2,
|
||||
lastIccIoResult.simResponse.len, lastIccIoResult.simResponse.data.str);
|
||||
|
||||
|
@ -291,14 +291,12 @@ static int libapduinterface_init(struct euicc_apdu_interface *ifstruct) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int libapduinterface_main(int argc, char **argv) { return 0; }
|
||||
|
||||
static void libapduinterface_fini(struct euicc_apdu_interface *ifstruct) {}
|
||||
|
||||
const struct euicc_driver driver_apdu_gbinder_hidl = {
|
||||
.type = DRIVER_APDU,
|
||||
.name = "gbinder_hidl",
|
||||
.init = (int (*)(void *))libapduinterface_init,
|
||||
.main = libapduinterface_main,
|
||||
.main = NULL,
|
||||
.fini = (void (*)(void *))libapduinterface_fini,
|
||||
};
|
||||
|
|
|
@ -289,7 +289,7 @@ static int libapduinterface_init(struct euicc_apdu_interface *ifstruct) {
|
|||
}
|
||||
|
||||
mbim_priv->uim_slot = uim_slot;
|
||||
mbim_priv->use_proxy = getenv_or_default(ENV_USE_PROXY, false);
|
||||
mbim_priv->use_proxy = getenv_or_default(ENV_USE_PROXY, (bool)false);
|
||||
mbim_priv->device_path = getenv_or_default(ENV_DEVICE, "/dev/cdc-wdm0");
|
||||
|
||||
memset(ifstruct, 0, sizeof(struct euicc_apdu_interface));
|
||||
|
@ -303,14 +303,12 @@ static int libapduinterface_init(struct euicc_apdu_interface *ifstruct) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int libapduinterface_main(int argc, char **argv) { return 0; }
|
||||
|
||||
static void libapduinterface_fini(struct euicc_apdu_interface *ifstruct) { g_free(ifstruct->userdata); }
|
||||
|
||||
const struct euicc_driver driver_apdu_mbim = {
|
||||
.type = DRIVER_APDU,
|
||||
.name = "mbim",
|
||||
.init = (int (*)(void *))libapduinterface_init,
|
||||
.main = libapduinterface_main,
|
||||
.main = NULL,
|
||||
.fini = (void (*)(void *))libapduinterface_fini,
|
||||
};
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
# include <PCSC/wintypes.h>
|
||||
#endif
|
||||
|
||||
#ifdef interface
|
||||
# undef interface
|
||||
#endif
|
||||
|
||||
#define ENV_DRV_IFID APDU_ENV_NAME(PCSC, DRV_IFID)
|
||||
#define ENV_DRV_NAME APDU_ENV_NAME(PCSC, DRV_NAME)
|
||||
#define ENV_DRV_IGNORE_NAME APDU_ENV_NAME(PCSC, DRV_IGNORE_NAME)
|
||||
|
@ -29,9 +33,11 @@
|
|||
#define APDU_CLOSELOGICCHANNEL "\x00\x70\x80\xFF\x00"
|
||||
#define APDU_SELECT_HEADER "\x00\xA4\x04\x00\xFF"
|
||||
|
||||
static SCARDCONTEXT pcsc_ctx;
|
||||
static SCARDHANDLE pcsc_hCard;
|
||||
static LPSTR pcsc_mszReaders;
|
||||
struct pcsc_userdata {
|
||||
SCARDCONTEXT ctx;
|
||||
SCARDHANDLE hCard;
|
||||
LPSTR mszReaders;
|
||||
};
|
||||
|
||||
static void pcsc_error(const char *method, const int32_t code) {
|
||||
fprintf(stderr, "%s failed: %08X (%s)\n", method, code, pcsc_stringify_error(code));
|
||||
|
@ -50,15 +56,14 @@ static bool is_ignored_reader_name(const char *reader) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static int pcsc_ctx_open(void) {
|
||||
int ret;
|
||||
static int pcsc_ctx_open(struct pcsc_userdata *userdata) {
|
||||
DWORD dwReaders;
|
||||
|
||||
pcsc_ctx = 0;
|
||||
pcsc_hCard = 0;
|
||||
pcsc_mszReaders = NULL;
|
||||
userdata->ctx = 0;
|
||||
userdata->hCard = 0;
|
||||
userdata->mszReaders = NULL;
|
||||
|
||||
ret = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &pcsc_ctx);
|
||||
int ret = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &userdata->ctx);
|
||||
if (ret != SCARD_S_SUCCESS) {
|
||||
pcsc_error("SCardEstablishContext()", ret);
|
||||
return -1;
|
||||
|
@ -66,21 +71,21 @@ static int pcsc_ctx_open(void) {
|
|||
|
||||
#ifdef SCARD_AUTOALLOCATE
|
||||
dwReaders = SCARD_AUTOALLOCATE;
|
||||
ret = SCardListReaders(pcsc_ctx, NULL, (LPSTR)&pcsc_mszReaders, &dwReaders);
|
||||
ret = SCardListReaders(userdata->ctx, NULL, (LPSTR)&userdata->mszReaders, &dwReaders);
|
||||
#else
|
||||
// macOS does not support SCARD_AUTOALLOCATE, so we need to call SCardListReaders twice.
|
||||
// First call to get the size of the buffer, second call to get the actual data.
|
||||
ret = SCardListReaders(pcsc_ctx, NULL, NULL, &dwReaders);
|
||||
ret = SCardListReaders(userdata->ctx, NULL, NULL, &dwReaders);
|
||||
if (ret != SCARD_S_SUCCESS) {
|
||||
pcsc_error("SCardListReaders()", ret);
|
||||
return -1;
|
||||
}
|
||||
pcsc_mszReaders = malloc(sizeof(char) * dwReaders);
|
||||
if (pcsc_mszReaders == NULL) {
|
||||
userdata->mszReaders = malloc(sizeof(char) * dwReaders);
|
||||
if (userdata->mszReaders == NULL) {
|
||||
fprintf(stderr, "malloc: not enough memory\n");
|
||||
return -1;
|
||||
}
|
||||
ret = SCardListReaders(pcsc_ctx, NULL, pcsc_mszReaders, &dwReaders);
|
||||
ret = SCardListReaders(userdata->ctx, NULL, userdata->mszReaders, &dwReaders);
|
||||
#endif
|
||||
if (ret != SCARD_S_SUCCESS) {
|
||||
pcsc_error("SCardListReaders()", ret);
|
||||
|
@ -90,30 +95,25 @@ static int pcsc_ctx_open(void) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int pcsc_iter_reader(int (*callback)(int index, const char *reader, void *userdata), void *userdata) {
|
||||
int ret;
|
||||
LPSTR psReader;
|
||||
|
||||
psReader = pcsc_mszReaders;
|
||||
for (int i = 0, n = 0;; i++) {
|
||||
char *p = pcsc_mszReaders + i;
|
||||
if (*p == '\0') {
|
||||
ret = callback(n, psReader, userdata);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
if (ret > 0)
|
||||
return 0;
|
||||
if (*(p + 1) == '\0') {
|
||||
break;
|
||||
}
|
||||
psReader = p + 1;
|
||||
n++;
|
||||
}
|
||||
static int pcsc_iter_reader(struct pcsc_userdata *userdata,
|
||||
int (*callback)(struct pcsc_userdata *userdata, int index, const char *reader,
|
||||
void *context),
|
||||
void *context) {
|
||||
int index = 0;
|
||||
LPSTR pReader = userdata->mszReaders;
|
||||
while (*pReader != '\0') {
|
||||
const int ret = callback(userdata, index, pReader, context);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
if (ret > 0)
|
||||
return 0;
|
||||
pReader += strlen(pReader) + 1;
|
||||
index++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int pcsc_open_hCard_iter(int index, const char *reader, void *userdata) {
|
||||
static int pcsc_open_hCard_iter(struct pcsc_userdata *userdata, const int index, const char *reader, void *context) {
|
||||
DWORD dwActiveProtocol;
|
||||
|
||||
const int id = getenv_or_default(ENV_DRV_IFID, (int)-1);
|
||||
|
@ -128,8 +128,8 @@ static int pcsc_open_hCard_iter(int index, const char *reader, void *userdata) {
|
|||
return 0; // skip ignored reader names
|
||||
}
|
||||
|
||||
const int ret =
|
||||
SCardConnect(pcsc_ctx, reader, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0, &pcsc_hCard, &dwActiveProtocol);
|
||||
const int ret = SCardConnect(userdata->ctx, reader, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0, &userdata->hCard,
|
||||
&dwActiveProtocol);
|
||||
if (ret != SCARD_S_SUCCESS) {
|
||||
pcsc_error("SCardConnect()", ret);
|
||||
// see <https://blog.apdu.fr/posts/2024/12/gnupg-and-pcsc-conflicts-episode-3/>
|
||||
|
@ -141,36 +141,36 @@ static int pcsc_open_hCard_iter(int index, const char *reader, void *userdata) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int pcsc_open_hCard(void) { return pcsc_iter_reader(pcsc_open_hCard_iter, NULL); }
|
||||
static int pcsc_open_hCard(struct pcsc_userdata *userdata) {
|
||||
return pcsc_iter_reader(userdata, pcsc_open_hCard_iter, NULL);
|
||||
}
|
||||
|
||||
static void pcsc_close(void) {
|
||||
if (pcsc_mszReaders) {
|
||||
static void pcsc_close(const struct pcsc_userdata *userdata) {
|
||||
if (userdata->mszReaders != NULL) {
|
||||
// macOS does not support SCARD_AUTOALLOCATE, so we need to free the buffer manually.
|
||||
#ifdef SCARD_AUTOALLOCATE
|
||||
SCardFreeMemory(pcsc_ctx, pcsc_mszReaders);
|
||||
SCardFreeMemory(userdata->ctx, userdata->mszReaders);
|
||||
#else
|
||||
// on macOS, pcsc_mszReaders is allocated by malloc()
|
||||
free(pcsc_mszReaders);
|
||||
// on macOS, mszReaders is allocated by malloc()
|
||||
free(userdata->mszReaders);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (pcsc_hCard) {
|
||||
SCardDisconnect(pcsc_hCard, SCARD_UNPOWER_CARD);
|
||||
if (userdata->hCard) {
|
||||
SCardDisconnect(userdata->hCard, SCARD_UNPOWER_CARD);
|
||||
}
|
||||
if (pcsc_ctx) {
|
||||
SCardReleaseContext(pcsc_ctx);
|
||||
if (userdata->ctx) {
|
||||
SCardReleaseContext(userdata->ctx);
|
||||
}
|
||||
pcsc_ctx = 0;
|
||||
pcsc_hCard = 0;
|
||||
pcsc_mszReaders = NULL;
|
||||
}
|
||||
|
||||
static int pcsc_transmit_lowlevel(uint8_t *rx, uint32_t *rx_len, const uint8_t *tx, const uint8_t tx_len) {
|
||||
static int pcsc_transmit_lowlevel(const struct pcsc_userdata *userdata, uint8_t *rx, uint32_t *rx_len,
|
||||
const uint8_t *tx, const uint8_t tx_len) {
|
||||
int ret;
|
||||
DWORD rx_len_merged;
|
||||
|
||||
rx_len_merged = *rx_len;
|
||||
ret = SCardTransmit(pcsc_hCard, SCARD_PCI_T0, tx, tx_len, NULL, rx, &rx_len_merged);
|
||||
ret = SCardTransmit(userdata->hCard, SCARD_PCI_T0, tx, tx_len, NULL, rx, &rx_len_merged);
|
||||
if (ret != SCARD_S_SUCCESS) {
|
||||
pcsc_error("SCardTransmit()", ret);
|
||||
return -1;
|
||||
|
@ -180,7 +180,7 @@ static int pcsc_transmit_lowlevel(uint8_t *rx, uint32_t *rx_len, const uint8_t *
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void pcsc_logic_channel_close(uint8_t channel) {
|
||||
static void pcsc_logic_channel_close(const struct pcsc_userdata *userdata, const uint8_t channel) {
|
||||
uint8_t tx[sizeof(APDU_CLOSELOGICCHANNEL) - 1];
|
||||
uint8_t rx[EUICC_INTERFACE_BUFSZ];
|
||||
uint32_t rx_len;
|
||||
|
@ -190,10 +190,10 @@ static void pcsc_logic_channel_close(uint8_t channel) {
|
|||
|
||||
rx_len = sizeof(rx);
|
||||
|
||||
pcsc_transmit_lowlevel(rx, &rx_len, tx, sizeof(tx));
|
||||
pcsc_transmit_lowlevel(userdata, rx, &rx_len, tx, sizeof(tx));
|
||||
}
|
||||
|
||||
static int pcsc_logic_channel_open(const uint8_t *aid, uint8_t aid_len) {
|
||||
static int pcsc_logic_channel_open(const struct pcsc_userdata *userdata, const uint8_t *aid, uint8_t aid_len) {
|
||||
int channel = 0;
|
||||
uint8_t tx[EUICC_INTERFACE_BUFSZ];
|
||||
uint8_t *tx_wptr;
|
||||
|
@ -205,7 +205,8 @@ static int pcsc_logic_channel_open(const uint8_t *aid, uint8_t aid_len) {
|
|||
}
|
||||
|
||||
rx_len = sizeof(rx);
|
||||
if (pcsc_transmit_lowlevel(rx, &rx_len, (const uint8_t *)APDU_OPENLOGICCHANNEL, sizeof(APDU_OPENLOGICCHANNEL) - 1)
|
||||
if (pcsc_transmit_lowlevel(userdata, rx, &rx_len, (const uint8_t *)APDU_OPENLOGICCHANNEL,
|
||||
sizeof(APDU_OPENLOGICCHANNEL) - 1)
|
||||
< 0) {
|
||||
goto err;
|
||||
}
|
||||
|
@ -230,7 +231,7 @@ static int pcsc_logic_channel_open(const uint8_t *aid, uint8_t aid_len) {
|
|||
tx[4] = aid_len;
|
||||
|
||||
rx_len = sizeof(rx);
|
||||
if (pcsc_transmit_lowlevel(rx, &rx_len, tx, tx_wptr - tx) < 0) {
|
||||
if (pcsc_transmit_lowlevel(userdata, rx, &rx_len, tx, tx_wptr - tx) < 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -248,31 +249,37 @@ static int pcsc_logic_channel_open(const uint8_t *aid, uint8_t aid_len) {
|
|||
|
||||
err:
|
||||
if (channel) {
|
||||
pcsc_logic_channel_close(channel);
|
||||
pcsc_logic_channel_close(userdata, channel);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int apdu_interface_connect(struct euicc_ctx *ctx) {
|
||||
struct pcsc_userdata *userdata = ctx->apdu.interface->userdata;
|
||||
|
||||
uint8_t rx[EUICC_INTERFACE_BUFSZ];
|
||||
uint32_t rx_len;
|
||||
|
||||
if (pcsc_open_hCard() < 0) {
|
||||
if (pcsc_open_hCard(userdata) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rx_len = sizeof(rx);
|
||||
pcsc_transmit_lowlevel(rx, &rx_len, (const uint8_t *)APDU_TERMINAL_CAPABILITIES,
|
||||
pcsc_transmit_lowlevel(userdata, rx, &rx_len, (const uint8_t *)APDU_TERMINAL_CAPABILITIES,
|
||||
sizeof(APDU_TERMINAL_CAPABILITIES) - 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void apdu_interface_disconnect(struct euicc_ctx *ctx) { pcsc_close(); }
|
||||
static void apdu_interface_disconnect(struct euicc_ctx *ctx) {
|
||||
const struct pcsc_userdata *userdata = ctx->apdu.interface->userdata;
|
||||
pcsc_close(userdata);
|
||||
}
|
||||
|
||||
static int apdu_interface_transmit(struct euicc_ctx *ctx, uint8_t **rx, uint32_t *rx_len, const uint8_t *tx,
|
||||
uint32_t tx_len) {
|
||||
const struct pcsc_userdata *userdata = ctx->apdu.interface->userdata;
|
||||
*rx = malloc(EUICC_INTERFACE_BUFSZ);
|
||||
if (!*rx) {
|
||||
fprintf(stderr, "SCardTransmit() RX buffer alloc failed\n");
|
||||
|
@ -280,7 +287,7 @@ static int apdu_interface_transmit(struct euicc_ctx *ctx, uint8_t **rx, uint32_t
|
|||
}
|
||||
*rx_len = EUICC_INTERFACE_BUFSZ;
|
||||
|
||||
if (pcsc_transmit_lowlevel(*rx, rx_len, tx, tx_len) < 0) {
|
||||
if (pcsc_transmit_lowlevel(userdata, *rx, rx_len, tx, tx_len) < 0) {
|
||||
free(*rx);
|
||||
*rx_len = 0;
|
||||
return -1;
|
||||
|
@ -290,21 +297,22 @@ static int apdu_interface_transmit(struct euicc_ctx *ctx, uint8_t **rx, uint32_t
|
|||
}
|
||||
|
||||
static int apdu_interface_logic_channel_open(struct euicc_ctx *ctx, const uint8_t *aid, uint8_t aid_len) {
|
||||
return pcsc_logic_channel_open(aid, aid_len);
|
||||
const struct pcsc_userdata *userdata = ctx->apdu.interface->userdata;
|
||||
return pcsc_logic_channel_open(userdata, aid, aid_len);
|
||||
}
|
||||
|
||||
static void apdu_interface_logic_channel_close(struct euicc_ctx *ctx, uint8_t channel) {
|
||||
pcsc_logic_channel_close(channel);
|
||||
const struct pcsc_userdata *userdata = ctx->apdu.interface->userdata;
|
||||
pcsc_logic_channel_close(userdata, channel);
|
||||
}
|
||||
|
||||
static int pcsc_list_iter(int index, const char *reader, void *userdata) {
|
||||
cJSON *json = userdata;
|
||||
cJSON *jreader;
|
||||
static int pcsc_list_iter(struct pcsc_userdata *userdata, const int index, const char *reader, void *context) {
|
||||
cJSON *json = context;
|
||||
char index_str[16];
|
||||
|
||||
snprintf(index_str, sizeof(index_str), "%d", index);
|
||||
|
||||
jreader = cJSON_CreateObject();
|
||||
cJSON *jreader = cJSON_CreateObject();
|
||||
if (!jreader) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -328,9 +336,14 @@ static int libapduinterface_init(struct euicc_apdu_interface *ifstruct) {
|
|||
set_deprecated_env_name(ENV_DRV_IFID, "DRIVER_IFID");
|
||||
set_deprecated_env_name(ENV_DRV_NAME, "DRIVER_NAME");
|
||||
|
||||
struct pcsc_userdata *userdata = malloc(sizeof(struct pcsc_userdata));
|
||||
if (userdata == NULL)
|
||||
return -1;
|
||||
memset(userdata, 0, sizeof(struct pcsc_userdata));
|
||||
|
||||
memset(ifstruct, 0, sizeof(struct euicc_apdu_interface));
|
||||
|
||||
if (pcsc_ctx_open() < 0) {
|
||||
if (pcsc_ctx_open(userdata) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -339,21 +352,26 @@ static int libapduinterface_init(struct euicc_apdu_interface *ifstruct) {
|
|||
ifstruct->logic_channel_open = apdu_interface_logic_channel_open;
|
||||
ifstruct->logic_channel_close = apdu_interface_logic_channel_close;
|
||||
ifstruct->transmit = apdu_interface_transmit;
|
||||
ifstruct->userdata = userdata;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int libapduinterface_main(int argc, char **argv) {
|
||||
static int libapduinterface_main(const struct euicc_apdu_interface *ifstruct, int argc, char **argv) {
|
||||
struct pcsc_userdata *userdata = ifstruct->userdata;
|
||||
|
||||
if (userdata == NULL) {
|
||||
fprintf(stderr, "No userdata set\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s <list>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "list") == 0) {
|
||||
cJSON *payload;
|
||||
cJSON *data;
|
||||
|
||||
payload = cJSON_CreateObject();
|
||||
cJSON *payload = cJSON_CreateObject();
|
||||
if (!payload) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -362,12 +380,12 @@ static int libapduinterface_main(int argc, char **argv) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
data = cJSON_CreateArray();
|
||||
cJSON *data = cJSON_CreateArray();
|
||||
if (!data) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pcsc_iter_reader(pcsc_list_iter, data);
|
||||
pcsc_iter_reader(userdata, pcsc_list_iter, data);
|
||||
|
||||
if (!cJSON_AddItemToObject(payload, "data", data)) {
|
||||
return -1;
|
||||
|
@ -381,12 +399,15 @@ static int libapduinterface_main(int argc, char **argv) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void libapduinterface_fini(struct euicc_apdu_interface *ifstruct) {}
|
||||
static void libapduinterface_fini(const struct euicc_apdu_interface *ifstruct) {
|
||||
struct pcsc_userdata *userdata = ifstruct->userdata;
|
||||
free(userdata);
|
||||
}
|
||||
|
||||
const struct euicc_driver driver_apdu_pcsc = {
|
||||
.type = DRIVER_APDU,
|
||||
.name = "pcsc",
|
||||
.init = (int (*)(void *))libapduinterface_init,
|
||||
.main = libapduinterface_main,
|
||||
.main = (int (*)(void *, int, char **))libapduinterface_main,
|
||||
.fini = (void (*)(void *))libapduinterface_fini,
|
||||
};
|
||||
|
|
|
@ -235,8 +235,6 @@ static int libapduinterface_init(struct euicc_apdu_interface *ifstruct) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int libapduinterface_main(int argc, char **argv) { return 0; }
|
||||
|
||||
static void libapduinterface_fini(struct euicc_apdu_interface *ifstruct) {
|
||||
struct qmi_data *qmi_priv = ifstruct->userdata;
|
||||
|
||||
|
@ -249,6 +247,6 @@ const struct euicc_driver driver_apdu_qmi = {
|
|||
.type = DRIVER_APDU,
|
||||
.name = "qmi",
|
||||
.init = (int (*)(void *))libapduinterface_init,
|
||||
.main = libapduinterface_main,
|
||||
.main = NULL,
|
||||
.fini = (void (*)(void *))libapduinterface_fini,
|
||||
};
|
||||
|
|
|
@ -101,8 +101,6 @@ static int libapduinterface_init(struct euicc_apdu_interface *ifstruct) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int libapduinterface_main(int argc, char **argv) { return 0; }
|
||||
|
||||
static void libapduinterface_fini(struct euicc_apdu_interface *ifstruct) {
|
||||
struct qmi_data *qmi_priv = ifstruct->userdata;
|
||||
|
||||
|
@ -115,6 +113,6 @@ const struct euicc_driver driver_apdu_qmi_qrtr = {
|
|||
.type = DRIVER_APDU,
|
||||
.name = "qmi_qrtr",
|
||||
.init = (int (*)(void *))libapduinterface_init,
|
||||
.main = libapduinterface_main,
|
||||
.main = NULL,
|
||||
.fini = (void (*)(void *))libapduinterface_fini,
|
||||
};
|
||||
|
|
|
@ -230,14 +230,12 @@ static int libapduinterface_init(struct euicc_apdu_interface *ifstruct) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int libapduinterface_main(int argc, char **argv) { return 0; }
|
||||
|
||||
static void libapduinterface_fini(struct euicc_apdu_interface *ifstruct) {}
|
||||
|
||||
const struct euicc_driver driver_apdu_stdio = {
|
||||
.type = DRIVER_APDU,
|
||||
.name = "stdio",
|
||||
.init = (int (*)(void *))libapduinterface_init,
|
||||
.main = libapduinterface_main,
|
||||
.main = NULL,
|
||||
.fini = (void (*)(void *))libapduinterface_fini,
|
||||
};
|
||||
|
|
|
@ -70,8 +70,6 @@ static const struct euicc_driver *_driver_http = NULL;
|
|||
|
||||
struct euicc_apdu_interface euicc_driver_interface_apdu;
|
||||
struct euicc_http_interface euicc_driver_interface_http;
|
||||
int (*euicc_driver_main_apdu)(int argc, char **argv) = NULL;
|
||||
int (*euicc_driver_main_http)(int argc, char **argv) = NULL;
|
||||
|
||||
static const struct euicc_driver *find_driver(const enum euicc_driver_type type, const char *name) {
|
||||
for (int i = 0; drivers[i] != NULL; i++) {
|
||||
|
@ -111,8 +109,8 @@ int euicc_driver_list(int argc, char **argv) {
|
|||
cJSON_AddItemToArray(http_drivers, driver_name);
|
||||
}
|
||||
}
|
||||
cJSON_AddItemToObject(payload, "LPAC_APDU", apdu_drivers);
|
||||
cJSON_AddItemToObject(payload, "LPAC_HTTP", http_drivers);
|
||||
cJSON_AddItemToObject(payload, ENV_APDU_DRIVER, apdu_drivers);
|
||||
cJSON_AddItemToObject(payload, ENV_HTTP_DRIVER, http_drivers);
|
||||
|
||||
json_print("driver", payload);
|
||||
return 0;
|
||||
|
@ -141,9 +139,6 @@ int euicc_driver_init(const char *apdu_driver_name, const char *http_driver_name
|
|||
return -1;
|
||||
}
|
||||
|
||||
euicc_driver_main_apdu = _driver_apdu->main;
|
||||
euicc_driver_main_http = _driver_http->main;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -155,3 +150,27 @@ void euicc_driver_fini() {
|
|||
_driver_http->fini(&euicc_driver_interface_http);
|
||||
}
|
||||
}
|
||||
|
||||
int euicc_driver_main_apdu(const int argc, char **argv) {
|
||||
if (_driver_apdu == NULL) {
|
||||
fprintf(stderr, "No APDU driver found\n");
|
||||
return -1;
|
||||
}
|
||||
if (_driver_apdu->main == NULL) {
|
||||
fprintf(stderr, "The APDU driver '%s' does not support main function\n", _driver_apdu->name);
|
||||
return -1;
|
||||
}
|
||||
return _driver_apdu->main(&euicc_driver_interface_apdu, argc, argv);
|
||||
}
|
||||
|
||||
int euicc_driver_main_http(const int argc, char **argv) {
|
||||
if (_driver_http == NULL) {
|
||||
fprintf(stderr, "No HTTP driver found\n");
|
||||
return -1;
|
||||
}
|
||||
if (_driver_http->main == NULL) {
|
||||
fprintf(stderr, "The HTTP driver '%s' does not support main function\n", _driver_http->name);
|
||||
return -1;
|
||||
}
|
||||
return _driver_http->main(&euicc_driver_interface_http, argc, argv);
|
||||
}
|
||||
|
|
|
@ -7,9 +7,10 @@
|
|||
|
||||
extern struct euicc_apdu_interface euicc_driver_interface_apdu;
|
||||
extern struct euicc_http_interface euicc_driver_interface_http;
|
||||
extern int (*euicc_driver_main_apdu)(int argc, char **argv);
|
||||
extern int (*euicc_driver_main_http)(int argc, char **argv);
|
||||
|
||||
int euicc_driver_list(int argc, char **argv);
|
||||
int euicc_driver_init(const char *apdu_driver_name, const char *http_driver_name);
|
||||
void euicc_driver_fini(void);
|
||||
|
||||
extern int euicc_driver_main_apdu(int argc, char **argv);
|
||||
extern int euicc_driver_main_http(int argc, char **argv);
|
||||
|
|
|
@ -9,6 +9,6 @@ struct euicc_driver {
|
|||
enum euicc_driver_type type;
|
||||
const char *name;
|
||||
int (*init)(void *interface);
|
||||
int (*main)(int argc, char **argv);
|
||||
int (*main)(void *interface, int argc, char **argv);
|
||||
void (*fini)(void *interface);
|
||||
};
|
||||
|
|
|
@ -174,14 +174,12 @@ static int libhttpinterface_init(struct euicc_http_interface *ifstruct) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int libhttpinterface_main(int argc, char **argv) { return 0; }
|
||||
|
||||
static void libhttpinterface_fini(struct euicc_http_interface *ifstruct) {}
|
||||
|
||||
const struct euicc_driver driver_http_curl = {
|
||||
.type = DRIVER_HTTP,
|
||||
.name = "curl",
|
||||
.init = (int (*)(void *))libhttpinterface_init,
|
||||
.main = libhttpinterface_main,
|
||||
.main = NULL,
|
||||
.fini = (void (*)(void *))libhttpinterface_fini,
|
||||
};
|
||||
|
|
|
@ -175,14 +175,12 @@ static int libhttpinterface_init(struct euicc_http_interface *ifstruct) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int libhttpinterface_main(int argc, char **argv) { return 0; }
|
||||
|
||||
static void libhttpinterface_fini(struct euicc_http_interface *ifstruct) {}
|
||||
|
||||
const struct euicc_driver driver_http_stdio = {
|
||||
.type = DRIVER_HTTP,
|
||||
.name = "stdio",
|
||||
.init = (int (*)(void *))libhttpinterface_init,
|
||||
.main = libhttpinterface_main,
|
||||
.main = NULL,
|
||||
.fini = (void (*)(void *))libhttpinterface_fini,
|
||||
};
|
||||
|
|
|
@ -7,6 +7,7 @@ else()
|
|||
endif()
|
||||
target_link_libraries(euicc cjson-static)
|
||||
target_include_directories(euicc PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>)
|
||||
target_compile_options(euicc PRIVATE -Wall -Wextra)
|
||||
if(LPAC_DYNAMIC_LIBEUICC)
|
||||
# Install headers
|
||||
file(GLOB ALL_HEADERS "*.h")
|
||||
|
|
|
@ -255,7 +255,7 @@ long euicc_derutil_convert_bin2long(const uint8_t *buffer, uint32_t buffer_len)
|
|||
int euicc_derutil_convert_long2bin(uint8_t *buffer, uint32_t *buffer_len, long value) {
|
||||
uint8_t required_len = 1;
|
||||
|
||||
for (int i = 1; i < sizeof(value); i++) {
|
||||
for (size_t i = 1; i < sizeof(value); i++) {
|
||||
if ((value >> (i * 8))) {
|
||||
required_len++;
|
||||
} else {
|
||||
|
|
19
euicc/es9p.c
19
euicc/es9p.c
|
@ -256,7 +256,7 @@ int es9p_initiate_authentication_r(struct euicc_ctx *ctx, char **transaction_id,
|
|||
struct es10b_authenticate_server_param *resp, const char *server_address,
|
||||
const char *b64_euicc_challenge, const char *b64_euicc_info_1) {
|
||||
const char *ikey[] = {"smdpAddress", "euiccChallenge", "euiccInfo1", NULL};
|
||||
const char *idata[] = {ctx->http.server_address, b64_euicc_challenge, b64_euicc_info_1, NULL};
|
||||
const char *idata[] = {server_address, b64_euicc_challenge, b64_euicc_info_1, NULL};
|
||||
const char *okey[] = {"transactionId", "serverSigned1", "serverSignature1",
|
||||
"euiccCiPKIdToBeUsed", "serverCertificate", NULL};
|
||||
const char oobj[] = {0, 0, 0, 0, 0};
|
||||
|
@ -267,8 +267,8 @@ int es9p_initiate_authentication_r(struct euicc_ctx *ctx, char **transaction_id,
|
|||
(void **)&resp->b64_serverCertificate,
|
||||
NULL};
|
||||
|
||||
if (es9p_trans_json(ctx, ctx->http.server_address, "/gsma/rsp2/es9plus/initiateAuthentication", ikey, idata, okey,
|
||||
oobj, optr)) {
|
||||
if (es9p_trans_json(ctx, server_address, "/gsma/rsp2/es9plus/initiateAuthentication", ikey, idata, okey, oobj,
|
||||
optr)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -289,8 +289,8 @@ int es9p_get_bound_profile_package_r(struct euicc_ctx *ctx, char **b64_bound_pro
|
|||
const char oobj[] = {0};
|
||||
void **optr[] = {(void **)b64_bound_profile_package, NULL};
|
||||
|
||||
if (es9p_trans_json(ctx, ctx->http.server_address, "/gsma/rsp2/es9plus/getBoundProfilePackage", ikey, idata, okey,
|
||||
oobj, optr)) {
|
||||
if (es9p_trans_json(ctx, server_address, "/gsma/rsp2/es9plus/getBoundProfilePackage", ikey, idata, okey, oobj,
|
||||
optr)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -309,8 +309,7 @@ int es9p_authenticate_client_r(struct euicc_ctx *ctx, struct es10b_prepare_downl
|
|||
void **optr[] = {(void **)&resp->b64_profileMetadata, (void **)&resp->b64_smdpSigned2,
|
||||
(void **)&resp->b64_smdpSignature2, (void **)&resp->b64_smdpCertificate, NULL};
|
||||
|
||||
if (es9p_trans_json(ctx, ctx->http.server_address, "/gsma/rsp2/es9plus/authenticateClient", ikey, idata, okey, oobj,
|
||||
optr)) {
|
||||
if (es9p_trans_json(ctx, server_address, "/gsma/rsp2/es9plus/authenticateClient", ikey, idata, okey, oobj, optr)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -327,8 +326,7 @@ int es9p_cancel_session_r(struct euicc_ctx *ctx, const char *server_address, con
|
|||
const char *ikey[] = {"transactionId", "cancelSessionResponse", NULL};
|
||||
const char *idata[] = {transaction_id, b64_cancel_session_response, NULL};
|
||||
|
||||
if (es9p_trans_json(ctx, ctx->http.server_address, "/gsma/rsp2/es9plus/cancelSession", ikey, idata, NULL, NULL,
|
||||
NULL)) {
|
||||
if (es9p_trans_json(ctx, server_address, "/gsma/rsp2/es9plus/cancelSession", ikey, idata, NULL, NULL, NULL)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -346,8 +344,7 @@ int es11_authenticate_client_r(struct euicc_ctx *ctx, char ***smdp_list, const c
|
|||
const char oobj[] = {1};
|
||||
void **optr[] = {(void **)&j_eventEntries, NULL};
|
||||
|
||||
if (es9p_trans_json(ctx, ctx->http.server_address, "/gsma/rsp2/es9plus/authenticateClient", ikey, idata, okey, oobj,
|
||||
optr)) {
|
||||
if (es9p_trans_json(ctx, server_address, "/gsma/rsp2/es9plus/authenticateClient", ikey, idata, okey, oobj, optr)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ static const struct es9p_error es9p_errors[] = {
|
|||
|
||||
const char *es9p_error_message(const char *subject_code, const char *reason_code) {
|
||||
struct es9p_error error;
|
||||
for (int i = 0; i < sizeof(es9p_errors) / sizeof(es9p_errors[0]); i++) {
|
||||
for (size_t i = 0; i < sizeof(es9p_errors) / sizeof(es9p_errors[0]); i++) {
|
||||
error = es9p_errors[i];
|
||||
if (strcmp(error.subject_code, subject_code) == 0 && strcmp(error.reason_code, reason_code) == 0) {
|
||||
return error.description;
|
||||
|
|
|
@ -125,13 +125,13 @@ int euicc_hexutil_bin2gsmbcd(char *output, uint32_t output_len, const uint8_t *b
|
|||
}
|
||||
|
||||
length = strlen(output);
|
||||
for (int i = 0; i < length - 1; i += 2) {
|
||||
for (size_t i = 0; i < length - 1; i += 2) {
|
||||
char temp = output[i];
|
||||
output[i] = output[i + 1];
|
||||
output[i + 1] = temp;
|
||||
}
|
||||
|
||||
for (int i = length - 1; i >= 0; i--) {
|
||||
for (uint32_t i = length - 1; i > 0; i--) {
|
||||
if (output[i] != 'f') {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -11,9 +11,10 @@ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/applet/chip DIR_LPAC_SRCS)
|
|||
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/applet/notification DIR_LPAC_SRCS)
|
||||
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/applet/profile DIR_LPAC_SRCS)
|
||||
|
||||
add_executable(lpac ${DIR_LPAC_SRCS})
|
||||
add_executable(lpac ${DIR_LPAC_SRCS} lpac.manifest)
|
||||
target_link_libraries(lpac euicc-drivers lpac-utils)
|
||||
target_include_directories(lpac PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
|
||||
target_compile_options(lpac PRIVATE -Wall -Wextra)
|
||||
|
||||
find_package(Git)
|
||||
add_custom_target(version
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int applet_main(int argc, char **argv) {
|
||||
static int applet_main(__attribute__((unused)) int argc, __attribute__((unused)) char **argv) {
|
||||
_cleanup_free_ char *eid = NULL;
|
||||
_cleanup_(es10a_euicc_configured_addresses_free) struct es10a_euicc_configured_addresses addresses;
|
||||
_cleanup_es10b_rat_list_ struct es10b_rat *ratList;
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int applet_main(int argc, char **argv) {
|
||||
static int applet_main(__attribute__((unused)) int argc, __attribute__((unused)) char **argv) {
|
||||
_cleanup_es10b_notification_metadata_list_ struct es10b_notification_metadata_list *notifications, *rptr;
|
||||
cJSON *jdata = NULL;
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ static int handle_notification(const uint32_t seqNumber, const struct es10b_pend
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int applet_main(const int argc, char **argv) {
|
||||
static int applet_main(__attribute__((unused)) const int argc, __attribute__((unused)) char **argv) {
|
||||
if (isatty(fileno(stdin))) {
|
||||
jprint_error("This applet must be run with input redirection from a file or pipe.", NULL);
|
||||
return -1;
|
||||
|
|
|
@ -43,7 +43,7 @@ char *strsep(char **stringp, const char *__delim) {
|
|||
|
||||
static bool is_strict_matching_id(const char *token) {
|
||||
const size_t n = strlen(token);
|
||||
for (int i = 0; i < n; i++) {
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
if (isalnum(token[i]) || token[i] == '-')
|
||||
continue;
|
||||
return false;
|
||||
|
@ -51,7 +51,7 @@ static bool is_strict_matching_id(const char *token) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static void sigint_handler(int x) { cancelled = 1; }
|
||||
static void sigint_handler(__attribute__((unused)) int x) { cancelled = 1; }
|
||||
|
||||
static cJSON *build_download_result_json(const struct es10b_load_bound_profile_package_result *result) {
|
||||
cJSON *jdata = cJSON_CreateObject();
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int applet_main(int argc, char **argv) {
|
||||
static int applet_main(__attribute__((unused)) int argc, __attribute__((unused)) char **argv) {
|
||||
_cleanup_es10c_profile_info_list_ struct es10c_profile_info_list *profiles;
|
||||
struct es10c_profile_info_list *rptr;
|
||||
cJSON *jdata = NULL;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# define LPAC_VERSION "v0.0.0-unknown"
|
||||
#endif
|
||||
|
||||
static int applet_main(int argc, char **argv) {
|
||||
static int applet_main(__attribute__((unused)) int argc, __attribute__((unused)) char **argv) {
|
||||
jprint_success(cJSON_CreateString(LPAC_VERSION));
|
||||
return 0;
|
||||
}
|
||||
|
|
9
src/lpac.manifest
Normal file
9
src/lpac.manifest
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity type="win32" name="me.estk.lpac" version="6.0.0.0"/>
|
||||
<application>
|
||||
<windowsSettings>
|
||||
<activeCodePage xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">UTF-8</activeCodePage>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
</assembly>
|
12
src/main.c
12
src/main.c
|
@ -15,6 +15,7 @@
|
|||
#include <driver.h>
|
||||
#include <euicc/euicc.h>
|
||||
#include <euicc/hexutil.h>
|
||||
#include <lpac/utils.h>
|
||||
|
||||
#ifdef WIN32
|
||||
# include <windef.h>
|
||||
|
@ -25,16 +26,13 @@
|
|||
# include <stringapiset.h>
|
||||
#endif
|
||||
|
||||
#define ENV_ISD_R_AID "LPAC_CUSTOM_ISD_R_AID"
|
||||
#define ENV_ISD_R_AID CUSTOM_ENV_NAME(ISD_R_AID)
|
||||
#define ISD_R_AID_MAX_LENGTH 16
|
||||
|
||||
#define ENV_ES10X_MSS "LPAC_CUSTOM_ES10X_MSS"
|
||||
#define ENV_ES10X_MSS CUSTOM_ENV_NAME(ES10X_MSS)
|
||||
#define ES10X_MSS_MIN_VALUE 6
|
||||
#define ES10X_MSS_MAX_VALUE 255
|
||||
|
||||
#define ENV_APDU_DRIVER "LPAC_APDU"
|
||||
#define ENV_HTTP_DRIVER "LPAC_HTTP"
|
||||
|
||||
static int driver_applet_main(const int argc, char **argv) {
|
||||
const struct applet_entry *applets[] = {
|
||||
&(struct applet_entry){
|
||||
|
@ -103,7 +101,7 @@ static int setup_mss(uint8_t *mss) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int main_init_euicc() {
|
||||
int main_init_euicc(void) {
|
||||
if (setup_aid(&euicc_ctx.aid, &euicc_ctx.aid_len)) {
|
||||
jprint_error("euicc_init", "invalid custom ISD-R applet id given");
|
||||
return -1;
|
||||
|
@ -120,7 +118,7 @@ int main_init_euicc() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void main_fini_euicc() {
|
||||
void main_fini_euicc(void) {
|
||||
if (!euicc_ctx_inited) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
add_library(lpac-utils OBJECT lpac/utils.c)
|
||||
target_include_directories(lpac-utils PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(lpac-utils PRIVATE cjson-static euicc)
|
||||
target_compile_options(lpac-utils PRIVATE -Wall -Wextra)
|
||||
|
|
|
@ -8,8 +8,12 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define HTTP_ENV_NAME(DRIVER, NAME) "LPAC_HTTP_" #DRIVER "_" #NAME
|
||||
#define APDU_ENV_NAME(DRIVER, NAME) "LPAC_APDU_" #DRIVER "_" #NAME
|
||||
#define ENV_HTTP_DRIVER "LPAC_HTTP"
|
||||
#define ENV_APDU_DRIVER "LPAC_APDU"
|
||||
|
||||
#define HTTP_ENV_NAME(DRIVER, NAME) ENV_HTTP_DRIVER "_" #DRIVER "_" #NAME
|
||||
#define APDU_ENV_NAME(DRIVER, NAME) ENV_APDU_DRIVER "_" #DRIVER "_" #NAME
|
||||
#define CUSTOM_ENV_NAME(NAME) "LPAC_CUSTOM_" #NAME
|
||||
|
||||
#define _cleanup_(x) __attribute__((cleanup(x)))
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue