Compare commits

..

6 Commits

Author SHA1 Message Date
af92e316da
feat: Création de la crate fsv, couche de haut niveau pour l'usage des librairies FSV 2024-10-01 19:13:03 +02:00
c9b1895e0c
fixup! feat: Gestion des versions multiples de FSV dans le wrapper exposant les fonctions de la librairie 2024-10-01 19:08:27 +02:00
7992f3df0e
feat: improve the fsv-sys README, and add a PROGESS.md for implementation tracking 2024-09-30 23:58:49 +02:00
59c325024a
feat: Gestion des versions multiples de FSV dans le wrapper exposant les fonctions de la librairie 2024-09-30 23:40:55 +02:00
473212c2e6
feat: handle multi-version bindings generation 2024-09-29 21:46:10 +02:00
f71b99a4c0
feat: Première implémentation de bindings pour FSV SESAM-Vitale
- Création de la crates/fsv-sys
- Ajout des headers de la FSV 1.40.14.13 dans crates/fsv-sys/vendor
- Génération des bindings depuis ces headers avec bindgen
- Implémentation d'une structure de loading de la librairie au runtime
- Implémentation d'une macro permettant de générer facilement la couche d'accès aux fonctions de la librairie
2024-09-29 21:44:29 +02:00
7 changed files with 40 additions and 149 deletions

1
.gitattributes vendored
View File

@ -1 +0,0 @@
Cargo.lock -merge linguist-generated=false

2
Cargo.lock generated
View File

@ -1527,9 +1527,7 @@ dependencies = [
name = "fsv" name = "fsv"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow",
"fsv-sys", "fsv-sys",
"num_enum",
"thiserror", "thiserror",
"utils", "utils",
] ]

View File

@ -1,12 +0,0 @@
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(unused)]
pub mod BINDINGS_V1_40_14 {
include!(concat!(env!("OUT_DIR"), "/bindings_1.40.14.rs"));
}
pub mod BINDINGS_V1_40_13 {
include!(concat!(env!("OUT_DIR"), "/bindings_1.40.13.rs"));
}

View File

