diff --git a/clego/.env.build.linux.example b/clego/.env.build.linux.example new file mode 100644 index 0000000..e7ab058 --- /dev/null +++ b/clego/.env.build.linux.example @@ -0,0 +1,3 @@ +SESAM_FSV_VERSION=1.40.13 +SESAM_FSV_LIB_PATH=/opt/santesocial/fsv/${SESAM_FSV_VERSION}/lib +SESAM_FSV_SSVLIB=ssvlux64 diff --git a/clego/.env.build.win.example b/clego/.env.build.win.example new file mode 100644 index 0000000..872ef1a --- /dev/null +++ b/clego/.env.build.win.example @@ -0,0 +1,3 @@ +SESAM_FSV_VERSION=1.40.13 +SESAM_FSV_LIB_PATH="C:/Program Files/santesocial/fsv/${SESAM_FSV_VERSION}/lib" +SESAM_FSV_SSVLIB=ssvw64 diff --git a/clego/.env.linux.example b/clego/.env.linux.example new file mode 100644 index 0000000..c8d84aa --- /dev/null +++ b/clego/.env.linux.example @@ -0,0 +1,2 @@ +SESAM_FSV_VERSION=1.40.13 +SESAM_INI_PATH=/etc/opt/santesocial/fsv/${SESAM_FSV_VERSION}/conf/sesam.ini diff --git a/clego/.env.win.example b/clego/.env.win.example new file mode 100644 index 0000000..bcd5177 --- /dev/null +++ b/clego/.env.win.example @@ -0,0 +1,2 @@ +SESAM_FSV_VERSION=1.40.13 +SESAM_INI_PATH=${ALLUSERSPROFILE}\\santesocial\\fsv\\${SESAM_FSV_VERSION}\\conf\\sesam.ini diff --git a/clego/.gitignore b/clego/.gitignore new file mode 100644 index 0000000..33da66d --- /dev/null +++ b/clego/.gitignore @@ -0,0 +1,6 @@ +# Ignore Rust target directory +/target + +# Ignore .env files +.env +.env.build \ No newline at end of file diff --git a/clego/Cargo.toml b/clego/Cargo.toml index a4fc835..e604456 100644 --- a/clego/Cargo.toml +++ b/clego/Cargo.toml @@ -4,4 +4,8 @@ version = "0.1.0" edition = "2021" [dependencies] -winapi = { version = "0.3.8", features = ["winuser","libloaderapi"] } +dotenv = "0.15" +libc = "0.2" + +[build-dependencies] +dotenv = "0.15" diff --git a/clego/README.md b/clego/README.md new file mode 100644 index 0000000..4b88d2a --- /dev/null +++ b/clego/README.md @@ -0,0 +1,33 @@ +## Requirements + +- Installer le [package FSV](https://industriels.sesam-vitale.fr/group/fournitures-sesam-vitale) + - Les librairies dynamiques (.lib, .dll, ...) fournies ne sont pas installés dans les emplacements standard du système, il faudra donc configurer leur chemin d'installation dans le fichier de configuration `.env.build` (voir ci-dessous) + - Le détail des chemins d'installation est donné dans la documentation du package FSV `fsv-mi-004_pack-FSV1.40.14_V2.3.pdf` + - Linux - par défaut : `/opt/santesocial/fsv/1.40.13/lib` + - Windows - par défaut : `C:\Program Files\santesocial\santesocial\fsv\1.40.14\lib` (ou dans Program Files (x86) si c'est le package 32bits qui a été installé) + +- Installer la [CryptolibCPS](https://industriels.sesam-vitale.fr/group/galss-cryptolib-cps) + - Ce package fourni également l'utilitaire "CPS Gestion" pour obtenir des informations sur le lecteur de carte, etc. + - Linux : `cpgeslux` + - Windows : `...` + +## Setup + +- Créer et éditer le fichier de configuration de build `.env.build` en s'inspirant d'un des fichiers d'exemple (`.env.build.linux.example`, `.env.build.win.example`...) + - Ce fichier est nécessaire pour le build du package Rust +- Créer et éditer le fichier de configuration de l'exécution `.env` en s'inspirant d'un des fichiers d'exemple (`.env.linux.example`, `.env.win.example`...) + - Ce fichier est nécessaire pour l'exécution du package Rust compilé, et doit donc être présent aux côtés de l'exécutable généré, le cas échéant + +## Build + +### Windows - Compilation des headers FSV + +Sous windows, la librairie dynamique fournie par le package FSV nécessite des header qui ne sont pas présents dans la `.dll`. Il est donc nécessaire de fournir ces headers, en les renseignant dans des fichiers `src/ssv_headers_c/*.def` qui seront compilés en leur version binaire `lib/*.lib`. + +En cas de modification des fichiers `.def`, pour re-compiler ces headers, faire appel au script `make.bat` du dossier `src/ssv_headers_c`. + + +## À creuser + +- Compilation cross platform facilitée par du Docker : https://github.com/cross-rs/cross +- Pour éviter l'usage de dotenv pour la configuration, on peut utiliser https://direnv.net/ diff --git a/clego/build.rs b/clego/build.rs new file mode 100644 index 0000000..15d7c70 --- /dev/null +++ b/clego/build.rs @@ -0,0 +1,31 @@ +extern crate dotenv; + +use std::env; +use std::path::PathBuf; + +fn main() { + // Load the .env.build file for build-time environment variables + dotenv::from_filename(".env.build").ok(); + println!("cargo::rerun-if-changed=.env.build"); + + let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + + // Add local lib directory to the linker search path (for def files and static libs) + let static_lib_path = PathBuf::from(manifest_dir).join("lib"); + println!("cargo::rustc-link-search=native={}", static_lib_path.display()); + + // Add the SESAM_FSV_LIB_PATH to the linker search path + let fsv_lib_path = PathBuf::from(env::var("SESAM_FSV_LIB_PATH").unwrap()); + println!("cargo::rustc-link-search=native={}", fsv_lib_path.display()); + + // Add the SESAM_FSV_LIB_PATH to the PATH environment variable + if cfg!(target_os = "windows") { + let path = env::var("PATH").unwrap_or(String::new()); + println!("cargo:rustc-env=PATH={};{}", fsv_lib_path.display(), path); + } else if cfg!(target_os = "linux") { + println!("cargo:rustc-env=LD_LIBRARY_PATH={}", fsv_lib_path.display()); + } + + // Link the SESAM_FSV_SSVLIB dynamic library + println!("cargo::rustc-link-lib=dylib={}", env::var("SESAM_FSV_SSVLIB").unwrap()); +} diff --git a/clego/lib/.gitkeep b/clego/lib/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/clego/src/ssv_headers_c/make.bat b/clego/src/ssv_headers_c/make.bat new file mode 100644 index 0000000..96a9f49 --- /dev/null +++ b/clego/src/ssv_headers_c/make.bat @@ -0,0 +1,27 @@ +@echo off +rem Set variables +set LIB_DIR=..\..\lib + +rem Create the %LIB_DIR% directory if it does not exist +if not exist %LIB_DIR% mkdir %LIB_DIR% + +if "%1"=="/clean" ( + goto clean +) + +@REM rem Set the environment for the x64 platform +@REM call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" x64 + +rem Create a ssvw64.lib file from the ssvw64.def file +lib /def:ssvw64.def /out:%LIB_DIR%\ssvw64.lib /machine:x64 + +rem Build complete +pause +exit /b 0 + +:clean +del %LIB_DIR%\*.lib + +rem Clean complete +pause +exit /b 0 diff --git a/clego/src/ssv_headers_c/ssvw64.def b/clego/src/ssv_headers_c/ssvw64.def new file mode 100644 index 0000000..4d66637 --- /dev/null +++ b/clego/src/ssv_headers_c/ssvw64.def @@ -0,0 +1,5 @@ +LIBRARY "ssvw64" +EXPORTS + SSV_InitLIB2 + SSV_LireCartePS + SSV_LireConfig diff --git a/clego/src/ssvlib_demo.rs b/clego/src/ssvlib_demo.rs new file mode 100644 index 0000000..9dd6f3e --- /dev/null +++ b/clego/src/ssvlib_demo.rs @@ -0,0 +1,84 @@ +extern crate libc; +extern crate dotenv; + +use libc::{ c_char, c_void, c_ushort, size_t }; +use std::ffi::CString; +use std::ptr; + +use dotenv::dotenv; +use std::env; + +extern "C" { + fn SSV_InitLIB2(pcRepSesamIni: *const c_char) -> c_ushort; + fn SSV_LireCartePS(NomRessourcePS: *const c_char, NomRessourceLecteur: *const c_char, CodePorteurPS: *const c_char, ZDonneesSortie: *mut *mut c_void, TTailleDonneesSortie: *mut size_t) -> c_ushort; + fn SSV_LireConfig(ZDonneesSortie: *mut *mut c_void, TTailleDonneesSortie: *mut size_t) -> c_ushort; +} + +fn ssv_init_lib_2() { + let ini_str = env::var("SESAM_INI_PATH").expect("SESAM_INI_PATH must be set"); + let ini = CString::new(ini_str).expect("CString::new failed"); + unsafe { + let result = SSV_InitLIB2(ini.as_ptr()); + println!("SSV_InitLIB2 result: {}", result); + } +} + +fn ssv_lire_carte_ps() { + let resource_ps = CString::new("PS").expect("CString::new failed"); + let resource_reader = CString::new("TRANSPA1").expect("CString::new failed"); + let card_number = CString::new("1234567890").expect("CString::new failed"); + + let mut buffer: *mut c_void = ptr::null_mut(); + let mut size: size_t = 0; + unsafe { + let result = SSV_LireCartePS( + resource_ps.as_ptr(), + resource_reader.as_ptr(), + card_number.as_ptr(), + &mut buffer, + &mut size + ); + println!("SSV_LireCartePS result: {}", result); + + if !buffer.is_null() { + let hex_values = std::slice::from_raw_parts(buffer as *const u8, size); + for &byte in hex_values { + print!("{:02X} ", byte); + } + println!(); + + libc::free(buffer); + } + } +} + +fn ssv_lire_config() { + let mut buffer: *mut c_void = ptr::null_mut(); + let mut size: size_t = 0; + unsafe { + let result = SSV_LireConfig(&mut buffer, &mut size); + println!("SSV_LireConfig result: {}", result); + + if !buffer.is_null() { + let hex_values = std::slice::from_raw_parts(buffer as *const u8, size); + for &byte in hex_values { + print!("{:02X} ", byte); + } + println!(); + + libc::free(buffer); + } + } +} + +pub fn demo() { + dotenv().ok(); + + println!("------- Demo for the SSV library --------"); + + ssv_init_lib_2(); + ssv_lire_carte_ps(); + ssv_lire_config(); + + println!("-----------------------------------------"); +}