Compare commits
3 Commits
45124db739
...
332fb01253
Author | SHA1 | Date | |
---|---|---|---|
332fb01253 | |||
bf5e7f201f | |||
3e1dc326f4 |
@ -1527,7 +1527,10 @@ dependencies = [
|
|||||||
name = "fsv"
|
name = "fsv"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"fsv-sys",
|
"fsv-sys",
|
||||||
|
"libc",
|
||||||
|
"num_enum",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"utils",
|
"utils",
|
||||||
]
|
]
|
||||||
|
@ -4,6 +4,9 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
anyhow = "1.0.89"
|
||||||
|
libc = "0.2.159"
|
||||||
|
num_enum = { version = "0.7.3", features = ["complex-expressions"] }
|
||||||
thiserror = "1.0.64"
|
thiserror = "1.0.64"
|
||||||
|
|
||||||
fsv-sys = { path = "../fsv-sys" }
|
fsv-sys = { path = "../fsv-sys" }
|
||||||
|
@ -1,83 +0,0 @@
|
|||||||
use thiserror::Error;
|
|
||||||
|
|
||||||
use fsv_sys::{get_library_path, Error as FsvError, SSVLibrary, SSVLibrary_Common, SUPPORTED_FSV_VERSIONS, V1_40_13, V1_40_14};
|
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
|
||||||
pub enum Error {
|
|
||||||
#[error(transparent)]
|
|
||||||
SysLibrary(#[from] FsvError)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Enum to hold the different versions of the SSV library
|
|
||||||
enum SsvLibraryVersion {
|
|
||||||
V1_40_13(SSVLibrary<V1_40_13>),
|
|
||||||
V1_40_14(SSVLibrary<V1_40_14>),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Struct to hold the SSV library and access its functions
|
|
||||||
pub struct SSV {
|
|
||||||
library: SsvLibraryVersion,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SSV {
|
|
||||||
fn new(version: SUPPORTED_FSV_VERSIONS) -> Result<Self, Error> {
|
|
||||||
let library = match version {
|
|
||||||
SUPPORTED_FSV_VERSIONS::V1_40_13 => {
|
|
||||||
let lib_path = get_library_path(&version);
|
|
||||||
let library = SSVLibrary::<V1_40_13>::new(&lib_path)?;
|
|
||||||
SsvLibraryVersion::V1_40_13(library)
|
|
||||||
},
|
|
||||||
SUPPORTED_FSV_VERSIONS::V1_40_14 => {
|
|
||||||
let lib_path = get_library_path(&version);
|
|
||||||
let library = SSVLibrary::<V1_40_14>::new(&lib_path)?;
|
|
||||||
SsvLibraryVersion::V1_40_14(library)
|
|
||||||
},
|
|
||||||
};
|
|
||||||
Ok(Self {
|
|
||||||
library,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// # Initialize the SSV library
|
|
||||||
/// Implement: SSV_InitLIB2
|
|
||||||
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");
|
|
||||||
match &self.library {
|
|
||||||
SsvLibraryVersion::V1_40_13(library) => {
|
|
||||||
let result = unsafe { library.ssv_init_lib2(sesam_ini_path.as_ptr()) }?;
|
|
||||||
println!("SSV_InitLIB2 result: {}", result);
|
|
||||||
},
|
|
||||||
SsvLibraryVersion::V1_40_14(library) => {
|
|
||||||
let result = unsafe { library.ssv_init_lib2(sesam_ini_path.as_ptr()) }?;
|
|
||||||
println!("SSV_InitLIB2 result: {}", result);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use std::env;
|
|
||||||
|
|
||||||
use utils::config::load_config;
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
fn init() -> SSV {
|
|
||||||
load_config().unwrap();
|
|
||||||
SSV::new(SUPPORTED_FSV_VERSIONS::V1_40_13).expect("SSV::new failed")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_init_library() {
|
|
||||||
let lib = init();
|
|
||||||
let sesam_ini_path = env::var("SESAM_INI_PATH").expect("SESAM_INI_PATH must be set");
|
|
||||||
lib.init_library(&sesam_ini_path).expect("init_library failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_ssv() {
|
|
||||||
assert_eq!("ssv", "ssv");
|
|
||||||
}
|
|
||||||
}
|
|
181
crates/fsv/src/ssv/errors_ssv.rs
Normal file
181
crates/fsv/src/ssv/errors_ssv.rs
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
use num_enum::FromPrimitive;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Error, Debug, Eq, PartialEq, FromPrimitive)]
|
||||||
|
#[repr(u16)]
|
||||||
|
pub enum SSVErrorCodes {
|
||||||
|
#[error("La Carte du Professionnel de Santé est absente du lecteur.")]
|
||||||
|
CPSMissing = 0xF001,
|
||||||
|
#[error("La Carte du Professionnel de Santé bloquée après trois codes porteur erronés.")]
|
||||||
|
CPSBlocked = 0xF002,
|
||||||
|
#[error("Le code porteur présenté est erroné.")]
|
||||||
|
CPSPinWrong = 0xF003,
|
||||||
|
#[error("Carte du Professionnel de Santé non valide ou inexploitable par le Logiciel Lecteur. Vérifier la présence d'un Domaine d'Assurance Maladie (DAM).")]
|
||||||
|
CPSInvalid = 0xF004,
|
||||||
|
#[error("La Carte du Professionnel de Santé est retirée du lecteur.")]
|
||||||
|
CPSRemoved = 0xF005,
|
||||||
|
/// - Sécurisation d'une série de lots en cours.
|
||||||
|
/// - Pour les fonctions TLA (sauf Identifier TLA) : Cette erreur survient lorsque le simulateur TLA est en mode 1.50.
|
||||||
|
/// - Lire Date Lecteur, Mettre à jour Date Lecteur, Lire Droits Vitale : Cette erreur peut survenir lorsque le Logiciel Lecteur ne connaît pas la fonction sollicitée, c'est-à-dire si la version du Logiciel Lecteur est antérieure à 2.00.
|
||||||
|
/// - Décharger Données Bénéficiaires : cette erreur peut survenir pour signaler que le
|
||||||
|
#[error("F022: Erreur commune à plusieurs fonctions.")]
|
||||||
|
F022 = 0xF022,
|
||||||
|
#[error("Message du lecteur incohérent. Débrancher et rebrancher le lecteur.")]
|
||||||
|
PCSCInconsistentMessage = 0xF0FF,
|
||||||
|
#[error("Le nom de lecteur fourni ne correspond à aucun lecteur reconnu.")]
|
||||||
|
PCSCReaderNotFound = 0xF101,
|
||||||
|
#[error("La fonction InitLIB2 n'est pas encore appelée ou la fonction TermLIB a déjà été appelée.")]
|
||||||
|
FunctionInitLib2NotCalled = 0xF600,
|
||||||
|
#[error("La bibliothèque SSV n’est pas chargée en mémoire. Vérifier que la fonction InitLIB2 a bien été appelée.")]
|
||||||
|
LibraryNotLoaded = 0xF690, // Warning
|
||||||
|
#[error("Carte vitale en opposition.")]
|
||||||
|
VitaleOpposition = 0xF6A1,
|
||||||
|
#[error("Zone de mémoire non allouée en sortie.")]
|
||||||
|
MemoryNotAllocated = 0xF800,
|
||||||
|
#[error("Erreur d'allocation de la zone de mémoire en sortie.")]
|
||||||
|
MemoryAllocationError = 0xF801,
|
||||||
|
#[error("Un des paramètres obligatoires d'entrée est non alloué ou invalide.")]
|
||||||
|
InputParameterNotAllocatedOrInvalid = 0xF802,
|
||||||
|
#[error("Zone de mémoire spécifiée en entrée non valide. Vérifier que la zone allouée ne dépasse pas la taille maximale autorisée (MAXBLOC).")]
|
||||||
|
InputMemoryInvalid = 0xF803,
|
||||||
|
#[error("Le format de la zone de mémoire d'entrée ou le nombre de zones mémoire est incorrect.")]
|
||||||
|
InputMemoryFormatIncorrect = 0xF810,
|
||||||
|
#[error("Problème lors de l’initialisation du protocole. Erreur du Ressource Manager PC/SC. Vérifiez le lecteur.")]
|
||||||
|
PCSCProtocolInitError = 0xFF01,
|
||||||
|
#[error("Time-out au niveau protocolaire ou transmission déjà en cours avec le lecteur. Vérifiez le lecteur et l'insertion de la carte.")]
|
||||||
|
PCSCProtocolTimeout = 0xFF02,
|
||||||
|
#[error("Taille insuffisante allouée en entrée d’une fonction du Resource Manager.")]
|
||||||
|
PCSCProtocolInputMemoryTooSmall = 0xFF03,
|
||||||
|
#[error("Erreur de transmission du protocole. Vérifiez le lecteur et l'insertion de la carte.")]
|
||||||
|
PCSCProtocolTransmissionError = 0xFF04,
|
||||||
|
#[error("Lecteur absent ou indisponible.")]
|
||||||
|
PCSCReaderMissingOrUnavailable = 0xFF05,
|
||||||
|
#[error("Le nom du lecteur transmis est inconnu du Resource Manager PC/SC.")]
|
||||||
|
PCSCReaderUnknown = 0xFF06,
|
||||||
|
#[error("Erreur inconnue remontée par le Resource Manager PC/SC.")]
|
||||||
|
PCSCUnknownError = 0xFF07,
|
||||||
|
#[error("Erreur interne Resource Manager PC/SC.")]
|
||||||
|
PCSCInternalError = 0xFF08,
|
||||||
|
#[error("Ressource PC/SC déjà prise en exclusivité. Vérifiez qu'une autre application n'utilise pas le lecteur.")]
|
||||||
|
PCSCResourceAlreadyExclusive = 0xFF09,
|
||||||
|
#[error("Protocole incompatible avec la carte à puce. Vérifiez l'insertion de la carte et son état.")]
|
||||||
|
PCSCProtocolIncompatible = 0xFF0A,
|
||||||
|
#[error("Paramètre incorrect. Erreur interne à la librairie SSV.")]
|
||||||
|
PCSCIncorrectParameter = 0xFF0B,
|
||||||
|
#[error("Carte absente. Insérez une carte dans le lecteur.")]
|
||||||
|
PCSCCardMissing = 0xFF0C,
|
||||||
|
#[error("L'état de la carte a été modifié (RAZ ou mise hors tension). Vérifiez si la carte n'a pas été retirée ou si une autre application n'utilise pas la carte.")]
|
||||||
|
PCSCCardStateChanged = 0xFF0D,
|
||||||
|
#[error("Carte muette ou non supportée. Vérifiez l'insertion de la carte.")]
|
||||||
|
PCSCCardUnsupported = 0xFF0E,
|
||||||
|
#[error("Code porteur CPS non renseigné.")]
|
||||||
|
CPSPinMissing = 0xFF21,
|
||||||
|
#[error("Ressource PC/SC déjà prise en exclusivité. Vérifiez que le processus en cours n'utilise pas déjà le lecteur.")]
|
||||||
|
PCSCReaderAlreadyExclusiveForCurrentProcess = 0xFF24,
|
||||||
|
#[error("Plusieurs lecteurs ou cartes de même type identifiés lors de la détection automatique.")]
|
||||||
|
PCSCDuplicatedReadersOrCardsDetected = 0xFF29,
|
||||||
|
#[error("Problème de chargement de la librairie cryptographique ou erreur retournée par la librairie cryptographique.")]
|
||||||
|
CryptoLibraryError = 0xFF30,
|
||||||
|
#[error("Erreurs internes aux Services SESAM-Vitale. Vérifiez les traces.")]
|
||||||
|
#[num_enum(alternatives = [0xFFF1..=0xFFFF])]
|
||||||
|
SSVInternalError = 0xFFF0,
|
||||||
|
#[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 d’accè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 d’extension 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é à l’emplacement 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),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_code_ranges() {
|
||||||
|
let error_code = 0xFFF1;
|
||||||
|
let error = SSVErrorCodes::from(error_code);
|
||||||
|
assert_eq!(error, SSVErrorCodes::SSVInternalError);
|
||||||
|
|
||||||
|
let error_code = 0xFFF8;
|
||||||
|
let error = SSVErrorCodes::from(error_code);
|
||||||
|
assert_eq!(error, SSVErrorCodes::SSVInternalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_catch_all() {
|
||||||
|
let error_code = 0xFBFF; // Not a valid error code
|
||||||
|
let error = SSVErrorCodes::from(error_code);
|
||||||
|
assert_eq!(error, SSVErrorCodes::Unexpected(0xFBFF));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
208
crates/fsv/src/ssv/mod.rs
Normal file
208
crates/fsv/src/ssv/mod.rs
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
use std::{ffi::CString, ptr};
|
||||||
|
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
use fsv_sys::{
|
||||||
|
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)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error(transparent)]
|
||||||
|
FSVSysLibrary(#[from] FsvError),
|
||||||
|
#[error(transparent)]
|
||||||
|
SSVError(#[from] SSVErrorCodes),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enum to hold the different versions of the SSV library
|
||||||
|
enum SsvLibraryVersion {
|
||||||
|
V1_40_13(SSVLibrary<V1_40_13>),
|
||||||
|
V1_40_14(SSVLibrary<V1_40_14>),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Struct to hold the SSV library and access its functions
|
||||||
|
pub struct SSV {
|
||||||
|
library: SsvLibraryVersion,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SSV {
|
||||||
|
fn new(version: SupportedFsvVersion) -> Result<Self, Error> {
|
||||||
|
let library = match version {
|
||||||
|
SupportedFsvVersion::V1_40_13 => {
|
||||||
|
let lib_path = get_library_path(&version);
|
||||||
|
let library = SSVLibrary::<V1_40_13>::new(&lib_path)?;
|
||||||
|
SsvLibraryVersion::V1_40_13(library)
|
||||||
|
},
|
||||||
|
SupportedFsvVersion::V1_40_14 => {
|
||||||
|
let lib_path = get_library_path(&version);
|
||||||
|
let library = SSVLibrary::<V1_40_14>::new(&lib_path)?;
|
||||||
|
SsvLibraryVersion::V1_40_14(library)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
Ok(Self {
|
||||||
|
library,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// # Initialize the SSV library
|
||||||
|
/// Implement: SSV_InitLIB2
|
||||||
|
pub fn init_library(&self, sesam_ini_path: &str) -> Result<(), Error> {
|
||||||
|
let sesam_ini_path = CString::new(sesam_ini_path).expect("CString::new failed");
|
||||||
|
let result = match &self.library {
|
||||||
|
SsvLibraryVersion::V1_40_13(library) => {
|
||||||
|
unsafe { library.ssv_init_lib2(sesam_ini_path.as_ptr()) }?
|
||||||
|
},
|
||||||
|
SsvLibraryVersion::V1_40_14(library) => {
|
||||||
|
unsafe { library.ssv_init_lib2(sesam_ini_path.as_ptr()) }?
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if result != 0 {
|
||||||
|
let error = SSVErrorCodes::from(result);
|
||||||
|
return Err(Error::SSVError(error));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// # Read the CPS card
|
||||||
|
/// Implement: SSV_LireCartePS
|
||||||
|
pub fn read_professional_card(&self, pin_code: &str) -> Result<(), Error> {
|
||||||
|
let pcsc_reader_name = "Gemalto PC Twin Reader (645D94C3) 00 00";
|
||||||
|
|
||||||
|
let pin_code = CString::new(pin_code).expect("CString::new failed");
|
||||||
|
let pcsc_reader_name = CString::new(pcsc_reader_name).expect("CString::new failed");
|
||||||
|
let mut out_buffer_ptr: *mut libc::c_void = ptr::null_mut();
|
||||||
|
let mut out_buffer_size: libc::size_t = 0;
|
||||||
|
|
||||||
|
let result = match &self.library {
|
||||||
|
SsvLibraryVersion::V1_40_13(library) => {
|
||||||
|
unsafe { library.ssv_lire_carte_ps(
|
||||||
|
pcsc_reader_name.as_ptr(),
|
||||||
|
pcsc_reader_name.as_ptr(),
|
||||||
|
pin_code.as_ptr(),
|
||||||
|
&mut out_buffer_ptr,
|
||||||
|
&mut out_buffer_size)
|
||||||
|
}?
|
||||||
|
},
|
||||||
|
SsvLibraryVersion::V1_40_14(library) => {
|
||||||
|
unsafe { library.ssv_lire_carte_ps(
|
||||||
|
pcsc_reader_name.as_ptr(),
|
||||||
|
pcsc_reader_name.as_ptr(),
|
||||||
|
pin_code.as_ptr(),
|
||||||
|
&mut out_buffer_ptr,
|
||||||
|
&mut out_buffer_size)
|
||||||
|
}?
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if result != 0 {
|
||||||
|
// Free memory
|
||||||
|
unsafe { libc::free(out_buffer_ptr) };
|
||||||
|
let error = SSVErrorCodes::from(result);
|
||||||
|
return Err(Error::SSVError(error));
|
||||||
|
}
|
||||||
|
// Print 10 bytes of the buffer
|
||||||
|
let buffer = unsafe { std::slice::from_raw_parts(out_buffer_ptr as *const u8, 10) };
|
||||||
|
println!("{:?}", buffer);
|
||||||
|
// Free memory
|
||||||
|
unsafe { libc::free(out_buffer_ptr) };
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// # Get the configuration of the SSV library
|
||||||
|
/// Implement: SSV_LireConfig
|
||||||
|
pub fn get_config(&self) -> Result<(), Error> {
|
||||||
|
let mut buffer_ptr: *mut libc::c_void = ptr::null_mut();
|
||||||
|
let mut size: libc::size_t = 0;
|
||||||
|
|
||||||
|
let result = match &self.library {
|
||||||
|
SsvLibraryVersion::V1_40_13(library) => {
|
||||||
|
unsafe { library.ssv_lire_config(&mut buffer_ptr, &mut size) }?
|
||||||
|
},
|
||||||
|
SsvLibraryVersion::V1_40_14(library) => {
|
||||||
|
unsafe { library.ssv_lire_config(&mut buffer_ptr, &mut size) }?
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if result != 0 {
|
||||||
|
// Free memory
|
||||||
|
unsafe { libc::free(buffer_ptr) };
|
||||||
|
let error = SSVErrorCodes::from(result);
|
||||||
|
return Err(Error::SSVError(error));
|
||||||
|
}
|
||||||
|
// Print 10 bytes of the buffer
|
||||||
|
let buffer = unsafe { std::slice::from_raw_parts(buffer_ptr as *const u8, 10) };
|
||||||
|
println!("{:?}", buffer);
|
||||||
|
// Free memory
|
||||||
|
unsafe { libc::free(buffer_ptr) };
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
use utils::config::load_config;
|
||||||
|
use anyhow::Result;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
mod setup {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub fn init() -> Result<SSV> {
|
||||||
|
load_config().unwrap();
|
||||||
|
let sesam_ini_path = env::var("SESAM_INI_PATH").expect("SESAM_INI_PATH must be set");
|
||||||
|
let lib = SSV::new(SupportedFsvVersion::V1_40_13)?;
|
||||||
|
lib.init_library(&sesam_ini_path)?;
|
||||||
|
Ok(lib)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_init_library() -> Result<()> {
|
||||||
|
setup::init()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_read_professional_card_good_pin() -> Result<()> {
|
||||||
|
let lib = setup::init()?;
|
||||||
|
let pin_code = "1234";
|
||||||
|
lib.read_professional_card(pin_code)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ignore]
|
||||||
|
#[test]
|
||||||
|
fn test_read_professional_card_bad_pin() -> Result<()> {
|
||||||
|
let lib = setup::init()?;
|
||||||
|
let pin_code = "0000";
|
||||||
|
// Should return an error
|
||||||
|
let err = lib.read_professional_card(pin_code).unwrap_err();
|
||||||
|
assert_eq!(err.to_string(), "Le code porteur présenté est erroné.");
|
||||||
|
match err {
|
||||||
|
Error::SSVError(err) => {
|
||||||
|
assert_eq!(err as SSVErrorCodes, SSVErrorCodes::CPSPinWrong);
|
||||||
|
},
|
||||||
|
_ => panic!("Error type is not SSVError"),
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_config() -> Result<()> {
|
||||||
|
let lib = setup::init()?;
|
||||||
|
lib.get_config()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user