@ -1,17 +1,16 @@
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)] #![allow(non_snake_case)]
use std::marker::PhantomData; use std::marker::PhantomData;
mod bindings;
use bindings::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum SupportedFsvVersion { pub enum SUPPORTED_FSV_VERSIONS {
V1_40_14, // 1.40.14 V1_40_14, // 1.40.14
V1_40_13, // 1.40.13 V1_40_13, // 1.40.13
} }
impl SupportedFsvVersion { impl SUPPORTED_FSV_VERSIONS {
fn as_str(&self) -> &'static str { fn as_str(&self) -> &'static str {
match self { match self {
Self::V1_40_14 => "1.40.14", Self::V1_40_14 => "1.40.14",
@ -20,6 +19,14 @@ impl SupportedFsvVersion {
} }
} }
mod BINDINGS_V1_40_14 {
include!(concat!(env!("OUT_DIR"), "/bindings_1.40.14.rs"));
}
mod BINDINGS_V1_40_13 {
include!(concat!(env!("OUT_DIR"), "/bindings_1.40.13.rs"));
}
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]
pub enum Error { pub enum Error {
#[error(transparent)] #[error(transparent)]
@ -59,26 +66,26 @@ mod sealed { pub trait Sealed {}}
/// Wrapper around the SESAM-VITALE library /// Wrapper around the SESAM-VITALE library
/// This struct is responsible for loading the library and providing an interface to call its functions. /// This struct is responsible for loading the library and providing an interface to call its functions.
/// The library is loaded at creation and kept in memory until the struct is dropped. /// The library is loaded at creation and kept in memory until the struct is dropped.
pub trait SSVLibraryCommon { pub trait SSVLibrary_Common {
fn new(path: &str) -> Result<Self, Error> where Self: Sized; fn new(path: &str) -> Result<Self, Error> where Self: Sized;
} }
pub trait SSVLibraryVersion: sealed::Sealed {} pub trait SSVLibrary_Version: sealed::Sealed {}
pub struct V1_40_13 {} pub struct V1_40_13 {}
impl sealed::Sealed for V1_40_13 {} impl sealed::Sealed for V1_40_13 {}
impl SSVLibraryVersion for V1_40_13 {} impl SSVLibrary_Version for V1_40_13 {}
pub struct V1_40_14 {} pub struct V1_40_14 {}
impl sealed::Sealed for V1_40_14 {} impl sealed::Sealed for V1_40_14 {}
impl SSVLibraryVersion for V1_40_14 {} impl SSVLibrary_Version for V1_40_14 {}
pub struct SSVLibrary<Version: SSVLibraryVersion> { pub struct SSVLibrary<Version: SSVLibrary_Version> {
_version: PhantomData<Version>, _version: PhantomData<Version>,
library: libloading::Library, library: libloading::Library,
} }
impl<Version: SSVLibraryVersion> SSVLibraryCommon for SSVLibrary<Version> { impl<Version: SSVLibrary_Version> SSVLibrary_Common for SSVLibrary<Version> {
fn new(path: &str) -> Result<Self, Error> { fn new(path: &str) -> Result<Self, Error> {
let library = unsafe { libloading::Library::new(path)?}; let library = unsafe { libloading::Library::new(path)?};
Ok(Self { Ok(Self {
@ -130,14 +137,14 @@ impl SSVLibrary<V1_40_13> {
}); });
} }
pub fn get_library_path(version: &SupportedFsvVersion) -> String { pub fn get_library_path(version: &SUPPORTED_FSV_VERSIONS) -> String {
let root_path = get_library_root_path(); let root_path = get_library_root_path();
let library_name = get_library_name(); let library_name = get_library_name();
let version = version.as_str(); let version = version.as_str();
format!("{root_path}/{version}/lib/{library_name}") format!("{root_path}/{version}/lib/{library_name}")
} }
pub fn sesam_ini_path(version: &SupportedFsvVersion) -> String { pub fn sesam_ini_path(version: &SUPPORTED_FSV_VERSIONS) -> String {
let root_path = get_sesam_ini_root_path(); let root_path = get_sesam_ini_root_path();
let version = version.as_str(); let version = version.as_str();
format!("{root_path}/{version}/conf/sesam.ini") format!("{root_path}/{version}/conf/sesam.ini")
@ -164,22 +171,22 @@ mod test {
#[test] #[test]
fn test_initlib2() { fn test_initlib2() {
let lib_path = &get_library_path(&SupportedFsvVersion::V1_40_13); let lib_path = &get_library_path(&SUPPORTED_FSV_VERSIONS::V1_40_13);
let ssv_library = SSVLibrary::<V1_40_13>::new(lib_path).expect("SSVLibrary::new failed"); let ssv_library = SSVLibrary::<V1_40_13>::new(lib_path).expect("SSVLibrary::new failed");
let sesam_ini_str = let sesam_ini_str =
CString::new(sesam_ini_path(&SupportedFsvVersion::V1_40_13)).expect("CString::new failed"); CString::new(sesam_ini_path(&SUPPORTED_FSV_VERSIONS::V1_40_13)).expect("CString::new failed");
let result = unsafe { ssv_library.ssv_init_lib2(sesam_ini_str.as_ptr()) }.unwrap(); let result = unsafe { ssv_library.ssv_init_lib2(sesam_ini_str.as_ptr()) }.unwrap();
assert_eq!(result, 0); assert_eq!(result, 0);
} }
#[test] #[test]
fn test_lire_config_and_carte_ps() { fn test_lire_config_and_carte_ps() {
let lib_path = &get_library_path(&SupportedFsvVersion::V1_40_13); let lib_path = &get_library_path(&SUPPORTED_FSV_VERSIONS::V1_40_13);
let ssv_library = SSVLibrary::<V1_40_13>::new(lib_path).expect("SSVLibrary::new failed"); let ssv_library = SSVLibrary::<V1_40_13>::new(lib_path).expect("SSVLibrary::new failed");
let sesam_ini_str = let sesam_ini_str =
CString::new(sesam_ini_path(&SupportedFsvVersion::V1_40_13)).expect("CString::new failed"); CString::new(sesam_ini_path(&SUPPORTED_FSV_VERSIONS::V1_40_13)).expect("CString::new failed");
let result = unsafe { ssv_library.ssv_init_lib2(sesam_ini_str.as_ptr()) }.unwrap(); let result = unsafe { ssv_library.ssv_init_lib2(sesam_ini_str.as_ptr()) }.unwrap();
assert_eq!(result, 0); assert_eq!(result, 0);

View File

@ -4,8 +4,6 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
anyhow = "1.0.89"
num_enum = "0.7.3"
thiserror = "1.0.64" thiserror = "1.0.64"
fsv-sys = { path = "../fsv-sys" } fsv-sys = { path = "../fsv-sys" }

View File

@ -1,24 +1,11 @@
use thiserror::Error; use thiserror::Error;
use fsv_sys::{ use fsv_sys::{get_library_path, Error as FsvError, SSVLibrary, SSVLibrary_Common, SUPPORTED_FSV_VERSIONS, V1_40_13, V1_40_14};
get_library_path,
Error as FsvError,
SSVLibrary,
SSVLibraryCommon,
SupportedFsvVersion,
V1_40_13,
V1_40_14
};
mod errors_ssv;
use errors_ssv::SSVErrorCodes;
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum Error { pub enum Error {
#[error(transparent)] #[error(transparent)]
FSVSysLibrary(#[from] FsvError), SysLibrary(#[from] FsvError)
#[error(transparent)]
SSVError(#[from] SSVErrorCodes),
} }
/// Enum to hold the different versions of the SSV library /// Enum to hold the different versions of the SSV library
@ -33,14 +20,14 @@ pub struct SSV {
} }
impl SSV { impl SSV {
fn new(version: SupportedFsvVersion) -> Result<Self, Error> { fn new(version: SUPPORTED_FSV_VERSIONS) -> Result<Self, Error> {
let library = match version { let library = match version {
SupportedFsvVersion::V1_40_13 => { SUPPORTED_FSV_VERSIONS::V1_40_13 => {
let lib_path = get_library_path(&version); let lib_path = get_library_path(&version);
let library = SSVLibrary::<V1_40_13>::new(&lib_path)?; let library = SSVLibrary::<V1_40_13>::new(&lib_path)?;
SsvLibraryVersion::V1_40_13(library) SsvLibraryVersion::V1_40_13(library)
}, },
SupportedFsvVersion::V1_40_14 => { SUPPORTED_FSV_VERSIONS::V1_40_14 => {
let lib_path = get_library_path(&version); let lib_path = get_library_path(&version);
let library = SSVLibrary::<V1_40_14>::new(&lib_path)?; let library = SSVLibrary::<V1_40_14>::new(&lib_path)?;
SsvLibraryVersion::V1_40_14(library) SsvLibraryVersion::V1_40_14(library)
@ -55,17 +42,15 @@ impl SSV {
/// Implement: SSV_InitLIB2 /// Implement: SSV_InitLIB2
pub fn init_library(&self, sesam_ini_path: &str) -> Result<(), Error> { pub fn init_library(&self, sesam_ini_path: &str) -> Result<(), Error> {
let sesam_ini_path = std::ffi::CString::new(sesam_ini_path).expect("CString::new failed"); let sesam_ini_path = std::ffi::CString::new(sesam_ini_path).expect("CString::new failed");
let result = match &self.library { match &self.library {
SsvLibraryVersion::V1_40_13(library) => { SsvLibraryVersion::V1_40_13(library) => {
unsafe { library.ssv_init_lib2(sesam_ini_path.as_ptr()) }? let result = unsafe { library.ssv_init_lib2(sesam_ini_path.as_ptr()) }?;
println!("SSV_InitLIB2 result: {}", result);
}, },
SsvLibraryVersion::V1_40_14(library) => { SsvLibraryVersion::V1_40_14(library) => {
unsafe { library.ssv_init_lib2(sesam_ini_path.as_ptr()) }? let result = unsafe { library.ssv_init_lib2(sesam_ini_path.as_ptr()) }?;
println!("SSV_InitLIB2 result: {}", result);
}, },
};
if result != 0 {
let error = SSVErrorCodes::from(result);
return Err(Error::SSVError(error));
} }
Ok(()) Ok(())
} }
@ -76,21 +61,19 @@ mod tests {
use std::env; use std::env;
use utils::config::load_config; use utils::config::load_config;
use anyhow::Result;
use super::*; use super::*;
fn init() -> Result<SSV> { fn init() -> SSV {
load_config().unwrap(); load_config().unwrap();
Ok(SSV::new(SupportedFsvVersion::V1_40_13)?) SSV::new(SUPPORTED_FSV_VERSIONS::V1_40_13).expect("SSV::new failed")
} }
#[test] #[test]
fn test_init_library() -> Result<()> { fn test_init_library() {
let lib = init()?; let lib = init();
let sesam_ini_path = env::var("SESAM_INI_PATH").expect("SESAM_INI_PATH must be set"); let sesam_ini_path = env::var("SESAM_INI_PATH").expect("SESAM_INI_PATH must be set");
lib.init_library(&sesam_ini_path)?; lib.init_library(&sesam_ini_path).expect("init_library failed");
Ok(())
} }
#[test] #[test]

View File

@ -1,82 +0,0 @@
use num_enum::FromPrimitive;
use thiserror::Error;
#[derive(Error, Debug, Eq, PartialEq, FromPrimitive)]
#[repr(u16)]
pub enum SSVErrorCodes {
#[error("Le fichier `tablebin.smc` est inaccessible en lecture (inexistant ou pas de droits d'accès).")]
FileMissingTablebinMsc = 0xF610, // tablebin.smc
#[error("Le fichier `scripts.sms` est inaccessible en lecture (inexistant ou pas de droits d'accès).")]
FileMissingScriptsSms = 0xF611, // scripts.sms
#[error("Le fichier `tablebin.ssv` est inaccessible en lecture (inexistant ou pas de droits d'accès).")]
FileMissingTablebinSsv = 0xF612, // tablebin.ssv
#[error("Le fichier `script.ssv` est inaccessible en lecture (inexistant ou pas de droits d'accès).")]
FileMissingScriptSsv = 0xF613, // script.ssv
#[error("La version du fichier `tablebin.smc` est incompatible avec la bibliothèque des SSV.")]
FileVersionIncompatibleTablebinMsc = 0xF620, // tablebin.smc
#[error("La version du fichier `scripts.sms` est incompatible avec la bibliothèque des SSV.")]
FileVersionIncompatibleScriptsSms = 0xF621, // scripts.sms
#[error("La version du fichier `tablebin.ssv` est incompatible avec la bibliothèque des SSV.")]
FileVersionIncompatibleTablebinSsv = 0xF622, // tablebin.ssv
#[error("La version du fichier `script.ssv` est incompatible avec la bibliothèque des SSV.")]
FileVersionIncompatibleScriptSsv = 0xF623, // script.ssv
#[error("L'intégrité du fichier `tablebin.smc` est incorrecte.")]
FileIntegrityIncorrectTablebinMsc = 0xF630, // tablebin.smc
#[error("L'intégrité du fichier `scripts.sms` est incorrecte.")]
FileIntegrityIncorrectScriptsSms = 0xF631, // scripts.sms
#[error("L'intégrité du fichier `tablebin.ssv` est incorrecte.")]
FileIntegrityIncorrectTablebinSsv = 0xF632, // tablebin.ssv
#[error("L'intégrité du fichier `script.ssv` est incorrecte.")]
FileIntegrityIncorrectScriptSsv = 0xF633, // script.ssv
#[error("La structure interne du fichier `tablebin.smc` est invalide.")]
FileStructureInvalidTablebinMsc = 0xF640, // tablebin.smc
#[error("La structure interne du fichier `scripts.sms` est invalide.")]
FileStructureInvalidScriptsSms = 0xF641, // scripts.sms
#[error("La structure interne du fichier `tablebin.ssv` est invalide.")]
FileStructureInvalidTablebinSsv = 0xF642, // tablebin.ssv
#[error("La structure interne du fichier `script.ssv` est invalide.")]
FileStructureInvalidScriptSsv = 0xF643, // script.ssv
#[error("Le fichier `tablebin.smc` n'a pas pu être chargé en mémoire. Essayez de libérer de la mémoire.")]
FileLoadFailedTablebinMsc = 0xF650, // tablebin.smc
#[error("Le fichier `scripts.sms` n'a pas pu être chargé en mémoire. Essayez de libérer de la mémoire.")]
FileLoadFailedScriptsSms = 0xF651, // scripts.sms
#[error("Le fichier `tablebin.ssv` n'a pas pu être chargé en mémoire. Essayez de libérer de la mémoire.")]
FileLoadFailedTablebinSsv = 0xF652, // tablebin.ssv
#[error("Le fichier `script.ssv` n'a pas pu être chargé en mémoire. Essayez de libérer de la mémoire.")]
FileLoadFailedScriptSsv = 0xF653, // script.ssv
#[error("Le nom du fichier `tablebin.smc` est invalide.")]
FileNameInvalidTablebinMsc = 0xF660, // tablebin.smc
#[error("Le nom du fichier `scripts.sms` est invalide.")]
FileNameInvalidScriptsSms = 0xF661, // scripts.sms
#[error("Le nom du fichier `tablebin.ssv` est invalide.")]
FileNameInvalidTablebinSsv = 0xF662, // tablebin.ssv
#[error("Le nom du fichier `script.ssv` est invalide.")]
FileNameInvalidScriptSsv = 0xF663, // script.ssv
#[error("La fonction Initialiser Librairie est déjà appelée.")]
FunctionInitLib2AlreadyCalled = 0xF670, // Warning
#[error("Le fichier SESAM.INI est inaccessible en lecture (fichier ou droit daccès manquant) ou ne contient pas le chemin des tables binaires des SSV.")]
SesamIniMissingFileOrTablebinPath = 0xF680,
#[error("Le chemin du répertoire de travail est absent du fichier SESAM.INI.")]
SesamIniMissingWorkDir = 0xF6F1,
#[error("Les fichiers dextension adm ne sont pas accessibles en écriture.")]
AdmFilesNotWritable = 0xF6F2, // Warning
#[error("Aucune version de FSV du socle technique trouvé. Vérifier que la version du fichier script.sms est bonne.")]
NoFsvVersionFound = 0xF6F4,
#[error("Librairie SGD absente ou incomplète.")]
LibraryMissingOrIncompleteSGD = 0xF6F5,
#[error("Librairie SMC absente ou incomplète.")]
LibraryMissingOrIncompleteSMC = 0xF6F6,
#[error("Librairie SJS absente ou incomplète.")]
LibraryMissingOrIncompleteSJS = 0xF6F7,
#[error("Librairie SMS absente ou incomplète.")]
LibraryMissingOrIncompleteSMS = 0xF6F8,
#[error("Section MGC absente / clé RepertoireConfigTrace absente / fichier log4crc.xml non trouvé à lemplacement indiqué par la clé RepertoireConfigTrace du fichier SESAM.INI.")]
SesamIniTracingConfigMissing = 0xFF22, // Warning
#[error("Interface Full PC/SC : problème de chargement de la librairie cryptographique ou erreur retournée par la librairie cryptographique.")]
PCSCInterfaceCryptoLibraryError = 0xFF25,
#[error("Valorisation incorrecte des paramètres de gestion de l'accès aux ressources dans le SESAM.INI. Vérifier les valeurs des clés tempoexclusivite, repetitionexclusivite, tempoexclusivitePCSC, repetitionexclusivitePCSC")]
SesamIniResourceAccessParamsIncorrect = 0xFF2A,
#[num_enum(catch_all)]
#[error("Erreur inattendue de la librairie SSV (code d'erreur: {0}).")]
Unexpected(u16),
}