Merge pull request #80 from kedars/bugfix/ios_support
Support Attributes of Nw Commissioning Cluster
This commit is contained in:
		
						commit
						e02b316030
					
				
					 2 changed files with 132 additions and 6 deletions
				
			
		| 
						 | 
					@ -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 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 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 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 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 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 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 NULLABLE = 0x08;   // Short: X
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const SN = Self::SCENE.bits | Self::PERSISTENT.bits;
 | 
					        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;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,17 +15,35 @@
 | 
				
			||||||
 *    limitations under the License.
 | 
					 *    limitations under the License.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use strum::FromRepr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::{
 | 
					use crate::{
 | 
				
			||||||
 | 
					    attribute_enum,
 | 
				
			||||||
    data_model::objects::{
 | 
					    data_model::objects::{
 | 
				
			||||||
        AttrDataEncoder, AttrDetails, ChangeNotifier, Cluster, Dataver, Handler,
 | 
					        Access, AttrDataEncoder, AttrDataWriter, AttrDetails, AttrType, Attribute, ChangeNotifier,
 | 
				
			||||||
        NonBlockingHandler, ATTRIBUTE_LIST, FEATURE_MAP,
 | 
					        Cluster, Dataver, Handler, NonBlockingHandler, Quality, ATTRIBUTE_LIST, FEATURE_MAP,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    error::{Error, ErrorCode},
 | 
					    error::Error,
 | 
				
			||||||
 | 
					    tlv::{OctetStr, TLVWriter, TagType, ToTLV},
 | 
				
			||||||
    utils::rand::Rand,
 | 
					    utils::rand::Rand,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub const ID: u32 = 0x0031;
 | 
					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 {
 | 
					enum FeatureMap {
 | 
				
			||||||
    _Wifi = 0x01,
 | 
					    _Wifi = 0x01,
 | 
				
			||||||
    _Thread = 0x02,
 | 
					    _Thread = 0x02,
 | 
				
			||||||
| 
						 | 
					@ -35,7 +53,33 @@ enum FeatureMap {
 | 
				
			||||||
pub const CLUSTER: Cluster<'static> = Cluster {
 | 
					pub const CLUSTER: Cluster<'static> = Cluster {
 | 
				
			||||||
    id: ID as _,
 | 
					    id: ID as _,
 | 
				
			||||||
    feature_map: FeatureMap::Ethernet 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: &[],
 | 
					    commands: &[],
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,15 +93,90 @@ impl NwCommCluster {
 | 
				
			||||||
            data_ver: Dataver::new(rand),
 | 
					            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 {
 | 
					impl Handler for NwCommCluster {
 | 
				
			||||||
    fn read(&self, attr: &AttrDetails, encoder: AttrDataEncoder) -> Result<(), Error> {
 | 
					    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() {
 | 
					            if attr.is_system() {
 | 
				
			||||||
                CLUSTER.read(attr.attr_id, writer)
 | 
					                CLUSTER.read(attr.attr_id, writer)
 | 
				
			||||||
            } else {
 | 
					            } 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 {
 | 
					        } else {
 | 
				
			||||||
            Ok(())
 | 
					            Ok(())
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue