Merge pull request #80 from kedars/bugfix/ios_support

Support Attributes of Nw Commissioning Cluster
This commit is contained in:
Kedar Sovani 2023-08-01 14:01:05 +05:30 committed by GitHub
commit e02b316030
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 132 additions and 6 deletions

View file

@ -40,9 +40,12 @@ bitflags! {
const READ_PRIVILEGE_MASK = Self::NEED_VIEW.bits | Self::NEED_MANAGE.bits | Self::NEED_OPERATE.bits | Self::NEED_ADMIN.bits;
const WRITE_PRIVILEGE_MASK = Self::NEED_MANAGE.bits | Self::NEED_OPERATE.bits | Self::NEED_ADMIN.bits;
const RV = Self::READ.bits | Self::NEED_VIEW.bits;
const RF = Self::READ.bits | Self::FAB_SCOPED.bits;
const RA = Self::READ.bits | Self::NEED_ADMIN.bits;
const RWVA = Self::READ.bits | Self::WRITE.bits | Self::NEED_VIEW.bits | Self::NEED_ADMIN.bits;
const RWFA = Self::READ.bits | Self::WRITE.bits | Self::FAB_SCOPED.bits | Self::NEED_ADMIN.bits;
const RWVM = Self::READ.bits | Self::WRITE.bits | Self::NEED_VIEW.bits | Self::NEED_MANAGE.bits;
const RWFVM = Self::READ.bits | Self::WRITE.bits | Self::FAB_SCOPED.bits |Self::NEED_VIEW.bits | Self::NEED_MANAGE.bits;
}
}
@ -79,6 +82,10 @@ bitflags! {
const NULLABLE = 0x08; // Short: X
const SN = Self::SCENE.bits | Self::PERSISTENT.bits;
const S = Self::SCENE.bits;
const N = Self::PERSISTENT.bits;
const F = Self::FIXED.bits;
const X = Self::NULLABLE.bits;
}
}

View file

@ -15,17 +15,35 @@
* limitations under the License.
*/
use strum::FromRepr;
use crate::{
attribute_enum,
data_model::objects::{
AttrDataEncoder, AttrDetails, ChangeNotifier, Cluster, Dataver, Handler,
NonBlockingHandler, ATTRIBUTE_LIST, FEATURE_MAP,
Access, AttrDataEncoder, AttrDataWriter, AttrDetails, AttrType, Attribute, ChangeNotifier,
Cluster, Dataver, Handler, NonBlockingHandler, Quality, ATTRIBUTE_LIST, FEATURE_MAP,
},
error::{Error, ErrorCode},
error::Error,
tlv::{OctetStr, TLVWriter, TagType, ToTLV},
utils::rand::Rand,
};
pub const ID: u32 = 0x0031;
#[derive(FromRepr)]
#[repr(u16)]
pub enum Attributes {
MaxNetworks = 0x00,
Networks = 0x01,
ConnectMaxTimeSecs = 0x03,
InterfaceEnabled = 0x04,
LastNetworkingStatus = 0x05,
LastNetworkID = 0x06,
LastConnectErrorValue = 0x07,
}
attribute_enum!(Attributes);
enum FeatureMap {
_Wifi = 0x01,
_Thread = 0x02,
@ -35,7 +53,33 @@ enum FeatureMap {
pub const CLUSTER: Cluster<'static> = Cluster {
id: ID as _,
feature_map: FeatureMap::Ethernet as _,
attributes: &[FEATURE_MAP, ATTRIBUTE_LIST],
attributes: &[
FEATURE_MAP,
ATTRIBUTE_LIST,
Attribute::new(Attributes::MaxNetworks as u16, Access::RA, Quality::F),
Attribute::new(Attributes::Networks as u16, Access::RA, Quality::NONE),
Attribute::new(
Attributes::ConnectMaxTimeSecs as u16,
Access::RV,
Quality::F,
),
Attribute::new(
Attributes::InterfaceEnabled as u16,
Access::RWVA,
Quality::N,
),
Attribute::new(
Attributes::LastNetworkingStatus as u16,
Access::RA,
Quality::X,
),
Attribute::new(Attributes::LastNetworkID as u16, Access::RA, Quality::X),
Attribute::new(
Attributes::LastConnectErrorValue as u16,
Access::RA,
Quality::X,
),
],
commands: &[],
};
@ -49,15 +93,90 @@ impl NwCommCluster {
data_ver: Dataver::new(rand),
}
}
fn get_network_info(&self) -> NwMetaInfo<'static> {
// Only single, Ethernet, supported for now
let nw_info = NwInfo {
network_id: OctetStr::new(b"en0"),
connected: true,
};
NwMetaInfo {
nw_info,
connect_max_time_secs: 60,
interface_enabled: true,
last_nw_status: NetworkCommissioningStatus::Success,
}
}
}
#[derive(ToTLV)]
struct NwInfo<'a> {
network_id: OctetStr<'a>,
connected: bool,
}
struct NwMetaInfo<'a> {
nw_info: NwInfo<'a>,
connect_max_time_secs: u8,
interface_enabled: bool,
last_nw_status: NetworkCommissioningStatus,
}
#[allow(dead_code)]
enum NetworkCommissioningStatus {
Success = 0,
OutOfRange = 1,
BoundsExceeded = 2,
NetworkIDNotFound = 3,
DuplicateNetworkID = 4,
NetworkNotFound = 5,
RegulatoryError = 6,
AuthFailure = 7,
UnsupportedSecurity = 8,
OtherConnectionFailure = 9,
IPV6Failed = 10,
IPBindFailed = 11,
UnknownError = 12,
}
impl Handler for NwCommCluster {
fn read(&self, attr: &AttrDetails, encoder: AttrDataEncoder) -> Result<(), Error> {
if let Some(writer) = encoder.with_dataver(self.data_ver.get())? {
let info = self.get_network_info();
if let Some(mut writer) = encoder.with_dataver(self.data_ver.get())? {
if attr.is_system() {
CLUSTER.read(attr.attr_id, writer)
} else {
Err(ErrorCode::AttributeNotFound.into())
match attr.attr_id.try_into()? {
Attributes::MaxNetworks => AttrType::<u8>::new().encode(writer, 1),
Attributes::Networks => {
writer.start_array(AttrDataWriter::TAG)?;
info.nw_info.to_tlv(&mut writer, TagType::Anonymous)?;
writer.end_container()?;
writer.complete()
}
Attributes::ConnectMaxTimeSecs => {
AttrType::<u8>::new().encode(writer, info.connect_max_time_secs)
}
Attributes::InterfaceEnabled => {
AttrType::<bool>::new().encode(writer, info.interface_enabled)
}
Attributes::LastNetworkingStatus => {
AttrType::<u8>::new().encode(writer, info.last_nw_status as u8)
}
Attributes::LastNetworkID => {
info.nw_info
.network_id
.to_tlv(&mut writer, AttrDataWriter::TAG)?;
writer.complete()
}
Attributes::LastConnectErrorValue => {
writer.null(AttrDataWriter::TAG)?;
writer.complete()
}
}
}
} else {
Ok(())