update du mediaserver pour le passer en mode stateless
This commit is contained in:
@@ -2,7 +2,7 @@ use crate::connectionmanager::variables::CURRENTCONNECTIONIDS;
|
|||||||
use pmoupnp::define_action;
|
use pmoupnp::define_action;
|
||||||
|
|
||||||
define_action! {
|
define_action! {
|
||||||
pub static GETCURRENTCONNECTIONIDS = "GetCurrentConnectionIDs" {
|
pub static GETCURRENTCONNECTIONIDS = "GetCurrentConnectionIDs" stateless {
|
||||||
out "ConnectionIDs" => CURRENTCONNECTIONIDS,
|
out "ConnectionIDs" => CURRENTCONNECTIONIDS,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use crate::connectionmanager::variables::{
|
|||||||
use pmoupnp::define_action;
|
use pmoupnp::define_action;
|
||||||
|
|
||||||
define_action! {
|
define_action! {
|
||||||
pub static GETCURRENTCONNECTIONINFO = "GetCurrentConnectionInfo" {
|
pub static GETCURRENTCONNECTIONINFO = "GetCurrentConnectionInfo" stateless {
|
||||||
in "ConnectionID" => A_ARG_TYPE_CONNECTIONID,
|
in "ConnectionID" => A_ARG_TYPE_CONNECTIONID,
|
||||||
out "RcsID" => A_ARG_TYPE_RCSID,
|
out "RcsID" => A_ARG_TYPE_RCSID,
|
||||||
out "AVTransportID" => A_ARG_TYPE_AVTRANSPORTID,
|
out "AVTransportID" => A_ARG_TYPE_AVTRANSPORTID,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use crate::connectionmanager::variables::{SOURCEPROTOCOLINFO, SINKPROTOCOLINFO};
|
|||||||
use pmoupnp::define_action;
|
use pmoupnp::define_action;
|
||||||
|
|
||||||
define_action! {
|
define_action! {
|
||||||
pub static GETPROTOCOLINFO = "GetProtocolInfo" {
|
pub static GETPROTOCOLINFO = "GetProtocolInfo" stateless {
|
||||||
out "Source" => SOURCEPROTOCOLINFO,
|
out "Source" => SOURCEPROTOCOLINFO,
|
||||||
out "Sink" => SINKPROTOCOLINFO,
|
out "Sink" => SINKPROTOCOLINFO,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use pmoupnp::define_action;
|
|||||||
use crate::contentdirectory::handlers;
|
use crate::contentdirectory::handlers;
|
||||||
|
|
||||||
define_action! {
|
define_action! {
|
||||||
pub static BROWSE = "Browse" {
|
pub static BROWSE = "Browse" stateless {
|
||||||
in "ObjectID" => A_ARG_TYPE_OBJECTID,
|
in "ObjectID" => A_ARG_TYPE_OBJECTID,
|
||||||
in "BrowseFlag" => A_ARG_TYPE_BROWSEFLAG,
|
in "BrowseFlag" => A_ARG_TYPE_BROWSEFLAG,
|
||||||
in "Filter" => A_ARG_TYPE_FILTER,
|
in "Filter" => A_ARG_TYPE_FILTER,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use pmoupnp::define_action;
|
|||||||
use crate::contentdirectory::handlers;
|
use crate::contentdirectory::handlers;
|
||||||
|
|
||||||
define_action! {
|
define_action! {
|
||||||
pub static GETSEARCHCAPABILITIES = "GetSearchCapabilities" {
|
pub static GETSEARCHCAPABILITIES = "GetSearchCapabilities" stateless {
|
||||||
out "SearchCaps" => SEARCHCAPABILITIES,
|
out "SearchCaps" => SEARCHCAPABILITIES,
|
||||||
}
|
}
|
||||||
with handler handlers::get_search_capabilities_handler()
|
with handler handlers::get_search_capabilities_handler()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use pmoupnp::define_action;
|
|||||||
use crate::contentdirectory::handlers;
|
use crate::contentdirectory::handlers;
|
||||||
|
|
||||||
define_action! {
|
define_action! {
|
||||||
pub static GETSORTCAPABILITIES = "GetSortCapabilities" {
|
pub static GETSORTCAPABILITIES = "GetSortCapabilities" stateless {
|
||||||
out "SortCaps" => SORTCAPABILITIES,
|
out "SortCaps" => SORTCAPABILITIES,
|
||||||
}
|
}
|
||||||
with handler handlers::get_sort_capabilities_handler()
|
with handler handlers::get_sort_capabilities_handler()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use pmoupnp::define_action;
|
|||||||
use crate::contentdirectory::handlers;
|
use crate::contentdirectory::handlers;
|
||||||
|
|
||||||
define_action! {
|
define_action! {
|
||||||
pub static GETSYSTEMUPDATEID = "GetSystemUpdateID" {
|
pub static GETSYSTEMUPDATEID = "GetSystemUpdateID" stateless {
|
||||||
out "Id" => SYSTEMUPDATEID,
|
out "Id" => SYSTEMUPDATEID,
|
||||||
}
|
}
|
||||||
with handler handlers::get_system_update_id_handler()
|
with handler handlers::get_system_update_id_handler()
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use pmoupnp::define_action;
|
|||||||
use crate::contentdirectory::handlers;
|
use crate::contentdirectory::handlers;
|
||||||
|
|
||||||
define_action! {
|
define_action! {
|
||||||
pub static SEARCH = "Search" {
|
pub static SEARCH = "Search" stateless {
|
||||||
in "ContainerID" => A_ARG_TYPE_OBJECTID,
|
in "ContainerID" => A_ARG_TYPE_OBJECTID,
|
||||||
in "SearchCriteria" => A_ARG_TYPE_SEARCHCRITERIA,
|
in "SearchCriteria" => A_ARG_TYPE_SEARCHCRITERIA,
|
||||||
in "Filter" => A_ARG_TYPE_FILTER,
|
in "Filter" => A_ARG_TYPE_FILTER,
|
||||||
|
|||||||
@@ -23,9 +23,8 @@
|
|||||||
//! - [`get_sort_capabilities_handler`] : Capacités de tri supportées
|
//! - [`get_sort_capabilities_handler`] : Capacités de tri supportées
|
||||||
//! - [`get_system_update_id_handler`] : ID de mise à jour du système
|
//! - [`get_system_update_id_handler`] : ID de mise à jour du système
|
||||||
|
|
||||||
use pmoupnp::action_handler;
|
use pmoupnp::{action_handler, get, set};
|
||||||
use pmoupnp::actions::{ActionHandler, ActionError};
|
use pmoupnp::actions::{ActionError, ActionHandler};
|
||||||
use pmoupnp::variable_types::StateValue;
|
|
||||||
use crate::content_handler::ContentHandler;
|
use crate::content_handler::ContentHandler;
|
||||||
use tracing::{debug, error};
|
use tracing::{debug, error};
|
||||||
|
|
||||||
@@ -49,51 +48,18 @@ use tracing::{debug, error};
|
|||||||
/// - `TotalMatches` : Nombre total d'éléments
|
/// - `TotalMatches` : Nombre total d'éléments
|
||||||
/// - `UpdateID` : ID de mise à jour
|
/// - `UpdateID` : ID de mise à jour
|
||||||
pub fn browse_handler() -> ActionHandler {
|
pub fn browse_handler() -> ActionHandler {
|
||||||
action_handler!(|instance| {
|
action_handler!(|data| {
|
||||||
|
let mut data = data;
|
||||||
debug!("📂 Browse handler called");
|
debug!("📂 Browse handler called");
|
||||||
|
|
||||||
let handler = ContentHandler::new();
|
let handler = ContentHandler::new();
|
||||||
|
|
||||||
// Extraire les arguments d'entrée
|
let object_id: String = get!(&data, "ObjectID", String);
|
||||||
let object_id = match instance
|
let browse_flag: String = get!(&data, "BrowseFlag", String);
|
||||||
.argument("ObjectID")
|
let starting_index: u32 = get!(&data, "StartingIndex", u32);
|
||||||
.and_then(|arg| arg.get_variable_instance())
|
let requested_count: u32 = get!(&data, "RequestedCount", u32);
|
||||||
.ok_or_else(|| ActionError::ArgumentError("ObjectID not found".to_string()))?
|
let _filter: String = get!(&data, "Filter", String);
|
||||||
.value()
|
let _sort_criteria: String = get!(&data, "SortCriteria", String);
|
||||||
{
|
|
||||||
StateValue::String(s) => s,
|
|
||||||
_ => return Err(ActionError::ArgumentError("ObjectID must be a string".to_string())),
|
|
||||||
};
|
|
||||||
|
|
||||||
let browse_flag = match instance
|
|
||||||
.argument("BrowseFlag")
|
|
||||||
.and_then(|arg| arg.get_variable_instance())
|
|
||||||
.ok_or_else(|| ActionError::ArgumentError("BrowseFlag not found".to_string()))?
|
|
||||||
.value()
|
|
||||||
{
|
|
||||||
StateValue::String(s) => s,
|
|
||||||
_ => return Err(ActionError::ArgumentError("BrowseFlag must be a string".to_string())),
|
|
||||||
};
|
|
||||||
|
|
||||||
let starting_index = match instance
|
|
||||||
.argument("StartingIndex")
|
|
||||||
.and_then(|arg| arg.get_variable_instance())
|
|
||||||
.ok_or_else(|| ActionError::ArgumentError("StartingIndex not found".to_string()))?
|
|
||||||
.value()
|
|
||||||
{
|
|
||||||
StateValue::UI4(n) => n,
|
|
||||||
_ => return Err(ActionError::ArgumentError("StartingIndex must be ui4".to_string())),
|
|
||||||
};
|
|
||||||
|
|
||||||
let requested_count = match instance
|
|
||||||
.argument("RequestedCount")
|
|
||||||
.and_then(|arg| arg.get_variable_instance())
|
|
||||||
.ok_or_else(|| ActionError::ArgumentError("RequestedCount not found".to_string()))?
|
|
||||||
.value()
|
|
||||||
{
|
|
||||||
StateValue::UI4(n) => n,
|
|
||||||
_ => return Err(ActionError::ArgumentError("RequestedCount must be ui4".to_string())),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Appeler la logique métier
|
// Appeler la logique métier
|
||||||
let (didl, returned, total, update_id) = handler
|
let (didl, returned, total, update_id) = handler
|
||||||
@@ -105,32 +71,13 @@ pub fn browse_handler() -> ActionHandler {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Définir les arguments de sortie
|
// Définir les arguments de sortie
|
||||||
if let Some(arg) = instance.argument("Result") {
|
set!(&mut data, "Result", didl);
|
||||||
if let Some(var) = arg.get_variable_instance() {
|
set!(&mut data, "NumberReturned", returned);
|
||||||
var.set_value(StateValue::String(didl)).await;
|
set!(&mut data, "TotalMatches", total);
|
||||||
}
|
set!(&mut data, "UpdateID", update_id);
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(arg) = instance.argument("NumberReturned") {
|
|
||||||
if let Some(var) = arg.get_variable_instance() {
|
|
||||||
var.set_value(StateValue::UI4(returned)).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(arg) = instance.argument("TotalMatches") {
|
|
||||||
if let Some(var) = arg.get_variable_instance() {
|
|
||||||
var.set_value(StateValue::UI4(total)).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(arg) = instance.argument("UpdateID") {
|
|
||||||
if let Some(var) = arg.get_variable_instance() {
|
|
||||||
var.set_value(StateValue::UI4(update_id)).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
debug!("✅ Browse completed: returned={}, total={}", returned, total);
|
debug!("✅ Browse completed: returned={}, total={}", returned, total);
|
||||||
Ok(())
|
Ok(data)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,30 +101,18 @@ pub fn browse_handler() -> ActionHandler {
|
|||||||
/// - `TotalMatches` : Total
|
/// - `TotalMatches` : Total
|
||||||
/// - `UpdateID` : ID de mise à jour
|
/// - `UpdateID` : ID de mise à jour
|
||||||
pub fn search_handler() -> ActionHandler {
|
pub fn search_handler() -> ActionHandler {
|
||||||
action_handler!(|instance| {
|
action_handler!(|data| {
|
||||||
|
let mut data = data;
|
||||||
debug!("🔍 Search handler called");
|
debug!("🔍 Search handler called");
|
||||||
|
|
||||||
let handler = ContentHandler::new();
|
let handler = ContentHandler::new();
|
||||||
|
|
||||||
let container_id = match instance
|
let container_id: String = get!(&data, "ContainerID", String);
|
||||||
.argument("ContainerID")
|
let search_criteria: String = get!(&data, "SearchCriteria", String);
|
||||||
.and_then(|arg| arg.get_variable_instance())
|
let _filter: String = get!(&data, "Filter", String);
|
||||||
.ok_or_else(|| ActionError::ArgumentError("ContainerID not found".to_string()))?
|
let _starting_index: u32 = get!(&data, "StartingIndex", u32);
|
||||||
.value()
|
let _requested_count: u32 = get!(&data, "RequestedCount", u32);
|
||||||
{
|
let _sort_criteria: String = get!(&data, "SortCriteria", String);
|
||||||
StateValue::String(s) => s,
|
|
||||||
_ => return Err(ActionError::ArgumentError("ContainerID must be a string".to_string())),
|
|
||||||
};
|
|
||||||
|
|
||||||
let search_criteria = match instance
|
|
||||||
.argument("SearchCriteria")
|
|
||||||
.and_then(|arg| arg.get_variable_instance())
|
|
||||||
.ok_or_else(|| ActionError::ArgumentError("SearchCriteria not found".to_string()))?
|
|
||||||
.value()
|
|
||||||
{
|
|
||||||
StateValue::String(s) => s,
|
|
||||||
_ => return Err(ActionError::ArgumentError("SearchCriteria must be a string".to_string())),
|
|
||||||
};
|
|
||||||
|
|
||||||
let (didl, returned, total, update_id) = handler
|
let (didl, returned, total, update_id) = handler
|
||||||
.search(&container_id, &search_criteria)
|
.search(&container_id, &search_criteria)
|
||||||
@@ -188,32 +123,13 @@ pub fn search_handler() -> ActionHandler {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Définir les sorties
|
// Définir les sorties
|
||||||
if let Some(arg) = instance.argument("Result") {
|
set!(&mut data, "Result", didl);
|
||||||
if let Some(var) = arg.get_variable_instance() {
|
set!(&mut data, "NumberReturned", returned);
|
||||||
var.set_value(StateValue::String(didl)).await;
|
set!(&mut data, "TotalMatches", total);
|
||||||
}
|
set!(&mut data, "UpdateID", update_id);
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(arg) = instance.argument("NumberReturned") {
|
|
||||||
if let Some(var) = arg.get_variable_instance() {
|
|
||||||
var.set_value(StateValue::UI4(returned)).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(arg) = instance.argument("TotalMatches") {
|
|
||||||
if let Some(var) = arg.get_variable_instance() {
|
|
||||||
var.set_value(StateValue::UI4(total)).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(arg) = instance.argument("UpdateID") {
|
|
||||||
if let Some(var) = arg.get_variable_instance() {
|
|
||||||
var.set_value(StateValue::UI4(update_id)).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
debug!("✅ Search completed: returned={}, total={}", returned, total);
|
debug!("✅ Search completed: returned={}, total={}", returned, total);
|
||||||
Ok(())
|
Ok(data)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,20 +141,17 @@ pub fn search_handler() -> ActionHandler {
|
|||||||
///
|
///
|
||||||
/// - `SearchCaps` : Chaîne de capacités séparées par virgules
|
/// - `SearchCaps` : Chaîne de capacités séparées par virgules
|
||||||
pub fn get_search_capabilities_handler() -> ActionHandler {
|
pub fn get_search_capabilities_handler() -> ActionHandler {
|
||||||
action_handler!(|instance| {
|
action_handler!(|data| {
|
||||||
|
let mut data = data;
|
||||||
debug!("🔍 GetSearchCapabilities handler called");
|
debug!("🔍 GetSearchCapabilities handler called");
|
||||||
|
|
||||||
let handler = ContentHandler::new();
|
let handler = ContentHandler::new();
|
||||||
let capabilities = handler.get_search_capabilities().await;
|
let capabilities = handler.get_search_capabilities().await;
|
||||||
|
|
||||||
if let Some(arg) = instance.argument("SearchCaps") {
|
set!(&mut data, "SearchCaps", capabilities.clone());
|
||||||
if let Some(var) = arg.get_variable_instance() {
|
|
||||||
var.set_value(StateValue::String(capabilities.clone())).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
debug!("✅ SearchCapabilities: {}", capabilities);
|
debug!("✅ SearchCapabilities: {}", capabilities);
|
||||||
Ok(())
|
Ok(data)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,20 +163,17 @@ pub fn get_search_capabilities_handler() -> ActionHandler {
|
|||||||
///
|
///
|
||||||
/// - `SortCaps` : Chaîne de capacités séparées par virgules
|
/// - `SortCaps` : Chaîne de capacités séparées par virgules
|
||||||
pub fn get_sort_capabilities_handler() -> ActionHandler {
|
pub fn get_sort_capabilities_handler() -> ActionHandler {
|
||||||
action_handler!(|instance| {
|
action_handler!(|data| {
|
||||||
|
let mut data = data;
|
||||||
debug!("📊 GetSortCapabilities handler called");
|
debug!("📊 GetSortCapabilities handler called");
|
||||||
|
|
||||||
let handler = ContentHandler::new();
|
let handler = ContentHandler::new();
|
||||||
let capabilities = handler.get_sort_capabilities().await;
|
let capabilities = handler.get_sort_capabilities().await;
|
||||||
|
|
||||||
if let Some(arg) = instance.argument("SortCaps") {
|
set!(&mut data, "SortCaps", capabilities.clone());
|
||||||
if let Some(var) = arg.get_variable_instance() {
|
|
||||||
var.set_value(StateValue::String(capabilities.clone())).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
debug!("✅ SortCapabilities: {}", capabilities);
|
debug!("✅ SortCapabilities: {}", capabilities);
|
||||||
Ok(())
|
Ok(data)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,20 +186,17 @@ pub fn get_sort_capabilities_handler() -> ActionHandler {
|
|||||||
///
|
///
|
||||||
/// - `Id` : ID de mise à jour (entier non signé)
|
/// - `Id` : ID de mise à jour (entier non signé)
|
||||||
pub fn get_system_update_id_handler() -> ActionHandler {
|
pub fn get_system_update_id_handler() -> ActionHandler {
|
||||||
action_handler!(|instance| {
|
action_handler!(|data| {
|
||||||
|
let mut data = data;
|
||||||
debug!("🔄 GetSystemUpdateID handler called");
|
debug!("🔄 GetSystemUpdateID handler called");
|
||||||
|
|
||||||
let handler = ContentHandler::new();
|
let handler = ContentHandler::new();
|
||||||
let update_id = handler.get_system_update_id().await;
|
let update_id = handler.get_system_update_id().await;
|
||||||
|
|
||||||
if let Some(arg) = instance.argument("Id") {
|
set!(&mut data, "Id", update_id);
|
||||||
if let Some(var) = arg.get_variable_instance() {
|
|
||||||
var.set_value(StateValue::UI4(update_id)).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
debug!("✅ SystemUpdateID: {}", update_id);
|
debug!("✅ SystemUpdateID: {}", update_id);
|
||||||
Ok(())
|
Ok(data)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ use pmoupnp::define_variable;
|
|||||||
|
|
||||||
define_variable! {
|
define_variable! {
|
||||||
pub static A_ARG_TYPE_BROWSEFLAG: String = "A_ARG_TYPE_BrowseFlag" {
|
pub static A_ARG_TYPE_BROWSEFLAG: String = "A_ARG_TYPE_BrowseFlag" {
|
||||||
default: "BrowseDirectChildren",
|
|
||||||
allowed: ["BrowseMetadata", "BrowseDirectChildren"],
|
allowed: ["BrowseMetadata", "BrowseDirectChildren"],
|
||||||
|
default: "BrowseDirectChildren",
|
||||||
evented: false,
|
evented: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,24 +104,8 @@
|
|||||||
/// - Initialisation paresseuse via `Lazy` (thread-safe)
|
/// - Initialisation paresseuse via `Lazy` (thread-safe)
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! define_action {
|
macro_rules! define_action {
|
||||||
// Variante sans arguments avec options `stateless` et handler
|
// Variante stateless avec arguments
|
||||||
(pub static $name:ident = $action_name:literal $(stateless)? $(with handler $handler:expr)?) => {
|
(pub static $name:ident = $action_name:literal stateless {
|
||||||
pub static $name: once_cell::sync::Lazy<std::sync::Arc<$crate::actions::Action>> =
|
|
||||||
once_cell::sync::Lazy::new(|| {
|
|
||||||
let mut ac = $crate::actions::Action::new($action_name.to_string());
|
|
||||||
|
|
||||||
define_action!(@maybe_stateless ac $(stateless)?);
|
|
||||||
|
|
||||||
$(
|
|
||||||
ac.set_handler($handler);
|
|
||||||
)?
|
|
||||||
|
|
||||||
std::sync::Arc::new(ac)
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// Variante avec arguments, options `stateless` et handler
|
|
||||||
(pub static $name:ident = $action_name:literal $(stateless)? {
|
|
||||||
$(
|
$(
|
||||||
$direction:ident $arg_name:literal => $var_ref:expr
|
$direction:ident $arg_name:literal => $var_ref:expr
|
||||||
),* $(,)?
|
),* $(,)?
|
||||||
@@ -131,8 +115,7 @@ macro_rules! define_action {
|
|||||||
pub static $name: once_cell::sync::Lazy<std::sync::Arc<$crate::actions::Action>> =
|
pub static $name: once_cell::sync::Lazy<std::sync::Arc<$crate::actions::Action>> =
|
||||||
once_cell::sync::Lazy::new(|| {
|
once_cell::sync::Lazy::new(|| {
|
||||||
let mut ac = $crate::actions::Action::new($action_name.to_string());
|
let mut ac = $crate::actions::Action::new($action_name.to_string());
|
||||||
|
ac.set_stateful(false);
|
||||||
define_action!(@maybe_stateless ac $(stateless)?);
|
|
||||||
|
|
||||||
$(
|
$(
|
||||||
ac.add_argument(
|
ac.add_argument(
|
||||||
@@ -148,11 +131,64 @@ macro_rules! define_action {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
(@maybe_stateless $ac:ident stateless) => {
|
// Variante stateless sans arguments
|
||||||
$ac.set_stateful(false);
|
(pub static $name:ident = $action_name:literal stateless
|
||||||
|
$(with handler $handler:expr)?
|
||||||
|
) => {
|
||||||
|
pub static $name: once_cell::sync::Lazy<std::sync::Arc<$crate::actions::Action>> =
|
||||||
|
once_cell::sync::Lazy::new(|| {
|
||||||
|
let mut ac = $crate::actions::Action::new($action_name.to_string());
|
||||||
|
ac.set_stateful(false);
|
||||||
|
|
||||||
|
$(
|
||||||
|
ac.set_handler($handler);
|
||||||
|
)?
|
||||||
|
|
||||||
|
std::sync::Arc::new(ac)
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
(@maybe_stateless $ac:ident) => {};
|
// Variante stateful (défaut) avec arguments
|
||||||
|
(pub static $name:ident = $action_name:literal {
|
||||||
|
$(
|
||||||
|
$direction:ident $arg_name:literal => $var_ref:expr
|
||||||
|
),* $(,)?
|
||||||
|
}
|
||||||
|
$(with handler $handler:expr)?
|
||||||
|
) => {
|
||||||
|
pub static $name: once_cell::sync::Lazy<std::sync::Arc<$crate::actions::Action>> =
|
||||||
|
once_cell::sync::Lazy::new(|| {
|
||||||
|
let mut ac = $crate::actions::Action::new($action_name.to_string());
|
||||||
|
|
||||||
|
$(
|
||||||
|
ac.add_argument(
|
||||||
|
define_action!(@arg $direction $arg_name, $var_ref)
|
||||||
|
);
|
||||||
|
)*
|
||||||
|
|
||||||
|
$(
|
||||||
|
ac.set_handler($handler);
|
||||||
|
)?
|
||||||
|
|
||||||
|
std::sync::Arc::new(ac)
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Variante stateful (défaut) sans arguments
|
||||||
|
(pub static $name:ident = $action_name:literal
|
||||||
|
$(with handler $handler:expr)?
|
||||||
|
) => {
|
||||||
|
pub static $name: once_cell::sync::Lazy<std::sync::Arc<$crate::actions::Action>> =
|
||||||
|
once_cell::sync::Lazy::new(|| {
|
||||||
|
let mut ac = $crate::actions::Action::new($action_name.to_string());
|
||||||
|
|
||||||
|
$(
|
||||||
|
ac.set_handler($handler);
|
||||||
|
)?
|
||||||
|
|
||||||
|
std::sync::Arc::new(ac)
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Helper interne pour créer un argument d'entrée
|
// Helper interne pour créer un argument d'entrée
|
||||||
(@arg in $name:literal, $var:expr) => {
|
(@arg in $name:literal, $var:expr) => {
|
||||||
|
|||||||
@@ -386,7 +386,7 @@ impl UpnpServerExt for Server {
|
|||||||
|
|
||||||
async fn create_upnp_server() -> Result<Server, anyhow::Error> {
|
async fn create_upnp_server() -> Result<Server, anyhow::Error> {
|
||||||
use pmoserver::ServerBuilder;
|
use pmoserver::ServerBuilder;
|
||||||
use tracing::{info, warn};
|
use tracing::{error, info, warn};
|
||||||
|
|
||||||
// 1. Créer le serveur depuis la config
|
// 1. Créer le serveur depuis la config
|
||||||
info!("🔧 Creating UPnP server from configuration...");
|
info!("🔧 Creating UPnP server from configuration...");
|
||||||
@@ -421,7 +421,19 @@ impl UpnpServerExt for Server {
|
|||||||
match server.init_ssdp() {
|
match server.init_ssdp() {
|
||||||
Ok(_) => info!("✅ SSDP server initialized"),
|
Ok(_) => info!("✅ SSDP server initialized"),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!("❌ SSDP initialization failed: {}", e);
|
let kind = e.kind();
|
||||||
|
if kind == std::io::ErrorKind::AddrInUse {
|
||||||
|
error!(
|
||||||
|
"❌ SSDP initialization failed: port {} is already in use. \
|
||||||
|
Check which process listens on UDP:{} (e.g. `lsof -nP -i UDP:{}`): {}",
|
||||||
|
crate::ssdp::SSDP_PORT,
|
||||||
|
crate::ssdp::SSDP_PORT,
|
||||||
|
crate::ssdp::SSDP_PORT,
|
||||||
|
e,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
error!("❌ SSDP initialization failed: {}", e);
|
||||||
|
}
|
||||||
return Err(e.into());
|
return Err(e.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user