8 Commits

69 changed files with 318 additions and 5070 deletions

View File

@ -1,27 +0,0 @@
name: Demande de fusion (Pull Request)
body:
- type: markdown
attributes:
value: |
Une demande de fusion (Pull Request) a pour objectif de
partager au reste de l'équipe un développement réalisé.
Décrire les modifications apportées, leur impact et le contexte
dans lequel elles ont été réalisées permettra aux relecteurices
de plus facilement comprendre et valider votre travail.
- type: textarea
id: details
attributes:
label: Détails
description: Décrivez le contenu de la PR, son impact concret
validations:
required: true
- type: textarea
id: why
attributes:
label: Pourquoi ?
description: Pourquoi ces modifications sont elles nécessaires ? Dans quel contexte s'inscrivent-elles ?
- type: textarea
id: documentation
attributes:
label: Documentation
description: Précisez ici des références à des ressources que vous avez utilisées pour réaliser ces modifications

View File

@ -1,29 +0,0 @@
name: Rapport de bug
about: Remplissez un rapport d'erreur
title: "[Bug]: "
blank_issues_enabled: false
labels:
- bug
- to-triage
body:
- type: textarea
id: what-happened
attributes:
label: Que se passe-t-il ?
description: Décrivez la situation que vous rencontrez
validations:
required: true
- type: textarea
id: environment-description
attributes:
label: Si le problème semble lié à votre environement, décrivez-le ici
placeholder: Windows 10, Firefox 89.0, etc.
- type: dropdown
id: module
attributes:
label: Ce problème est il relatif à un ou des modules en particulier ?
multiple: true
options:
- Clego
- Tauri
- Axum

View File

@ -1,13 +0,0 @@
name: Proposez une fonctionnalité / amélioration
about: Proposez vos idées de fonctionnalités ou d'améliorations
blank_issues_enabled: false
labels:
- feature
- to-triage
body:
- type: textarea
id: description
attributes:
label: Décrivez votre idée
validations:
required: true

View File

@ -1,20 +0,0 @@
name: Posez une question
about: Une interrogation, une difficulté ? Posez votre question
blank_issues_enabled: false
labels:
- question
- to-triage
body:
- type: textarea
id: question
attributes:
label: Que se passe-t-il ?
description: Décrivez la situation que vous rencontrez, posez votre question
validations:
required: true
- type: textarea
id: environment-description
attributes:
label: Précisez votre environnement
description: S'il vous semble pertinent de préciser votre environement, décrivez-le ici
placeholder: Windows 10, Firefox 89.0, etc.

27
.gitignore vendored
View File

