Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 30 additions & 6 deletions device/mock_device/src/mock_device_ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,60 +70,84 @@ pub async fn start_service() {
}

async fn init(client: ServiceClient) {
info!("@@@NNA: Entered init function");
if let Some(mut extn_client) = client.get_extn_client() {
info!("@@@NNA: extn_client found, spawning websocket server");
let client_c_for_init = client.clone();
tokio::spawn(async move {
match boot_ws_server(extn_client.clone()).await {
Ok(server) => {
info!("@@@NNA: Websocket server started successfully");
let state = MockDeviceState::new(server);

let mut methods = Methods::new();
let _ = methods.merge(MockDeviceController::new(state).into_rpc());
info!("@@@NNA: RPC methods merged");
let processor = RPCRequestProcessor::new(
extn_client.clone(),
methods,
ExtnId::new_channel(ExtnClassId::Device, "mock_device".into()),
);
info!("@@@NNA: RPCRequestProcessor created, adding to extn_client");
extn_client.add_request_processor(processor);
}
Err(err) => panic!("websocket server failed to start. {}", err),
Err(err) => {
error!("@@@NNA: websocket server failed to start. {}", err);
panic!("websocket server failed to start. {}", err);
}
};
});

info!("@@@NNA: Initializing client_c_for_init");
client_c_for_init.initialize().await;
info!("@@@NNA: client_c_for_init initialized");
} else {
error!("Service client does not hold an extn client. Cannot start eos extension.");
error!("@@@NNA: Service client does not hold an extn client. Cannot start eos extension.");
}
}

fn start() {
info!("@@@NNA: Entered start function");
let Ok((extn_manifest, _device_manifest)) = RippleManifestLoader::initialize() else {
error!("Error initializing manifests");
error!("@@@NNA: Error initializing manifests");
return;
};
info!("@@@NNA: Manifests initialized successfully");

let runtime = match Runtime::new() {
Ok(r) => r,
Ok(r) => {
info!("@@@NNA: Tokio runtime created successfully");
r
}
Err(err) => {
error!("Error creating runtime: {}", err);
error!("@@@NNA: Error creating runtime: {}", err);
return;
}
};

let id = ExtnId::new_channel(ExtnClassId::Device, EXTN_NAME.to_string()).to_string();
info!("@@@NNA: Generated ExtnId: {}", id);

let symbol = extn_manifest.get_extn_symbol(&id);
if symbol.is_none() {
error!("Error getting symbol");
error!("@@@NNA: Error getting symbol");
return;
}
info!("@@@NNA: Extension symbol found");

let service_client = if let Some(symbol) = symbol {
info!("@@@NNA: Building ServiceClient with extension symbol");
ServiceClient::builder().with_extension(symbol).build()
} else {
info!("@@@NNA: Building ServiceClient without extension symbol");
ServiceClient::builder().build()
};

info!("@@@NNA: Starting async init in runtime");
runtime.block_on(async move {
init(service_client.clone()).await;
});
info!("@@@NNA: Exiting start function");
}

