bucky_objects/objects/
device.rs

1use crate::*;
2
3use std::convert::TryFrom;
4
5//分类:OOD、server、pc、路由器、android mobile、android pad、android watch、Android  TV
6//    iOS mobile、iOS pad、iOS watch、
7//    智能音箱
8//    浏览器
9//    IoT 传感器
10//    智能家具设备
11#[repr(u8)]
12#[derive(Eq, PartialEq, Debug, Clone, Copy)]
13pub enum DeviceCategory {
14    OOD = 0,
15    Server = 1,
16    PC = 2,
17    Router = 3,
18    AndroidMobile = 4,
19    AndroidPad = 5,
20    AndroidWatch = 6,
21    AndroidTV = 7,
22    IOSMobile = 8,
23    IOSPad = 9,
24    IOSWatch = 10,
25    SmartSpeakers = 11,
26    Browser = 12,
27    IoT = 13,
28    SmartHome = 14,
29    VirtualOOD = 15,
30    Unknown = 255,
31}
32
33impl TryFrom<u8> for DeviceCategory {
34    type Error = BuckyError;
35
36    fn try_from(value: u8) -> Result<Self, Self::Error> {
37        match value {
38            0u8 => Ok(DeviceCategory::OOD),
39            1u8 => Ok(DeviceCategory::Server),
40            2u8 => Ok(DeviceCategory::PC),
41            3u8 => Ok(DeviceCategory::Router),
42            4u8 => Ok(DeviceCategory::AndroidMobile),
43            5u8 => Ok(DeviceCategory::AndroidPad),
44            6u8 => Ok(DeviceCategory::AndroidWatch),
45            7u8 => Ok(DeviceCategory::AndroidTV),
46            8u8 => Ok(DeviceCategory::IOSMobile),
47            9u8 => Ok(DeviceCategory::IOSPad),
48            10u8 => Ok(DeviceCategory::IOSWatch),
49            11u8 => Ok(DeviceCategory::SmartSpeakers),
50            12u8 => Ok(DeviceCategory::Browser),
51            13u8 => Ok(DeviceCategory::IoT),
52            14u8 => Ok(DeviceCategory::SmartHome),
53            15u8 => Ok(DeviceCategory::VirtualOOD),
54            v @ _ => {
55                error!("unknown device category: {}", v);
56                Err(BuckyError::from(BuckyErrorCode::InvalidFormat))
57            }
58        }
59    }
60}
61
62impl std::fmt::Display for DeviceCategory {
63    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64        match self {
65            DeviceCategory::OOD => write!(f, "OOD"),
66            DeviceCategory::Server => write!(f, "Server"),
67            DeviceCategory::PC => write!(f, "PC"),
68            DeviceCategory::Router => write!(f, "Router"),
69            DeviceCategory::AndroidMobile => write!(f, "AndroidMobile"),
70            DeviceCategory::AndroidPad => write!(f, "AndroidPad"),
71            DeviceCategory::AndroidWatch => write!(f, "AndroidWatch"),
72            DeviceCategory::AndroidTV => write!(f, "AndroidTV"),
73            DeviceCategory::IOSMobile => write!(f, "IOSMobile"),
74            DeviceCategory::IOSPad => write!(f, "IOSPad"),
75            DeviceCategory::IOSWatch => write!(f, "IOSWatch"),
76            DeviceCategory::SmartSpeakers => write!(f, "SmartSpeakers"),
77            DeviceCategory::Browser => write!(f, "Browser"),
78            DeviceCategory::IoT => write!(f, "IoT"),
79            DeviceCategory::SmartHome => write!(f, "SmartHome"),
80            DeviceCategory::VirtualOOD => write!(f, "VirtualOOD"),
81            DeviceCategory::Unknown => write!(f, "Unknown"),
82        }
83    }
84}
85
86#[derive(Clone, Debug, Eq, PartialEq)]
87pub struct DeviceDescContent {
88    unique_id: UniqueId,
89}
90
91impl DeviceDescContent {
92    pub fn new(unique_id: UniqueId) -> Self {
93        Self { unique_id }
94    }
95
96    pub fn unique_id(&self) -> &UniqueId {
97        &self.unique_id
98    }
99}
100
101impl DescContent for DeviceDescContent {
102    fn obj_type() -> u16 {
103        ObjectTypeCode::Device.into()
104    }
105
106    type OwnerType = Option<ObjectId>;
107    type AreaType = Option<Area>;
108    type AuthorType = SubDescNone;
109    type PublicKeyType = PublicKey;
110}
111
112impl RawEncode for DeviceDescContent {
113    fn raw_measure(&self, purpose: &Option<RawEncodePurpose>) -> Result<usize, BuckyError> {
114        let size = self.unique_id.raw_measure(purpose).map_err(|e| {
115            log::error!("DeviceDescContent::raw_measure error:{}", e);
116            e
117        })?;
118        Ok(size)
119    }
120
121    fn raw_encode<'a>(
122        &self,
123        buf: &'a mut [u8],
124        purpose: &Option<RawEncodePurpose>,
125    ) -> Result<&'a mut [u8], BuckyError> {
126        let size = self.raw_measure(purpose).unwrap();
127        if buf.len() < size {
128            return Err(BuckyError::new(
129                BuckyErrorCode::OutOfLimit,
130                format!("[raw_encode] not enough buffer for DeviceDescContent, except {}, actual {}", size, buf.len()),
131            ));
132        }
133
134        let buf = self.unique_id.raw_encode(buf, purpose).map_err(|e| {
135            log::error!("DeviceDescContent::raw_encode error:{}", e);
136            e
137        })?;
138
139        Ok(buf)
140    }
141}
142
143impl<'de> RawDecode<'de> for DeviceDescContent {
144    fn raw_decode(buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])> {
145        let (unique_id, buf) = UniqueId::raw_decode(buf).map_err(|e| {
146            log::error!("DeviceDescContent::raw_decode error:{}", e);
147            e
148        })?;
149        Ok((Self { unique_id }, buf))
150    }
151}
152
153#[derive(Clone, Debug, Eq, PartialEq)]
154pub struct DeviceBodyContent {
155    endpoints: Vec<Endpoint>,
156    sn_list: Vec<DeviceId>,
157    passive_pn_list: Vec<DeviceId>,
158    name: Option<String>,
159    bdt_version: Option<u8>,
160}
161
162// body使用protobuf编解码
163impl BodyContent for DeviceBodyContent {
164    fn format(&self) -> u8 {
165        OBJECT_CONTENT_CODEC_FORMAT_PROTOBUF
166    }
167}
168
169impl std::fmt::Display for DeviceBodyContent {
170    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
171        write!(f, "DeviceBodyContent:{{name:{:?},endpoints:[", self.name()).map_err(|e| {
172            log::error!("DeviceBodyContent::fmt error:{}", e);
173            e
174        })?;
175        for ep in self.endpoints() {
176            write!(f, "{},", ep).map_err(|e| {
177                log::error!("DeviceBodyContent::fmt endpoint error:{}", e);
178                e
179            })?;
180        }
181        write!(f, "],sn_list:[").map_err(|e| {
182            log::error!("DeviceBodyContent::fmt sn_list error:{}", e);
183            e
184        })?;
185        for id in self.sn_list() {
186            write!(f, "{},", id).map_err(|e| {
187                log::error!("DeviceBodyContent::fmt sn_list error:{}", e);
188                e
189            })?;
190        }
191        write!(f, "]}}")
192    }
193}
194
195impl Default for DeviceBodyContent {
196    fn default() -> Self {
197        Self {
198            endpoints: Vec::new(),
199            sn_list: Vec::new(),
200            passive_pn_list: Vec::new(),
201            name: None,
202            bdt_version: None,
203        }
204    }
205}
206
207impl DeviceBodyContent {
208    pub fn new(
209        endpoints: Vec<Endpoint>,
210        sn_list: Vec<DeviceId>,
211        passive_pn_list: Vec<DeviceId>,
212        name: Option<String>,
213        bdt_version: Option<u8>,
214    ) -> Self {
215        Self {
216            endpoints,
217            sn_list,
218            passive_pn_list,
219            name,
220            bdt_version,
221        }
222    }
223
224    pub fn endpoints(&self) -> &Vec<Endpoint> {
225        &self.endpoints
226    }
227
228    pub fn sn_list(&self) -> &Vec<DeviceId> {
229        &self.sn_list
230    }
231
232    pub fn passive_pn_list(&self) -> &Vec<DeviceId> {
233        &self.passive_pn_list
234    }
235
236    pub fn mut_endpoints(&mut self) -> &mut Vec<Endpoint> {
237        &mut self.endpoints
238    }
239
240    pub fn mut_sn_list(&mut self) -> &mut Vec<DeviceId> {
241        &mut self.sn_list
242    }
243
244    pub fn mut_passive_pn_list(&mut self) -> &mut Vec<DeviceId> {
245        &mut self.passive_pn_list
246    }
247
248    pub fn name(&self) -> Option<&str> {
249        self.name.as_ref().map(|f| f.as_str())
250    }
251    pub fn set_name(&mut self, name: Option<String>) {
252        self.name = name
253    }
254
255    pub fn bdt_version(&self) -> Option<u8> {self.bdt_version}
256    pub fn set_bdt_version(&mut self, bdt_version: Option<u8>) {self.bdt_version = bdt_version}
257}
258
259// protos编解码
260impl TryFrom<&DeviceBodyContent> for protos::DeviceBodyContent {
261    type Error = BuckyError;
262
263    fn try_from(value: &DeviceBodyContent) -> BuckyResult<Self> {
264        let mut ret = protos::DeviceBodyContent::new();
265
266        ret.set_endpoints(ProtobufCodecHelper::encode_buf_list(&value.endpoints)?);
267        ret.set_sn_list(ProtobufCodecHelper::encode_buf_list(&value.sn_list)?);
268        ret.set_passive_pn_list(ProtobufCodecHelper::encode_buf_list(
269            &value.passive_pn_list,
270        )?);
271
272        if let Some(name) = &value.name {
273            ret.set_name(name.to_owned());
274        }
275
276        if let Some(bdt_version) = value.bdt_version {
277            ret.set_bdt_version(bdt_version as u32);
278        }
279
280        Ok(ret)
281    }
282}
283
284impl TryFrom<protos::DeviceBodyContent> for DeviceBodyContent {
285    type Error = BuckyError;
286
287    fn try_from(mut value: protos::DeviceBodyContent) -> BuckyResult<Self> {
288        let mut ret = Self {
289            endpoints: ProtobufCodecHelper::decode_buf_list(value.take_endpoints())?,
290            sn_list: ProtobufCodecHelper::decode_buf_list(value.take_sn_list())?,
291            passive_pn_list: ProtobufCodecHelper::decode_buf_list(value.take_passive_pn_list())?,
292            name: None,
293            bdt_version: None,
294        };
295
296        if value.has_name() {
297            ret.name = Some(value.take_name());
298        }
299
300        if value.has_bdt_version() {
301            ret.bdt_version = Some(value.get_bdt_version() as u8);
302        }
303
304        Ok(ret)
305    }
306}
307
308crate::inner_impl_default_protobuf_raw_codec!(DeviceBodyContent);
309
310pub type DeviceType = NamedObjType<DeviceDescContent, DeviceBodyContent>;
311pub type DeviceBuilder = NamedObjectBuilder<DeviceDescContent, DeviceBodyContent>;
312
313pub type DeviceId = NamedObjectId<DeviceType>;
314pub type DeviceDesc = NamedObjectDesc<DeviceDescContent>;
315pub type Device = NamedObjectBase<DeviceType>;
316
317impl DeviceDesc {
318    pub fn device_id(&self) -> DeviceId {
319        DeviceId::try_from(self.calculate_id()).unwrap()
320    }
321
322    pub fn unique_id(&self) -> &UniqueId {
323        &self.content().unique_id
324    }
325}
326
327impl Device {
328    pub fn new(
329        owner: Option<ObjectId>,
330        unique_id: UniqueId,
331        endpoints: Vec<Endpoint>,
332        sn_list: Vec<DeviceId>,
333        passive_pn_list: Vec<DeviceId>,
334        public_key: PublicKey,
335        area: Area,
336        category: DeviceCategory,
337    ) -> DeviceBuilder {
338        let desc_content = DeviceDescContent::new(unique_id);
339
340        let body_content = DeviceBodyContent::new(endpoints, sn_list, passive_pn_list, None, None);
341        let mut real_area = area.clone();
342        real_area.inner = category as u8;
343
344        DeviceBuilder::new(desc_content, body_content)
345            .public_key(public_key)
346            .area(real_area)
347            .option_owner(owner)
348    }
349
350    pub fn connect_info(&self) -> &DeviceBodyContent {
351        self.body().as_ref().unwrap().content()
352    }
353
354    pub fn mut_connect_info(&mut self) -> &mut DeviceBodyContent {
355        self.body_mut().as_mut().unwrap().content_mut()
356    }
357
358    pub fn name(&self) -> Option<&str> {
359        self.body().as_ref().unwrap().content().name()
360    }
361
362    pub fn set_name(&mut self, name: Option<String>) {
363        self.body_mut()
364            .as_mut()
365            .unwrap()
366            .content_mut()
367            .set_name(name)
368    }
369
370    pub fn bdt_version(&self) -> Option<u8> {
371        self.body().as_ref().unwrap().content().bdt_version()
372    }
373
374    pub fn set_bdt_version(&mut self, bdt_version: Option<u8>) {
375        self.body_mut()
376            .as_mut()
377            .unwrap()
378            .content_mut()
379            .set_bdt_version(bdt_version)
380    }
381
382    pub fn category(&self) -> BuckyResult<DeviceCategory> {
383        match DeviceCategory::try_from(self.desc().area().as_ref().unwrap().inner) {
384            Ok(category) => Ok(category),
385            Err(_) => {
386                Ok(DeviceCategory::Unknown)
387            }
388        }
389    }
390
391    pub fn has_wan_endpoint(&self) -> bool {
392        match self.body() {
393            Some(body) => {
394                for ep in body.content().endpoints() {
395                    if ep.is_mapped_wan() {
396                        return true;
397                    }
398                }
399
400                false
401            }
402            None => false,
403        }
404    }
405}
406
407impl RawMergable for Device {
408    fn raw_merge_ok(&self, other: &Self) -> bool {
409        self.desc().device_id() == other.desc().device_id()
410    }
411}
412
413#[cfg(test)]
414mod test {
415    use crate::*;
416    use std::str::FromStr;
417
418    use std::convert::TryFrom;
419    use hex::encode;
420    //use std::path::Path;
421
422    #[test]
423    fn test_decode() {
424        // let device = "0001580e4800000000857283dc484f7a184c158fa8e2deec97145ca5b8d0fd0bd6de4057e2000d5e02010030818902818100b96dad4eee3ff9ec6b666595e2c3767b2d1f67007147d48962f1ff545e476585ce7b38513d35c6d835f6ccc5b2728de64b569df33f5f0a11c906cf7db6cbcea68e36f0ceb1e485a085991c7a7aaab0f0deafc0b44035a9fec7041f5177ba3fd545f898b8149b287cef15cb7984047114a83245521f3d4947812a9bace47d1d350203010001000000000000000000000000000000000000000000000000001069f84401d28397116f58a580b99d437900002f3e1afce634ec0001408b0a070a721fc0a864100a070c721fc0a864100a1312721f000000000000000000000000000000000a1314721f00000000000000000000000000000000122044000000010f6bb5a1f53156de084c5f116f8c60aba978dbc5752e81cb2ce07f1a2044000000019ab0d16fabaece45f63e77f715e102c925d7db23ff68b572ad4ca52209302d52756e74696d65010000002f3e0f2dd0a37d002f7977a55ef776a8a892b8ab73da95acdb1352825024de84b39fa215ab5a46bf573513251acf4b27927978c75f51cbfc6d0f7914456bb48c382487eb99f1f056d9f72082cb0da823a9a3ebb445aa450be78b0121bcecec311b26ac03612130c4eb2d1b51e90b59c8da5081865456a0a803a2838fdcd43078b08c1db86ddd0f06010000002f3e0f2dd0a47d008ac5f0a2384ab0814b37d45ede8c0f37aea9d44160e274fb9f964b2afd6a29508547a3de179f8fac518d152006209d6702a2ae13e813ca9f67b3fc64cc21a4ffce76062c74af0a12bc54b26d884f321a9b2c2b91dc07db3b2a5dc46f6687d020f460d58b990ecd9dbadf020ca9fd91299b2dd0aebbb4e6913e49d64e6e721b2a";
425        // let device = "0001580e4800000000857283dc484f7a184c158fa8e2deec97145ca5b8d0fd0bd6de4057e2000d5e02010030818902818100b96dad4eee3ff9ec6b666595e2c3767b2d1f67007147d48962f1ff545e476585ce7b38513d35c6d835f6ccc5b2728de64b569df33f5f0a11c906cf7db6cbcea68e36f0ceb1e485a085991c7a7aaab0f0deafc0b44035a9fec7041f5177ba3fd545f898b8149b287cef15cb7984047114a83245521f3d4947812a9bace47d1d350203010001000000000000000000000000000000000000000000000000001069f84401d28397116f58a580b99d437900002f3e1ad112fd9c000140690a070a721fc0a864100a1312721f000000000000000000000000000000000a070c721fc0a864100a1314721f00000000000000000000000000000000122044000000010f6bb5a1f53156de084c5f116f8c60aba978dbc5752e81cb2ce07f2209302d52756e74696d65010000002f3e0f2dd0a37d002f7977a55ef776a8a892b8ab73da95acdb1352825024de84b39fa215ab5a46bf573513251acf4b27927978c75f51cbfc6d0f7914456bb48c382487eb99f1f056d9f72082cb0da823a9a3ebb445aa450be78b0121bcecec311b26ac03612130c4eb2d1b51e90b59c8da5081865456a0a803a2838fdcd43078b08c1db86ddd0f06010000002f3e0f2dd0a47d008ac5f0a2384ab0814b37d45ede8c0f37aea9d44160e274fb9f964b2afd6a29508547a3de179f8fac518d152006209d6702a2ae13e813ca9f67b3fc64cc21a4ffce76062c74af0a12bc54b26d884f321a9b2c2b91dc07db3b2a5dc46f6687d020f460d58b990ecd9dbadf020ca9fd91299b2dd0aebbb4e6913e49d64e6e721b2a";
426        let old_str = "00015a0e002f4943def944e94800000000e471f8f0e4069b9ec1f04a5e652a9bcb30432d50416468d744a0c700000000000100308189028181009cf42aa4b1c72607dca379fff9f57101521c3b6ef83400eca478083e27542c74a5a3ab4320e7a3e270977747e0e4a86b78304f103557fc8acdb9a5413e6b663fb52baa7b0b86c9513cb805dd776ea72fb6e2a22272363a4976429d20dc819f984a0d2f3ca41d3fa508dd90acad6bb711bb9537371b2e77f9e604873769ea50f3020301000100000000000000000000000000000000000000000000000000100000000000000000000000000000000000002f4943def944eb0001090a07090000000000000100fe002f4943defc32c600079f4ba67290707f9757e5f3ffa9c64c537fbd2b9cf3f13e27c0b7bd3000e93a399044736a0c8b0ce42e0bd783d937a5d53f7e5a92a9f78a2c1054e80a1e6a084d7ea05974cbb02ec3199eb04894b860645c56451b74652fd9e168c5a6e02a446d008f74985ce8efd51827744f7ed3a143c519d0e369b5176dabc44c53e7f22b0100fe002f4943defc59d20007d5c812c7814a6a921d6fdd480c7a07d7e3f5ffcf4f38921732c0c3d46c52173e193d0a7aa0ce28fc29c177dad7350f01587121309140809d8fca75e885eb44b8dc2cce62afd3a2579427182f1b3dc836e87710a17912e9457853e59b2ad1bea38105a8a84a4108de444bae097d7e52545b67dbbb7b31f59bdf653ee5374e69";
427        {
428            let device = "0001580e4800000000661456d9a5d0503f01cbca7dc66dea0d4de188f44a3751ee66d0230000000000010a027fee89e7e40d2f9544683e480d28575794f56013a49d81b119ce3b84ff29e761000000107e8397450134fdbf16e62a576a32e35900002f4b38abe31967000140680a070a1481c0a838010a070a1481c0a864ed0a070c1481c0a838010a070c1481c0a864ed12204400000001d707019d5593b7e33a6acf5c2beb475df3feffecee8acadb8f0b741a204400000001ecdeb526690e03f1feb00d51796cc7cca0eac8a1f06915780163360100fe002f4b38abc85cb0055c4f938cd5ee2f303909cb4556d5b8033c48e69db17308d01e886e823111002645f936ed188cb9848452b9fec239f5fc8394110421ff440007b51f3e676fa2f10100ff002f4b38abe3197405863ac70379ab5cddec296d5ca292a918815e59741b22bbc8e24765d6feb25e2940c15a24979fe71ba97ffa754c405449ba64cc8a79034b579703f2fd0054b0dd";
429
430            let mut buf = vec![];
431            let d = Device::clone_from_hex(&device, &mut buf).unwrap();
432            println!("{}", d.desc().public_key().key_type_str());
433
434            d.to_vec().unwrap();
435            let id = d.desc().device_id();
436            println!("{}", id);
437        }
438
439        let mut buf = vec![];
440        let device = Device::clone_from_hex(old_str, &mut buf).unwrap();
441        let new_device = device.to_vec().unwrap();
442        let new_str = encode(new_device);
443        for i in 0 .. old_str.len() {
444            if old_str.as_bytes()[i] != new_str.as_bytes()[i] {
445                println!("{}, {:#x}!={:#x}", i, old_str.as_bytes()[i], new_str.as_bytes()[i]);
446            }
447        }
448        assert_eq!(old_str, new_str);
449    }
450
451    #[test]
452    fn device_load_test() {
453        let root = std::env::current_dir().unwrap();
454        let p = root.join("../../../util/peers/sn-miner.desc");
455        if p.exists() {
456            let mut v = Vec::<u8>::new();
457            let (device, _) = Device::decode_from_file(&p, &mut v).unwrap();
458            println!("{:?}", device);
459
460            let v = device
461                .body_expect("sssss")
462                .content()
463                .sn_list
464                .get(0)
465                .unwrap()
466                .object_id()
467                .as_slice();
468            println!("snlist 0 {:?}", v);
469
470            let v = device.desc().public_key().to_vec().unwrap();
471            println!("public key {:?}, len:{}", v, v.len());
472        }
473    }
474
475    #[test]
476    fn device() {
477        let area = Area::new(0, 0, 0, 0);
478
479        let private_key = PrivateKey::generate_rsa(1024).unwrap();
480
481        let pubic_key = private_key.public();
482        let device_public_key = pubic_key.clone();
483
484        // {
485        //     let size = pubic_key.raw_measure(purpose).unwrap();
486        //     let mut encod_buf = vec![0u8;size];
487        //     let buf = pubic_key.raw_encode(& mut encod_buf).unwrap();
488
489        //     let (d,buf) = PublicKey::raw_decode(&encod_buf).unwrap();
490        // }
491
492        let endpoints = vec![Endpoint::default()];
493        let sn_list = vec![];
494
495        // {
496        //     let size = endpoints.raw_measure(purpose).unwrap();
497        //     let mut encod_buf = vec![0u8;size];
498        //     let buf = endpoints.raw_encode(& mut encod_buf).unwrap();
499
500        //     let (d,buf) = Vec::<Endpoint>::raw_decode(&encod_buf).unwrap();
501        // }
502
503        let sn_unique_id = UniqueId::default();
504        let _btc_hash_value = Some(HashValue::default());
505        let sn_1 = Device::new(
506            Some(ObjectId::default()),
507            sn_unique_id,
508            endpoints,
509            sn_list,
510            Vec::new(),
511            pubic_key,
512            area,
513            DeviceCategory::Server,
514        )
515        .build();
516
517        let sn_1_deviceid = sn_1.desc().calculate_id();
518
519        println!("an sn device, sn_1_deviceid:{}", sn_1_deviceid);
520
521        let device_endpoints = vec![Endpoint::default()];
522        let device_unique_id = UniqueId::default();
523        // let device_sn_list = vec![DeviceId::try_from(sn_1_deviceid).unwrap()];
524        let mut device_sn_list = vec![];
525        for _i in 0..64 {
526            device_sn_list.push(DeviceId::try_from(sn_1_deviceid).unwrap());
527        }
528        let _btc_hash_value_2 = Some(HashValue::default());
529
530        let device_area = Area::new(0, 5, 0, 1);
531        let mut device = Device::new(
532            Some(ObjectId::default()),
533            device_unique_id,
534            device_endpoints,
535            device_sn_list,
536            Vec::new(),
537            device_public_key,
538            device_area,
539            DeviceCategory::OOD,
540        )
541        .build();
542
543        //let device_id = device.desc().calculate_id();
544        //let body = device.body_mut().as_mut().unwrap();
545        //let content = body.content_mut();
546
547        let user_data = vec![0u8; 100];
548        let _ = device.body_mut().as_mut().unwrap().set_userdata(&user_data);
549
550        let device_clone = device.clone();
551        // let device_clone2 = device.clone();
552        println!("before={}", device_clone.desc().device_id());
553        // let device_id2 = device_clone.desc().calculate_id();
554        // assert_eq!(device_id,device_id2);
555
556        // let p = Path::new("f:\\temp\\device.obj");
557        // if p.parent().unwrap().exists() {
558        //     device_clone2.encode_to_file(p, false);
559        // }
560
561        let size = device.raw_measure(&None).unwrap();
562        let mut encod_buf = vec![0u8; size];
563        let buf = device.raw_encode(&mut encod_buf, &None).unwrap();
564        println!("encode buf rest:{}", buf.len());
565        assert_eq!(buf.len(), 0);
566
567        let _ = device.desc().owner();
568        let _ = device.desc().area();
569
570        // let (t,buf) = ObjectTypeInfo::raw_decode(& encod_buf).unwrap();
571        // println!("a device with sn peer info, device t:{:?}, size:{}, encod_buf:{}, buf:{}", t, size, encod_buf.len(), buf.len());
572
573        let (d, buf) = Device::raw_decode(&encod_buf).unwrap();
574        println!(
575            "a device with sn peer info, device d:{:?}, buf:{}",
576            d,
577            buf.len()
578        );
579
580        let _id = d.desc().device_id();
581        let id_str = _id.to_string();
582        println!("id to string:{}", id_str);
583        let id_from_str = DeviceId::from_str(&id_str);
584        println!("id from str:{:?}", id_from_str);
585
586        println!("[object id] {:?}", _id);
587        println!("[object id] {:?}", _id.to_string());
588
589        println!("[object id] {:?}", _id.object_id());
590        println!("[object id] {}", _id.object_id().to_string());
591
592        // d.signs_mut().push_body_sign(Signature::default());
593
594        println!("\n\n\n");
595
596        let buf = d.to_vec().unwrap();
597        // println!("d: {:?}", &buf[..10]);
598
599        println!("test:{:?}", d.body_expect("xx").content().sn_list());
600
601        let dd = Device::clone_from_slice(&buf).unwrap();
602        let buf = dd.to_vec().unwrap();
603        println!("dd: {:?}", &buf[..10]);
604
605        let mut dc = dd.clone();
606        dc.signs_mut().push_body_sign(Signature::default());
607
608        let buf = dd.to_vec().unwrap();
609        println!("dd: {:?}", &buf[..10]);
610
611        let buf = dc.to_vec().unwrap();
612        println!("dc: {:?}", &buf[..10]);
613
614        // assert!(false);
615
616        assert!(dc.signs().body_signs().is_some());
617    }
618}