@ -1,23 +1,6 @@
# ---> Rust # Ignore Rust target directory
# Generated by Cargo /target
# will have compiled files and executables
debug/
target/
# These are backup files generated by rustfmt
**/*.rs.bk
# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# Ignore .env files
.env
.env.build

4513
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,12 @@
[workspace] [package]
resolver = "2" name = "utils-debug-c-lib"
members = [ version = "0.1.0"
"crates/app", edition = "2021"
"crates/sesam-vitale", build = "build.rs"
"crates/desktop"
] [dependencies]
dotenv = "0.15"
libc = "0.2"
[build-dependencies]
dotenv = "0.15"

View File

@ -1,39 +1,46 @@
# Krys4lide ## Requirements
Logiciel de Pharmacie libre et open-source. - 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é)
## Crates - 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 : `...`
- `app`: Interface du logiciel, servie par un serveur web propulsé par Axum. Utilisable en mode endpoint ou encapsulé dans le client `desktop` ## Setup
- `desktop`: Client desktop propulsé par Tauri, encapsulant le serveur web `app`
- `sesam-vitale`: Bibliothèque de gestion des services SESAM-Vitale (Lecture des cartes CPS et Vitale, téléservices ...)
## Development - 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
### Pré-requis - 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
La CLI Tauri est nécessaire au lancement du client `desktop`. Elle peut être installée via Cargo :
```bash
cargo install tauri-cli
```
### Exécution de l'application cliente desktop
```bash
cargo tauri dev
```
### Exécution du serveur web `app` en mode endpoint
```bash
cargo run --bin app
```
## Build ## Build
Packager le client desktop ### Compilation C
```bash Ce package s'appuie sur deux librairies :
cargo tauri build - Une librairie statique, compilée à partir des sources (`*.c`, `*.h`) fournies dans le dossier `./src`
``` - Une librairie dynamique, fournie par le package FSV
- Windows : on fournit les headers, non présents dans la `.dll` en compilant les fichiers `src/*.def` en leur version binaire `lib/*.lib`
Pour compiler les fichiers de librairie :
- Windows : `.\make.bat`
- Linux : `make`
Pour nettoyer le dossier `./lib` :
- Windows : `.\make.bat /clean`
- Linux : `make clean`
### Compilation Rust
`cargo build`
## Run
`cargo run`

View File

@ -4,33 +4,23 @@ use std::env;
use std::path::PathBuf; use std::path::PathBuf;
fn main() { fn main() {
// Load the .env.build file for build-time environment variables dotenv::from_filename(".env.build").ok();
let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let manifest_path = PathBuf::from(manifest_dir);
dotenv::from_path(manifest_path.join(".env.build")).ok();
println!("cargo::rerun-if-env-changed=SESAM_FSV_LIB_PATH");
println!("cargo::rerun-if-env-changed=SESAM_FSV_SSVLIB");
println!("cargo::rerun-if-changed=.env.build"); println!("cargo::rerun-if-changed=.env.build");
println!("cargo::rerun-if-changed=build.rs");
// Add local lib directory to the linker search path (for def files and static libs) let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let static_lib_path = manifest_path.join("lib");
let static_lib_path = PathBuf::from(manifest_dir).join("lib");
println!("cargo::rustc-link-search=native={}", static_lib_path.display()); println!("cargo::rustc-link-search=native={}", static_lib_path.display());
println!("cargo::rustc-link-lib=static=p4pillondebuglib");
// Add the SESAM_FSV_LIB_PATH to the linker search path
let fsv_lib_path = PathBuf::from(env::var("SESAM_FSV_LIB_PATH").unwrap()); let fsv_lib_path = PathBuf::from(env::var("SESAM_FSV_LIB_PATH").unwrap());
println!("cargo::rustc-link-search=native={}", fsv_lib_path.display()); println!("cargo::rustc-link-search=native={}", fsv_lib_path.display());
println!("cargo::rustc-link-lib=dylib={}", env::var("SESAM_FSV_SSVLIB").unwrap());
// Add the SESAM_FSV_LIB_PATH to the PATH environment variable
if cfg!(target_os = "windows") { if cfg!(target_os = "windows") {
let path = env::var("PATH").unwrap_or(String::new()); let path = env::var("PATH").unwrap_or(String::new());
println!("cargo:rustc-env=PATH={};{}", fsv_lib_path.display(), path); println!("cargo:rustc-env=PATH={};{}", fsv_lib_path.display(), path);
} else if cfg!(target_os = "linux") { } else if cfg!(target_os = "linux") {
println!("cargo:rustc-env=LD_LIBRARY_PATH={}", fsv_lib_path.display()); 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());
// TODO : try `raw-dylib` instead of `dylib` on Windows to avoid the need of the `lib` headers compiled from the `def`
} }

View File

@ -1 +0,0 @@
/target

View File

@ -1,12 +0,0 @@
[package]
name = "app"
version = "0.1.0"
edition = "2021"
[dependencies]
askama = "0.12.1"
askama_axum = "0.4.0"
axum = "0.7.5"
tokio = { version = "1.39.1", features = ["macros", "rt-multi-thread"] }
tower-http = { version = "0.5.2", features = ["fs"] }

File diff suppressed because one or more lines are too long

View File

@ -1,27 +0,0 @@
mod templates;
use std::path::Path;
use askama_axum::IntoResponse;
use templates::{hello::HelloResponse, index::GetIndexResponse};
use tower_http::services::ServeDir;
async fn root() -> impl IntoResponse {
return GetIndexResponse {}.into_response();
}
async fn hello() -> impl IntoResponse {
return HelloResponse {
name: "Theo".to_string(),
}
.into_response();
}
pub fn get_router(assets_path: &Path) -> axum::Router {
let router = axum::Router::new()
.nest_service("/assets", ServeDir::new(assets_path))
.route("/", axum::routing::get(root))
.route("/hello", axum::routing::get(hello));
router
}

View File

@ -1,14 +0,0 @@
use ::app::get_router;
use std::env;
use std::path::Path;
#[tokio::main]
async fn main() {
let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let assets_path = Path::new(&manifest_dir).join("assets");
let router = get_router(assets_path.as_path());
// TODO: select port based on available port (or ask in CLI)
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, router).await.unwrap();
}

View File

@ -1,7 +0,0 @@
use askama::Template;
#[derive(Template)]
#[template(path = "hello.html")]
pub struct HelloResponse {
pub name: String,
}

View File

@ -1,5 +0,0 @@
use askama::Template;
#[derive(Template)]
#[template(path = "index.html")]
pub struct GetIndexResponse;

View File

@ -1,2 +0,0 @@
pub mod hello;
pub mod index;

View File

@ -1,13 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<title>{% block title %}{{ title }}{% endblock %}</title>
<script src="/assets/js/htmx.min.js"></script>
{% block head %}{% endblock %}
</head>
<body>
{% block body %}{% endblock %}
</body>
</html>

View File

@ -1 +0,0 @@
<div>Hello {{name}}!</div>

View File

@ -1,23 +0,0 @@
{% extends "base.html" %}
{% block title %}Pharma Libre{% endblock %}
{% block body %}
<div>
<header>
<h1>Pharma Libre</h1>
</header>
<main>
<div
id="hello"
hx-get="/hello"
hx-target="this"
hx-trigger="load"
hx-swap="outerHTML"
>
Loading...
</div>
</main>
</div>
{% endblock %}

View File

@ -1,7 +0,0 @@
# Generated by Cargo
# will have compiled files and executables
/target/
# Generated by Tauri
# will have schema files for capabilities auto-completion
/gen/schemas

View File

@ -1,24 +0,0 @@
[package]
name = "desktop"
version = "0.1.0"
description = "Un logiciel de pharmacie libre et open-source."
authors = ["p4pillon"]
edition = "2021"
[lib]
name = "desktop_lib"
crate-type = ["lib", "cdylib", "staticlib"]
[build-dependencies]
tauri-build = { version = "2.0.0-beta", features = [] }
[dependencies]
axum = "0.7.5"
tauri = { version = "2.0.0-beta", features = [] }
tower = "0.4.13"
tokio = "1.39.1"
app = { path = "../app" }
http = "1.1.0"
bytes = "1.6.1"

View File

@ -1,3 +0,0 @@
fn main() {
tauri_build::build()
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 974 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 903 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@ -1,69 +0,0 @@
use bytes::Bytes;
use http::{request, response, Request, Response};
use std::path::PathBuf;
use std::sync::Arc;
use axum::body::{to_bytes, Body};
use axum::Router;
use tauri::path::BaseDirectory;
use tauri::Manager;
use tokio::sync::{Mutex, MutexGuard};
use tower::{Service, ServiceExt};
async fn process_tauri_request(
tauri_request: Request<Vec<u8>>,
mut router: MutexGuard<'_, Router>,
) -> Response<Vec<u8>> {
let (parts, body): (request::Parts, Vec<u8>) = tauri_request.into_parts();
let axum_request: Request<Body> = Request::from_parts(parts, body.into());
let axum_response: Response<Body> = router
.as_service()
.ready()
.await
.expect("Failed to get ready service from router")
.call(axum_request)
.await
.expect("Could not get response from router");
let (parts, body): (response::Parts, Body) = axum_response.into_parts();
let body: Bytes = to_bytes(body, usize::MAX).await.unwrap_or_default();
let tauri_response: Response<Vec<u8>> = Response::from_parts(parts, body.into());
tauri_response
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.setup(|app| {
let assets_path: PathBuf = app
.path()
.resolve("assets", BaseDirectory::Resource)
.expect("Path should be resolvable");
// Adds Axum router to application state
// This makes it so we can retrieve it from any app instance (see bellow)
let router = Arc::new(Mutex::new(app::get_router(&assets_path)));
app.manage(router);
Ok(())
})
.register_asynchronous_uri_scheme_protocol("axum", move |app, request, responder| {
// Retrieve the router from the application state and clone it for the async block
let router = Arc::clone(&app.state::<Arc<Mutex<axum::Router>>>());
// Spawn a new async task to process the request
tauri::async_runtime::spawn(async move {
let router = router.lock().await;
let response = process_tauri_request(request, router).await;
responder.respond(response);
});
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

View File

@ -1,6 +0,0 @@
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
desktop_lib::run()
}

View File

@ -1,41 +0,0 @@
{
"productName": "Logiciel Pharma",
"version": "0.0.1",
"identifier": "org.p4pillon.pharma.desktop",
"build": {
"beforeDevCommand": {
"cwd": "../app",
"script": "cargo run"
},
"devUrl": "http://localhost:3000",
"frontendDist": "axum://place.holder/"
},
"app": {
"withGlobalTauri": true,
"windows": [
{
"title": "Logiciel Pharma",
"width": 800,
"height": 600
}
],
"security": {
"csp": null
}
},
"bundle": {
"active": true,
"resources": {
"../app/assets/": "./assets/"
},
"targets": "all",
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
]
}
}

View File

@ -1,9 +0,0 @@
# Ignore Rust target directory
/target
# Ignore .env files
.env
.env.build
# Ignore exploitation files - only usefull for local debugging on windows
lib/*.exp

View File

@ -1,11 +0,0 @@
[package]
name = "sesam-vitale"
version = "0.1.0"
edition = "2021"
[dependencies]
dotenv = "0.15"
libc = "0.2"
[build-dependencies]
dotenv = "0.15"

View File

@ -1,34 +0,0 @@
## 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 headers qui ne sont pas présents dans la `.dll`. Il est donc nécessaire de fournir ces headers, en les renseignant dans des fichiers `crates/sesam-vitale/src/win/fsv/*.def` qui seront compilés en leur version binaire `crates/sesam-vitale/lib/*.lib`.
En cas de modification des fichiers `.def`, pour re-compiler ces headers, faire appel au script `scripts/compile_win_headers.bat`.
| /!\ Attention, le script `compile_win_headers.bat` exécute, en interne, l'utilitaire `vcvarsall.bat` et le linker `lib.exe` de Visual Studio. Visual Studio doit donc être installé et le chemin vers l'intallation le script `vcvarsall.bat`, écrit en dur dans le script `compile_win_headers.bat` doit être adapté à votre installation.
## À 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/

View File

@ -1,14 +0,0 @@
pub fn add(left: usize, right: usize) -> usize {
left + right
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
}

View File

@ -1,17 +0,0 @@
/**
* libssv.rs
*
* Low level bindings to the SSVLIB dynamic library.
* TODO : look for creating a dedicated *-sys crate : https://kornel.ski/rust-sys-crate
*/
use libc::{ c_char, c_void, c_ushort, size_t };
#[cfg_attr(target_os = "linux", link(name = "ssvlux64"))]
#[cfg_attr(target_os = "windows", link(name = "ssvw64"))]
extern "C" {
pub fn SSV_InitLIB2(pcRepSesamIni: *const c_char) -> c_ushort;
pub 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;
pub fn SSV_LireConfig(ZDonneesSortie: *mut *mut c_void, TTailleDonneesSortie: *mut size_t) -> c_ushort;
}
/* TODO : replace void* by Rust struct : https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs */

