Skip to content

Commit

Permalink
Move drivers into libeuicc-drivers.so (estkme-group#59)
Browse files Browse the repository at this point in the history
* Move drivers back to their own (optionally dynamic)

This allows for reuse from projects dynamically linked to libeuicc. Note
that we don't reintroduce dlopen() based drivers here.

All backends except stdio have been made optional using CMake options.
C-side macros in driver.c have been adjusted to always mean enabling the
corresponding backend when defined.

Note that the GBinder backend does not need to distinguish between the
current HIDL version and a future AIDL implementation. Both will have
the same dependencies and will probably fall back on to each other
automatically.

* Set up installed headers and pkg-config for libeuicc-drivers.so

Also separate lpac_driver struct from the installed version

* Namespace all exposed symbols in libeuicc-drivers.so

* Add back output directory config

This is needed by github actions

* curl is dlopen()'d on Windows
  • Loading branch information
PeterCxy authored and ocd0711 committed May 7, 2024
1 parent 922edc1 commit b7a4000
Show file tree
Hide file tree
Showing 25 changed files with 196 additions and 190 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,5 @@ endif()

add_subdirectory(cjson)
add_subdirectory(euicc)
add_subdirectory(driver)
add_subdirectory(src)
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ then execute `./output/lpac` to use.

- Droidian

Same as normal Debian/Ubuntu, however, in order to build the GBinder backends, you will need `libgbinder-dev`, `glib2.0-dev`, and you will have to set `-DLPAC_APDU_INTERFACE_GBINDER=ON` when invoking `cmake`.
Same as normal Debian/Ubuntu, however, in order to build the GBinder backends, you will need `libgbinder-dev`, `glib2.0-dev`, and you will have to set `-DLPAC_WITH_APDU_GBINDER=ON` when invoking `cmake`.

</details>

Expand Down Expand Up @@ -487,7 +487,7 @@ A: The verification of SM-DP+ servers of telecom operators is diverse. Please ch

## License

- lpac (/src): AGPL-3.0
- lpac (/src, /driver): AGPL-3.0
- libeuicc (/euicc): LGPL-v2

Copyright (c) 2023-2024 eSTKme Group
16 changes: 16 additions & 0 deletions driver.private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

enum lpac_driver_type
{
DRIVER_APDU,
DRIVER_HTTP,
};

struct lpac_driver
{
enum lpac_driver_type type;
const char *name;
int (*init)(void *interface);
int (*main)(int argc, char **argv);
void (*fini)(void);
};
75 changes: 75 additions & 0 deletions driver/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
include(CMakeDependentOption)
cmake_dependent_option(LPAC_DYNAMIC_DRIVERS "Build lpac/libeuicc driver backends as a dynamic library" OFF "LPAC_DYNAMIC_LIBEUICC" OFF)

option(LPAC_WITH_APDU_PCSC "Build APDU PCSC Backend (requires PCSC libraries)" ON)
option(LPAC_WITH_APDU_AT "Build APDU AT Backend" ON)
option(LPAC_WITH_APDU_GBINDER "Build APDU Gbinder backend for libhybris devices (requires gbinder headers)" OFF)

option(LPAC_WITH_HTTP_CURL "Build HTTP Curl interface" ON)

aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} DIR_INTERFACE_SRCS)
if(LPAC_DYNAMIC_DRIVERS)
add_library(euicc-drivers SHARED ${DIR_INTERFACE_SRCS})
else()
add_library(euicc-drivers STATIC ${DIR_INTERFACE_SRCS})
endif()
target_link_libraries(euicc-drivers euicc cjson-static)
target_include_directories(euicc-drivers PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

target_sources(euicc-drivers PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/apdu/stdio.c)
target_sources(euicc-drivers PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/http/stdio.c)

if(LPAC_WITH_APDU_PCSC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DLPAC_WITH_APDU_PCSC")
target_sources(euicc-drivers PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/apdu/pcsc.c)
if(WIN32)
target_link_libraries(euicc-drivers winscard)
elseif(APPLE)
target_link_libraries(euicc-drivers "-framework PCSC")
else()
find_package(PCSCLite)
target_link_libraries(euicc-drivers PCSCLite::PCSCLite)
endif()
endif()

if(LPAC_WITH_APDU_AT)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DLPAC_WITH_APDU_AT")
target_sources(euicc-drivers PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/apdu/at.c)
endif()

if(LPAC_WITH_APDU_GBINDER)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DLPAC_WITH_APDU_GBINDER")
target_sources(euicc-drivers PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/apdu/gbinder_hidl.c)
find_package(PkgConfig REQUIRED)
pkg_check_modules(GBINDER REQUIRED IMPORTED_TARGET libgbinder)
pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
target_link_libraries(euicc-drivers PkgConfig::GBINDER PkgConfig::GLIB)
endif()

if(LPAC_WITH_HTTP_CURL)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DLPAC_WITH_HTTP_CURL")
target_sources(euicc-drivers PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/http/curl.c)
if(WIN32)
target_link_libraries(euicc-drivers ${DL_LIBRARY})
else()
find_package(curl)
target_link_libraries(euicc-drivers curl)
endif()
endif()

if(LPAC_DYNAMIC_DRIVERS)
# Install headers
file(GLOB ALL_HEADERS "*.h")
foreach(header ${ALL_HEADERS})
if(${header} MATCHES "^.*\.private\.h$")
list(REMOVE_ITEM ALL_HEADERS ${header})
endif()
endforeach()
set_target_properties(euicc-drivers PROPERTIES PUBLIC_HEADER "${ALL_HEADERS}")
# Install a pkg-config file
configure_file(libeuicc-drivers.pc.in libeuicc-drivers.pc @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libeuicc-drivers.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
set_target_properties(euicc-drivers PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR})
install(TARGETS euicc-drivers LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/euicc)
endif()
File renamed without changes.
2 changes: 1 addition & 1 deletion src/driver/apdu/at.h → driver/apdu/at.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#pragma once
#include <driver.h>
#include <driver.private.h>

extern const struct lpac_driver driver_apdu_at;
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#pragma once
#include <driver.h>
#include <driver.private.h>

extern const struct lpac_driver driver_apdu_gbinder_hidl;
File renamed without changes.
2 changes: 1 addition & 1 deletion src/driver/apdu/pcsc.h → driver/apdu/pcsc.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#pragma once
#include <driver.h>
#include <driver.private.h>

extern const struct lpac_driver driver_apdu_pcsc;
File renamed without changes.
2 changes: 1 addition & 1 deletion src/driver/apdu/stdio.h → driver/apdu/stdio.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#pragma once
#include <driver.h>
#include <driver.private.h>

extern const struct lpac_driver driver_apdu_stdio;
60 changes: 20 additions & 40 deletions src/driver.c → driver/driver.c
Original file line number Diff line number Diff line change
@@ -1,57 +1,52 @@
#include "driver.h"
#include "driver.private.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef LPAC_WITH_APDU_GBINDER_HIDL
#ifdef LPAC_WITH_APDU_GBINDER
#include "driver/apdu/gbinder_hidl.h"
#endif

#ifndef LPAC_WITHOUT_APDU_PCSC
#ifdef LPAC_WITH_APDU_PCSC
#include "driver/apdu/pcsc.h"
#endif
#ifndef LPAC_WITHOUT_APDU_AT
#ifdef LPAC_WITH_APDU_AT
#include "driver/apdu/at.h"
#endif
#ifndef LPAC_WITHOUT_HTTP_CURL
#ifdef LPAC_WITH_HTTP_CURL
#include "driver/http/curl.h"
#endif
#include "driver/apdu/stdio.h"
#include "driver/http/stdio.h"

static const struct lpac_driver *drivers[] = {
#ifdef LPAC_WITH_APDU_GBINDER_HIDL
#ifdef LPAC_WITH_APDU_GBINDER
&driver_apdu_gbinder_hidl,
#endif
#ifndef LPAC_WITHOUT_APDU_PCSC
#ifdef LPAC_WITH_APDU_PCSC
&driver_apdu_pcsc,
#endif
#ifndef LPAC_WITHOUT_APDU_AT
#ifdef LPAC_WITH_APDU_AT
&driver_apdu_at,
#endif
#ifndef LPAC_WITHOUT_HTTP_CURL
#ifdef LPAC_WITH_HTTP_CURL
&driver_http_curl,
#endif
&driver_apdu_stdio,
&driver_http_stdio,
NULL,
};

struct euicc_apdu_interface driver_interface_apdu;
struct euicc_http_interface driver_interface_http;
static struct applet_entry applet_apdu = {
.name = "apdu",
.main = NULL,
};
static struct applet_entry applet_http = {
.name = "http",
.main = NULL,
};

static const struct lpac_driver *_driver_apdu = NULL;
static const struct lpac_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 lpac_driver *_find_driver(enum lpac_driver_type type, const char *name)
{
for (int i = 0; drivers[i] != NULL; i++)
Expand All @@ -73,7 +68,7 @@ static const struct lpac_driver *_find_driver(enum lpac_driver_type type, const
return NULL;
}

int driver_init()
int euicc_driver_init()
{
_driver_apdu = _find_driver(DRIVER_APDU, getenv("LPAC_APDU"));
if (_driver_apdu == NULL)
Expand All @@ -89,16 +84,16 @@ int driver_init()
return -1;
}

_driver_apdu->init(&driver_interface_apdu);
_driver_http->init(&driver_interface_http);
_driver_apdu->init(&euicc_driver_interface_apdu);
_driver_http->init(&euicc_driver_interface_http);

applet_apdu.main = _driver_apdu->main;
applet_http.main = _driver_http->main;
euicc_driver_main_apdu = _driver_apdu->main;
euicc_driver_main_http = _driver_http->main;

return 0;
}

void driver_fini()
void euicc_driver_fini()
{
if (_driver_apdu != NULL)
{
Expand All @@ -109,18 +104,3 @@ void driver_fini()
_driver_http->fini();
}
}

static int dlsym_interface_applet_main(int argc, char **argv)
{
static const struct applet_entry *applets[] = {
&applet_apdu,
&applet_http,
NULL,
};
return applet_entry(argc, argv, applets);
}

struct applet_entry driver_applet = {
.name = "driver",
.main = dlsym_interface_applet_main,
};
12 changes: 12 additions & 0 deletions driver/driver.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once
#include <stddef.h>
#include <inttypes.h>
#include <euicc/interface.h>

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_init(void);
void euicc_driver_fini(void);
17 changes: 17 additions & 0 deletions driver/driver.private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

enum lpac_driver_type
{
DRIVER_APDU,
DRIVER_HTTP,
};

struct lpac_driver
{
enum lpac_driver_type type;
const char *name;
int (*init)(void *interface);
int (*main)(int argc, char **argv);
void (*fini)(void);
};

File renamed without changes.
2 changes: 1 addition & 1 deletion src/driver/http/curl.h → driver/http/curl.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#pragma once
#include <driver.h>
#include <driver.private.h>

extern const struct lpac_driver driver_http_curl;
File renamed without changes.
2 changes: 1 addition & 1 deletion src/driver/http/stdio.h → driver/http/stdio.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#pragma once
#include <driver.h>
#include <driver.private.h>

extern const struct lpac_driver driver_http_stdio;
11 changes: 11 additions & 0 deletions driver/libeuicc-drivers.pc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
prefix="@CMAKE_INSTALL_PREFIX@"
exec_prefix="${prefix}"
libdir="${prefix}/lib"
includedir="${prefix}/include"

Name: libeuicc-drivers
Description: An "official" collection of drivers (backends) and their loader for use with libeuicc
Version: @PROJECT_VERSION@
Requires: libeuicc = @PROJECT_VERSION@
Cflags: -I${includedir}
Libs: -L${libdir} -leuicc-drivers
17 changes: 5 additions & 12 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,8 @@ 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)

aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/driver DIR_LPAC_SRCS)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/driver/apdu DIR_LPAC_SRCS)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/driver/http DIR_LPAC_SRCS)

find_package(PCSCLite)
find_package(curl)

add_executable(lpac ${DIR_LPAC_SRCS})
set_target_properties(lpac PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/output"
BUILD_RPATH "${RPATH_BINARY_PATH}"
)
target_link_libraries(lpac euicc PCSCLite::PCSCLite curl ${DL_LIBRARY})
target_link_libraries(lpac euicc euicc-drivers)
target_include_directories(lpac PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)

find_package(Git)
Expand All @@ -35,6 +24,10 @@ add_custom_target(version
-P ${CMAKE_MODULE_PATH}/git-version.cmake
)
add_dependencies(lpac version)
set_target_properties(lpac PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/output"
BUILD_RPATH "${RPATH_BINARY_PATH}"
)

if(UNIX)
install(TARGETS lpac RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
Expand Down
27 changes: 0 additions & 27 deletions src/driver.h

This file was deleted.

Loading

0 comments on commit b7a4000

Please sign in to comment.