1use crate::*;
2
3use std::convert::TryFrom;
4
5#[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
162impl 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
259impl 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 #[test]
423 fn test_decode() {
424 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 let endpoints = vec![Endpoint::default()];
493 let sn_list = vec![];
494
495 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 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 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 println!("before={}", device_clone.desc().device_id());
553 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 (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 println!("\n\n\n");
595
596 let buf = d.to_vec().unwrap();
597 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!(dc.signs().body_signs().is_some());
617 }
618}