View File

@ -1,6 +0,0 @@
mod ssvlib_demo;
mod libssv;
fn main() {
ssvlib_demo::demo();
}

BIN
lib/libp4pillondebuglib.a Normal file

Binary file not shown.

BIN
lib/p4pillondebuglib.lib Normal file

Binary file not shown.

BIN
lib/p4pillondebuglib.o Normal file

Binary file not shown.

BIN
lib/p4pillondebuglib.obj Normal file

Binary file not shown.

BIN
lib/ssvw64.exp Normal file

Binary file not shown.

36
make.bat Normal file
View File

@ -0,0 +1,36 @@
@echo off
rem Set variables
set SRC_DIR=src
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 Configure the environment for Visual Studio
call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" x64
rem Build %SRC_DIR%\*.c files
cl /c /Fd:%LIB_DIR%\ /Fo:%LIB_DIR%\ /Iinclude\ /I%SRC_DIR%\ %SRC_DIR%\*.c
rem Link the object files into a static library
lib %LIB_DIR%\*.obj
rem Create a ssvw64.lib file from a ssvw64.def file
lib /def:%SRC_DIR%\ssvw64.def /out:%LIB_DIR%\ssvw64.lib /machine:x64
rem Build complete
pause
exit /b 0
:clean
del %LIB_DIR%\*.obj
del %LIB_DIR%\*.lib
del %LIB_DIR%\*.exp
rem Clean complete
pause
exit /b 0