fn init_extn_channel() -> ExtnChannel {
Expand Down
32 changes: 29 additions & 3 deletions device/mock_device/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,53 +37,79 @@ use crate::{
pub async fn boot_ws_server(
mut client: ExtnClient,
) -> Result<Arc<MockWebSocketServer>, MockDeviceError> {
debug!("Booting WS Server for mock device");
debug!("@@@NNA Booting WS Server for mock device");
debug!(
"@@@NNA Booting WS Server for mock device client:{:?}",
client
);
let gateway = platform_gateway_url(&mut client).await?;
debug!("@@@NNA platform_gateway_url returned: {:?}", gateway);

if gateway.scheme() != "ws" {
debug!("@@@NNA Bad URL scheme: {}", gateway.scheme());
return Err(BootFailedError::BadUrlScheme)?;
}

if !is_valid_host(gateway.host()) {
debug!("@@@NNA Bad hostname: {:?}", gateway.host());
return Err(BootFailedError::BadHostname)?;
}

let config = load_config(&client);
debug!("@@@NNA Loaded config: {:?}", config);

let mut server_config = WsServerParameters::new();
let mock_data_v2 = load_mock_data_v2(client.clone()).await?;
debug!("@@@NNA Loaded mock data v2");

server_config
.port(gateway.port().unwrap_or(0))
.path(gateway.path());
debug!(
"@@@NNA Server config: port={}, path={}",
gateway.port().unwrap_or(0),
gateway.path()
);

let ws_server = MockWebSocketServer::new(mock_data_v2, server_config, config)
.await
.map_err(BootFailedError::ServerStartFailed)?;
debug!("@@@NNA MockWebSocketServer created");

let ws_server = Arc::new(ws_server);
let server = ws_server.clone();

tokio::spawn(async move {
debug!("@@@NNA Starting WebSocket server");
server.start_server().await;
});

debug!("@@@NNA Returning ws_server Arc");
Ok(ws_server)
}

async fn platform_gateway_url(client: &mut ExtnClient) -> Result<Url, MockDeviceError> {
debug!("sending request for config.platform_parameters");
debug!(
"@@@NNA platform_gateway_url called with client: {:?}",
client
);
debug!("@@@NNA sending request for config.platform_parameters");
if let Ok(response) = client.request(Config::PlatformParameters).await {
debug!("@@@NNA received response: {:?}", response);
if let Some(ExtnResponse::Value(value)) = response.payload.extract() {
debug!("@@@NNA extracted value: {:?}", value);
let gateway: Url = value
.as_object()
.and_then(|obj| obj.get("gateway"))
.and_then(|val| val.as_str())
.and_then(|s| s.parse().ok())
.ok_or(BootFailedError::GetPlatformGatewayFailed)?;
debug!("{}", gateway);
debug!("@@@NNA parsed gateway URL: {}", gateway);
return Ok(gateway);
}
}

error!("@@@NNA Failed to get platform gateway URL");
Err(BootFailedError::GetPlatformGatewayFailed)?
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ impl ThunderDeviceInfoRequestProcessor {
}

async fn model(state: CachedState, req: ExtnMessage) -> bool {
ripple_sdk::log::info!("@@@NNA...Entered ThunderDeviceInfoRequestProcessor::model");
let response = Self::get_model(&state).await;
Self::respond(state.get_client(), req, ExtnResponse::String(response))
.await
Expand Down Expand Up @@ -942,6 +943,11 @@ impl ExtnRequestProcessor for ThunderDeviceInfoRequestProcessor {
msg: ExtnMessage,
extracted_message: Self::VALUE,
) -> bool {
// Debug log: print contract name for incoming request
ripple_sdk::log::info!(
"@@@NNA...Incoming DeviceInfoRequest: {:?}",
extracted_message
);
match extracted_message {
DeviceInfoRequest::Model => Self::model(state.clone(), msg).await,
DeviceInfoRequest::Audio => Self::audio(state.clone(), msg).await,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,42 @@ async fn test_register_state_change_event() {
.await;
}

// //added to avoid RESPONSE: {"jsonrpc":"2.0","error":{"code":-32600,"message":"Cannot find a matching response for the received request","data":""}}
// #[tokio::test(flavor = "multi_thread")]
// #[cfg_attr(not(feature = "websocket_contract_tests"), ignore)]
// async fn test_controller_status_no_callsign() {
// mock_websocket_server!(
// builder,
// server,
// server_url,
// "controller_status_no_callsign",
// json!({
// "pact:content-type": "application/json",
// "request": {"jsonrpc": "matching(type, '2.0')", "id": "matching(integer, 0)", "method": "Controller.1.status"},
// "requestMetadata": {
// "path": "/jsonrpc"
// },
// "response": [{
// "jsonrpc": "matching(type, '2.0')",
// "id": "matching(integer, 0)",
// "result": [{
// "state": "activated"
// }]
// }]
// })
// );

// send_thunder_call_message!(
// server_url.to_string(),
// json!({
// "jsonrpc": "2.0",
// "id": 3,
// "method": "Controller.1.status"
// })
// )
// .await;
// }

#[tokio::test(flavor = "multi_thread")]
#[cfg_attr(not(feature = "websocket_contract_tests"), ignore)]
async fn test_device_info_plugin_status() {
Expand All @@ -66,13 +102,13 @@ async fn test_device_info_plugin_status() {
"device_info_plugin_status",
json!({
"pact:content-type": "application/json",
"request": {"jsonrpc": "matching(type, '2.0')", "id": "matching(integer, 1)", "method": "Controller.1.status@DeviceInfo"},
"request": {"jsonrpc": "matching(type, '2.0')", "id": "matching(integer, 0)", "method": "Controller.1.status@DeviceInfo"},
"requestMetadata": {
"path": "/jsonrpc"
},
"response": [{
"jsonrpc": "matching(type, '2.0')",
"id": "matching(integer, 1)",
"id": "matching(integer, 0)",
"result": [{
"callsign": "matching(type, 'string')",
"locator": "matching(type, 'string')",
Expand Down Expand Up @@ -149,13 +185,13 @@ async fn test_display_settings_plugin_status() {
"display_settings_plugin_status",
json!({
"pact:content-type": "application/json",
"request": {"jsonrpc": "matching(type, '2.0')", "id": "matching(integer, 3)", "method": "[email protected]"},
"request": {"jsonrpc": "matching(type, '2.0')", "id": "matching(integer, 0)", "method": "[email protected]"},
"requestMetadata": {
"path": "/jsonrpc"
},
"response": [{
"jsonrpc": "matching(type, '2.0')",
"id": "matching(integer, 3)",
"id": "matching(integer, 0)",
"result": [{
"callsign": "matching(type, 'string')",
"locator": "matching(type, 'string')",
Expand Down Expand Up @@ -231,13 +267,13 @@ async fn test_status_org_rdk_system() {
"status_org_rdk_system",
json!({
"pact:content-type": "application/json",
"request": {"jsonrpc": "matching(type, '2.0')", "id": "matching(integer, 5)", "method": "[email protected]"},
"request": {"jsonrpc": "matching(type, '2.0')", "id": "matching(integer, 0)", "method": "[email protected]"},
"requestMetadata": {
"path": "/jsonrpc"
},
"response": [{
"jsonrpc": "matching(type, '2.0')",
"id": "matching(integer, 5)",
"id": "matching(integer, 0)",
"result": [{
"callsign": "matching(type, 'string')",
"locator": "matching(type, 'string')",
Expand Down Expand Up @@ -313,13 +349,13 @@ async fn test_status_org_rdk_hdcp_profile() {
"status_org_rdk_hdcp_profile",
json!({
"pact:content-type": "application/json",
"request": {"jsonrpc": "matching(type, '2.0')", "id": "matching(integer, 7)", "method": "[email protected]"},
"request": {"jsonrpc": "matching(type, '2.0')", "id": "matching(integer, 0)", "method": "[email protected]"},
"requestMetadata": {
"path": "/jsonrpc"
},
"response": [{
"jsonrpc": "matching(type, '2.0')",
"id": "matching(integer, 7)",
"id": "matching(integer, 0)",
"result": [{
"callsign": "matching(type, 'string')",
"locator": "matching(type, 'string')",
Expand Down Expand Up @@ -395,13 +431,13 @@ async fn test_status_org_rdk_telemetry() {
"status_org_rdk_telemetry",
json!({
"pact:content-type": "application/json",
"request": {"jsonrpc": "matching(type, '2.0')", "id": "matching(integer, 9)", "method": "[email protected]"},
"request": {"jsonrpc": "matching(type, '2.0')", "id": "matching(integer, 0)", "method": "[email protected]"},
"requestMetadata": {
"path": "/jsonrpc"
},
"response": [{
"jsonrpc": "matching(type, '2.0')",
"id": "matching(integer, 9)",
"id": "matching(integer, 0)",
"result": [{
"callsign": "matching(type, 'string')",
"locator": "matching(type, 'string')",
Expand Down
Loading