2022-12-27 09:32:52 +05:30
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Copyright (c) 2020-2022 Project CHIP Authors
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2023-02-02 18:22:21 +00:00
|
|
|
use log::info;
|
2022-12-27 09:32:52 +05:30
|
|
|
|
2023-06-09 07:47:49 +00:00
|
|
|
use crate::{error::*, CommissioningData, Matter};
|
2022-12-27 09:32:52 +05:30
|
|
|
|
2023-02-02 18:22:21 +00:00
|
|
|
use crate::secure_channel::common::PROTO_ID_SECURE_CHANNEL;
|
|
|
|
use crate::secure_channel::core::SecureChannel;
|
2022-12-27 09:32:52 +05:30
|
|
|
use crate::transport::mrp::ReliableMessage;
|
2023-04-24 21:41:16 +00:00
|
|
|
use crate::transport::{exchange, network::Address, packet::Packet};
|
2023-02-02 18:22:21 +00:00
|
|
|
|
|
|
|
use super::proto_ctx::ProtoCtx;
|
2023-04-24 09:00:08 +00:00
|
|
|
use super::session::CloneData;
|
2023-02-02 18:22:21 +00:00
|
|
|
|
|
|
|
enum RecvState {
|
|
|
|
New,
|
|
|
|
OpenExchange,
|
2023-04-24 09:00:08 +00:00
|
|
|
AddSession(CloneData),
|
2023-02-02 18:22:21 +00:00
|
|
|
EvictSession,
|
2023-04-24 09:00:08 +00:00
|
|
|
EvictSession2(CloneData),
|
2023-02-02 18:22:21 +00:00
|
|
|
Ack,
|
|
|
|
}
|
2022-12-27 09:32:52 +05:30
|
|
|
|
2023-02-02 18:22:21 +00:00
|
|
|
pub enum RecvAction<'r, 'p> {
|
2023-04-24 11:34:32 +00:00
|
|
|
Send(Address, &'r [u8]),
|
2023-02-02 18:22:21 +00:00
|
|
|
Interact(ProtoCtx<'r, 'p>),
|
2022-12-27 09:32:52 +05:30
|
|
|
}
|
|
|
|
|
2023-02-02 18:22:21 +00:00
|
|
|
pub struct RecvCompletion<'r, 'a, 'p> {
|
2023-06-09 07:47:49 +00:00
|
|
|
transport: &'r mut Transport<'a>,
|
2023-04-24 21:41:16 +00:00
|
|
|
rx: Packet<'p>,
|
|
|
|
tx: Packet<'p>,
|
2023-02-02 18:22:21 +00:00
|
|
|
state: RecvState,
|
|
|
|
}
|
2022-12-27 09:32:52 +05:30
|
|
|
|
2023-02-02 18:22:21 +00:00
|
|
|
impl<'r, 'a, 'p> RecvCompletion<'r, 'a, 'p> {
|
|
|
|
pub fn next_action(&mut self) -> Result<Option<RecvAction<'_, 'p>>, Error> {
|
|
|
|
loop {
|
|
|
|
// Polonius will remove the need for unsafe one day
|
|
|
|
let this = unsafe { (self as *mut RecvCompletion).as_mut().unwrap() };
|
2022-12-27 09:32:52 +05:30
|
|
|
|
2023-02-02 18:22:21 +00:00
|
|
|
if let Some(action) = this.maybe_next_action()? {
|
|
|
|
return Ok(action);
|
|
|
|
}
|
|
|
|
}
|
2022-12-27 09:32:52 +05:30
|
|
|
}
|
|
|
|
|
2023-02-02 18:22:21 +00:00
|
|
|
fn maybe_next_action(&mut self) -> Result<Option<Option<RecvAction<'_, 'p>>>, Error> {
|
2023-06-09 07:47:49 +00:00
|
|
|
self.transport.exch_mgr.purge();
|
2023-04-28 10:42:55 +00:00
|
|
|
self.tx.reset();
|
2022-12-27 09:32:52 +05:30
|
|
|
|
2023-04-24 21:41:16 +00:00
|
|
|
let (state, next) = match core::mem::replace(&mut self.state, RecvState::New) {
|
2023-02-02 18:22:21 +00:00
|
|
|
RecvState::New => {
|
2023-06-09 07:47:49 +00:00
|
|
|
self.transport
|
|
|
|
.exch_mgr
|
|
|
|
.get_sess_mgr()
|
|
|
|
.decode(&mut self.rx)?;
|
2023-04-24 21:41:16 +00:00
|
|
|
(RecvState::OpenExchange, None)
|
2023-02-02 18:22:21 +00:00
|
|
|
}
|
2023-06-09 07:47:49 +00:00
|
|
|
RecvState::OpenExchange => match self.transport.exch_mgr.recv(&mut self.rx) {
|
2023-02-02 18:22:21 +00:00
|
|
|
Ok(Some(exch_ctx)) => {
|
|
|
|
if self.rx.get_proto_id() == PROTO_ID_SECURE_CHANNEL {
|
2023-04-24 21:41:16 +00:00
|
|
|
let mut proto_ctx = ProtoCtx::new(exch_ctx, &self.rx, &mut self.tx);
|
2023-02-02 18:22:21 +00:00
|
|
|
|
2023-06-09 07:47:49 +00:00
|
|
|
let mut secure_channel = SecureChannel::new(self.transport.matter);
|
|
|
|
|
|
|
|
let (reply, clone_data) = secure_channel.handle(&mut proto_ctx)?;
|
2023-02-02 18:22:21 +00:00
|
|
|
|
2023-04-24 21:41:16 +00:00
|
|
|
let state = if let Some(clone_data) = clone_data {
|
|
|
|
RecvState::AddSession(clone_data)
|
2023-04-24 09:00:08 +00:00
|
|
|
} else {
|
2023-04-24 21:41:16 +00:00
|
|
|
RecvState::Ack
|
|
|
|
};
|
|
|
|
|
|
|
|
if reply {
|
|
|
|
if proto_ctx.send()? {
|
|
|
|
(
|
|
|
|
state,
|
|
|
|
Some(Some(RecvAction::Send(self.tx.peer, self.tx.as_slice()))),
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
(state, None)
|
|
|
|
}
|
2023-02-02 18:22:21 +00:00
|
|
|
} else {
|
2023-04-24 21:41:16 +00:00
|
|
|
(state, None)
|
2023-02-02 18:22:21 +00:00
|
|
|
}
|
|
|
|
} else {
|
2023-04-24 21:41:16 +00:00
|
|
|
let proto_ctx = ProtoCtx::new(exch_ctx, &self.rx, &mut self.tx);
|
2023-02-02 18:22:21 +00:00
|
|
|
|
2023-04-24 21:41:16 +00:00
|
|
|
(RecvState::Ack, Some(Some(RecvAction::Interact(proto_ctx))))
|
2023-02-02 18:22:21 +00:00
|
|
|
}
|
|
|
|
}
|
2023-04-24 21:41:16 +00:00
|
|
|
Ok(None) => (RecvState::Ack, None),
|
2023-04-29 19:38:01 +03:00
|
|
|
Err(e) => match e.code() {
|
|
|
|
ErrorCode::Duplicate => (RecvState::Ack, None),
|
|
|
|
ErrorCode::NoSpace => (RecvState::EvictSession, None),
|
|
|
|
_ => Err(e)?,
|
|
|
|
},
|
2023-02-02 18:22:21 +00:00
|
|
|
},
|
2023-06-09 07:47:49 +00:00
|
|
|
RecvState::AddSession(clone_data) => {
|
|
|
|
match self.transport.exch_mgr.add_session(&clone_data) {
|
|
|
|
Ok(_) => (RecvState::Ack, None),
|
|
|
|
Err(e) => match e.code() {
|
|
|
|
ErrorCode::NoSpace => (RecvState::EvictSession2(clone_data), None),
|
|
|
|
_ => Err(e)?,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
2023-02-02 18:22:21 +00:00
|
|
|
RecvState::EvictSession => {
|
2023-06-09 07:47:49 +00:00
|
|
|
if self.transport.exch_mgr.evict_session(&mut self.tx)? {
|
2023-04-24 21:41:16 +00:00
|
|
|
(
|
|
|
|
RecvState::OpenExchange,
|
|
|
|
Some(Some(RecvAction::Send(self.tx.peer, self.tx.as_slice()))),
|
|
|
|
)
|
2023-04-24 11:34:32 +00:00
|
|
|
} else {
|
2023-04-24 21:41:16 +00:00
|
|
|
(RecvState::EvictSession, None)
|
2023-04-24 11:34:32 +00:00
|
|
|
}
|
2022-12-27 09:32:52 +05:30
|
|
|
}
|
2023-04-24 09:00:08 +00:00
|
|
|
RecvState::EvictSession2(clone_data) => {
|
2023-06-09 07:47:49 +00:00
|
|
|
if self.transport.exch_mgr.evict_session(&mut self.tx)? {
|
2023-04-24 21:41:16 +00:00
|
|
|
(
|
|
|
|
RecvState::AddSession(clone_data),
|
|
|
|
Some(Some(RecvAction::Send(self.tx.peer, self.tx.as_slice()))),
|
|
|
|
)
|
2023-04-24 11:34:32 +00:00
|
|
|
} else {
|
2023-04-24 21:41:16 +00:00
|
|
|
(RecvState::EvictSession2(clone_data), None)
|
2023-04-24 11:34:32 +00:00
|
|
|
}
|
2023-04-24 09:00:08 +00:00
|
|
|
}
|
2023-02-02 18:22:21 +00:00
|
|
|
RecvState::Ack => {
|
2023-06-09 07:47:49 +00:00
|
|
|
if let Some(exch_id) = self.transport.exch_mgr.pending_ack() {
|
2023-02-02 18:22:21 +00:00
|
|
|
info!("Sending MRP Standalone ACK for exch {}", exch_id);
|
|
|
|
|
2023-04-24 21:41:16 +00:00
|
|
|
ReliableMessage::prepare_ack(exch_id, &mut self.tx);
|
2023-02-02 18:22:21 +00:00
|
|
|
|
2023-06-09 07:47:49 +00:00
|
|
|
if self.transport.exch_mgr.send(exch_id, &mut self.tx)? {
|
2023-04-24 21:41:16 +00:00
|
|
|
(
|
|
|
|
RecvState::Ack,
|
|
|
|
Some(Some(RecvAction::Send(self.tx.peer, self.tx.as_slice()))),
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
(RecvState::Ack, None)
|
|
|
|
}
|
2023-02-02 18:22:21 +00:00
|
|
|
} else {
|
2023-04-24 21:41:16 +00:00
|
|
|
(RecvState::Ack, Some(None))
|
2023-02-02 18:22:21 +00:00
|
|
|
}
|
2022-12-27 09:32:52 +05:30
|
|
|
}
|
2023-04-24 21:41:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
self.state = state;
|
|
|
|
Ok(next)
|
2023-02-02 18:22:21 +00:00
|
|
|
}
|
|
|
|
}
|
2022-12-27 09:32:52 +05:30
|
|
|
|
2023-02-02 18:22:21 +00:00
|
|
|
enum NotifyState {}
|
2022-12-27 09:32:52 +05:30
|
|
|
|
2023-02-02 18:22:21 +00:00
|
|
|
pub enum NotifyAction<'r, 'p> {
|
|
|
|
Send(&'r [u8]),
|
|
|
|
Notify(ProtoCtx<'r, 'p>),
|
|
|
|
}
|
2022-12-27 09:32:52 +05:30
|
|
|
|
2023-02-02 18:22:21 +00:00
|
|
|
pub struct NotifyCompletion<'r, 'a, 'p> {
|
|
|
|
// TODO
|
2023-06-09 07:47:49 +00:00
|
|
|
_transport: &'r mut Transport<'a>,
|
2023-02-02 18:22:21 +00:00
|
|
|
_rx: &'r mut Packet<'p>,
|
|
|
|
_tx: &'r mut Packet<'p>,
|
|
|
|
_state: NotifyState,
|
|
|
|
}
|
2022-12-27 09:32:52 +05:30
|
|
|
|
2023-02-02 18:22:21 +00:00
|
|
|
impl<'r, 'a, 'p> NotifyCompletion<'r, 'a, 'p> {
|
|
|
|
pub fn next_action(&mut self) -> Result<Option<NotifyAction<'_, 'p>>, Error> {
|
|
|
|
loop {
|
|
|
|
// Polonius will remove the need for unsafe one day
|
|
|
|
let this = unsafe { (self as *mut NotifyCompletion).as_mut().unwrap() };
|
|
|
|
|
|
|
|
if let Some(action) = this.maybe_next_action()? {
|
|
|
|
return Ok(action);
|
2022-12-27 09:32:52 +05:30
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-02 18:22:21 +00:00
|
|
|
fn maybe_next_action(&mut self) -> Result<Option<Option<NotifyAction<'_, 'p>>>, Error> {
|
|
|
|
Ok(Some(None)) // TODO: Future
|
|
|
|
}
|
|
|
|
}
|
2022-12-27 09:32:52 +05:30
|
|
|
|
2023-06-09 07:47:49 +00:00
|
|
|
pub struct Transport<'a> {
|
|
|
|
matter: &'a Matter<'a>,
|
2023-02-02 18:22:21 +00:00
|
|
|
exch_mgr: exchange::ExchangeMgr,
|
|
|
|
}
|
2022-12-27 09:32:52 +05:30
|
|
|
|
2023-06-09 07:47:49 +00:00
|
|
|
impl<'a> Transport<'a> {
|
|
|
|
#[inline(always)]
|
|
|
|
pub fn new(matter: &'a Matter<'a>) -> Self {
|
|
|
|
let epoch = matter.epoch;
|
|
|
|
let rand = matter.rand;
|
2022-12-27 09:32:52 +05:30
|
|
|
|
2023-02-02 18:22:21 +00:00
|
|
|
Self {
|
2023-06-09 07:47:49 +00:00
|
|
|
matter,
|
2023-02-02 18:22:21 +00:00
|
|
|
exch_mgr: exchange::ExchangeMgr::new(epoch, rand),
|
|
|
|
}
|
|
|
|
}
|
2022-12-27 09:32:52 +05:30
|
|
|
|
2023-06-09 07:47:49 +00:00
|
|
|
pub fn matter(&self) -> &Matter<'a> {
|
|
|
|
&self.matter
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn start(&mut self, dev_comm: CommissioningData, buf: &mut [u8]) -> Result<(), Error> {
|
|
|
|
info!("Starting Matter transport");
|
|
|
|
|
|
|
|
if self.matter().start_comissioning(dev_comm, buf)? {
|
|
|
|
info!("Comissioning started");
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2023-02-02 18:22:21 +00:00
|
|
|
pub fn recv<'r, 'p>(
|
|
|
|
&'r mut self,
|
2023-04-24 11:34:32 +00:00
|
|
|
addr: Address,
|
2023-04-24 21:41:16 +00:00
|
|
|
rx_buf: &'p mut [u8],
|
|
|
|
tx_buf: &'p mut [u8],
|
2023-02-02 18:22:21 +00:00
|
|
|
) -> RecvCompletion<'r, 'a, 'p> {
|
2023-04-24 21:41:16 +00:00
|
|
|
let mut rx = Packet::new_rx(rx_buf);
|
|
|
|
let tx = Packet::new_tx(tx_buf);
|
|
|
|
|
|
|
|
rx.peer = addr;
|
|
|
|
|
2023-02-02 18:22:21 +00:00
|
|
|
RecvCompletion {
|
2023-06-09 07:47:49 +00:00
|
|
|
transport: self,
|
2023-02-02 18:22:21 +00:00
|
|
|
rx,
|
|
|
|
tx,
|
|
|
|
state: RecvState::New,
|
2022-12-27 09:32:52 +05:30
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-02 18:22:21 +00:00
|
|
|
pub fn notify(&mut self, _tx: &mut Packet) -> Result<bool, Error> {
|
|
|
|
Ok(false)
|
2022-12-27 09:32:52 +05:30
|
|
|
}
|
|
|
|
}
|