32
makefile Normal file
View File

@ -0,0 +1,32 @@
# Detect the operating system
ifeq ($(OS),Windows_NT)
MKDIR = if not exist $(LIB_DIR) mkdir $(LIB_DIR)
RM = del
else
MKDIR = mkdir -p $(LIB_DIR)
RM = rm -f
endif
CC = gcc
AR = ar
CFLAGS = -Wall -fPIC
SRC_DIR = src
LIB_DIR = lib
SRC_FILES = $(wildcard $(SRC_DIR)/*.c)
OBJ_FILES = $(SRC_FILES:$(SRC_DIR)/%.c=$(LIB_DIR)/%.o)
STATIC_LIB = $(LIB_DIR)/libp4pillondebuglib.a
all: $(STATIC_LIB)
$(STATIC_LIB): $(OBJ_FILES)
$(MKDIR)
$(AR) rcs $@ $^
$(LIB_DIR)/%.o: $(SRC_DIR)/%.c
$(MKDIR)
$(CC) $(CFLAGS) -c $< -o $@
clean:
$(RM) $(OBJ_FILES) $(STATIC_LIB)
.PHONY: all clean

View File

View File

@ -1,26 +0,0 @@
@echo off
rem Set variables
set LIB_DIR=crates/sesam-vitale/lib
set DEF_DIR=crates/sesam-vitale/src/win/fsv
if "%1"=="/clean" (
goto clean
)
rem Set the environment for the x64 platform
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
del %LIB_DIR%\*.exp
rem Clean complete
pause
exit /b 0

7
src/main.rs Normal file
View File

@ -0,0 +1,7 @@
mod p4pillondebuglib_demo;
mod ssvlib_demo;
fn main() {
p4pillondebuglib_demo::demo();
ssvlib_demo::demo();
}

57
src/p4pillondebuglib.c Normal file
View File

@ -0,0 +1,57 @@
// mylib.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* hello() {
return "Hello, World!";
}
char* helloName(const char *name) {
char *result = (char *)malloc(strlen(name) + 9);
if (result) {
sprintf(result, "Hello, %s!", name);
}
return result;
}
void helloPtr(char *result) {
sprintf(result, "Hello, World!");
}
void helloPtrPtr(char **result, size_t *size) {
const char *message = "Hello, World!";
*size = strlen(message) + 1; // +1 for null terminator
*result = (char *)malloc(*size);
if (*result) {
strcpy(*result, message);
}
}
void helloVoidPtrPtr(void **result, size_t *size) {
const char *message = "Hello, World!";
*size = strlen(message) + 1; // +1 for null terminator
*result = malloc(*size);
if (*result != NULL) {
strcpy((char *)*result, message);
}
}
int add(int a, int b) {
return a + b;
}
// Add function returning result in a pointer
void addPtr(int a, int b, int *result) {
*result = a + b;
}
void fillHexValues(void **result, size_t *size) {
unsigned char values[5] = {0x05, 0xE7, 0x02, 0x00, 0x00};
*size = sizeof(values);
*result = malloc(*size);
if (*result != NULL) {
memcpy(*result, values, *size);
}
}

15
src/p4pillondebuglib.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef P4PILLONDEBUGLIB_H
#define P4PILLONDEBUGLIB_H
#include <stddef.h>
char* hello();
char* helloName(const char *name);
void helloPtr(char *result);
void helloPtrPtr(char **result, size_t *size);
void helloVoidPtrPtr(void **result, size_t *size);
int add(int a, int b);
void addPtr(int a, int b, int *result);
void fillHexValues(void **result, size_t *size);
#endif // P4PILLONDEBUGLIB_H

View File

@ -0,0 +1,101 @@
extern crate libc;
use libc::{ c_char, c_int, c_void, size_t };
use std::ffi::{ CStr, CString };
use std::ptr;
#[link(name = "p4pillondebuglib")]
extern "C" {
fn hello() -> *const c_char;
fn helloName(name: *const c_char) -> *const c_char;
fn helloPtr(result: *mut c_char);
fn helloPtrPtr(result: *mut *mut c_char, size: *mut size_t);
fn helloVoidPtrPtr(result: *mut *mut c_void, size: *mut size_t);
fn add(a: c_int, b: c_int) -> c_int;
fn addPtr(a: c_int, b: c_int, result: *mut c_int);
fn fillHexValues(result: *mut *mut c_void, size: *mut size_t);
}
pub fn demo() {
println!("------- Demo for the P4PillonDebugLib ---");
unsafe {
let c_str = hello();
let r_str: &str = CStr::from_ptr(c_str).to_str().unwrap();
println!("{} from C", r_str);
}
let name = CString::new("John").expect("CString::new failed");
unsafe {
let c_str = helloName(name.as_ptr());
let r_str = CStr::from_ptr(c_str).to_str().expect("Conversion failed");
println!("{} from C with name", r_str);
libc::free(c_str as *mut c_void);
}
let mut buffer: [c_char; 50] = [0; 50];
unsafe {
helloPtr(buffer.as_mut_ptr());
let c_str = CStr::from_ptr(buffer.as_ptr());
let r_str = c_str.to_str().unwrap();
println!("{} from C Ptr", r_str);
}
let mut buffer: *mut c_char = ptr::null_mut();
let mut size: size_t = 0;
unsafe {
helloPtrPtr(&mut buffer, &mut size);
if !buffer.is_null() {
let c_str = CStr::from_ptr(buffer);
let r_str = c_str.to_str().unwrap();
println!("{} from C Ptr Ptr (size: {})", r_str, size);
libc::free(buffer as *mut c_void);
}
}
let mut buffer: *mut c_void = ptr::null_mut();
let mut size: size_t = 0;
unsafe {
helloVoidPtrPtr(&mut buffer, &mut size);
if !buffer.is_null() {
let c_str = CStr::from_ptr(buffer as *const c_char);
let r_str = c_str.to_str().unwrap();
println!("{} from C Void Ptr Ptr (size: {})", r_str, size);
libc::free(buffer);
}
}
unsafe {
let result = add(1, 2);
println!("Result of 1 + 2 = {}", result);
}
unsafe {
let mut result = 0;
addPtr(1, 2, &mut result);
println!("Result Ptr of 1 + 2 = {}", result);
}
let mut buffer: *mut c_void = ptr::null_mut();
let mut size: size_t = 0;
unsafe {
fillHexValues(&mut buffer, &mut size);
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);
}
}
println!("-----------------------------------------");
}

View File

@ -1,24 +1,18 @@
/**
* High level API for the SSV library,
* based on the low level bindings in libssv.rs.
*
*/
extern crate libc; extern crate libc;
extern crate dotenv; extern crate dotenv;
use libc::{ c_void, size_t }; use libc::{ c_char, c_void, c_ushort, size_t };
use std::ffi::CString; use std::ffi::CString;
use std::path::PathBuf;
use std::ptr; use std::ptr;
use dotenv::dotenv;
use std::env; use std::env;
use crate::libssv:: { extern "C" {
SSV_InitLIB2, fn SSV_InitLIB2(pcRepSesamIni: *const c_char) -> c_ushort;
SSV_LireCartePS, 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;
SSV_LireConfig fn SSV_LireConfig(ZDonneesSortie: *mut *mut c_void, TTailleDonneesSortie: *mut size_t) -> c_ushort;
}; }
fn ssv_init_lib_2() { fn ssv_init_lib_2() {
let ini_str = env::var("SESAM_INI_PATH").expect("SESAM_INI_PATH must be set"); let ini_str = env::var("SESAM_INI_PATH").expect("SESAM_INI_PATH must be set");
@ -78,13 +72,7 @@ fn ssv_lire_config() {
} }
pub fn demo() { pub fn demo() {
/* dotenv().ok();
* TODO : this is probably not working on release, because I'm not sure it exists a CARGO_MANIFEST_DIR and so it can find the `.env`
* Maybe we could use a system standard config path to store a config file
*/
let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let manifest_path = PathBuf::from(manifest_dir);
dotenv::from_path(manifest_path.join(".env")).ok();
println!("------- Demo for the SSV library --------"); println!("------- Demo for the SSV library --------");