@@ -6,14 +6,20 @@ use crate::{
6
6
} ,
7
7
} ;
8
8
use serialport:: SerialPort ;
9
- use std:: { path:: PathBuf , time:: Duration } ;
9
+ use std:: {
10
+ borrow:: BorrowMut ,
11
+ ops:: DerefMut ,
12
+ path:: PathBuf ,
13
+ sync:: { Arc , Mutex } ,
14
+ time:: Duration ,
15
+ } ;
10
16
11
17
//TODO: fix this
12
18
const MAXIMUM_ZIGBEE_PAYLOAD_SIZE : usize = 255 ;
13
19
14
20
pub struct CC2531X {
15
21
_supports_led : Option < bool > ,
16
- serial : Box < dyn SerialPort > ,
22
+ serial : Arc < Mutex < Box < dyn SerialPort > > > ,
17
23
}
18
24
19
25
impl CC2531X {
@@ -23,13 +29,13 @@ impl CC2531X {
23
29
. open ( )
24
30
. map_err ( |_e| CoordinatorError :: SerialOpen ) ?;
25
31
Ok ( Self {
26
- serial,
32
+ serial : Arc :: new ( Mutex :: new ( serial ) ) ,
27
33
_supports_led : None ,
28
34
} )
29
35
}
30
36
31
37
pub async fn wait_for (
32
- & mut self ,
38
+ & self ,
33
39
name : & str ,
34
40
message_type : MessageType ,
35
41
subsystem : Subsystem ,
@@ -40,6 +46,8 @@ impl CC2531X {
40
46
let mut buffer = [ 0 ; MAX_FRAME_SIZE ] ;
41
47
let len = self
42
48
. serial
49
+ . lock ( )
50
+ . unwrap ( )
43
51
. read ( & mut buffer)
44
52
. map_err ( |_e| CoordinatorError :: Io ) ?;
45
53
let packet = UnpiPacket :: from_payload (
@@ -78,51 +86,48 @@ impl Coordinator for CC2531X {
78
86
todo ! ( )
79
87
}
80
88
81
- async fn version ( & mut self ) -> Result < usize , CoordinatorError > {
89
+ async fn version ( & self ) -> Result < usize , CoordinatorError > {
82
90
let command = get_command_by_name ( & Subsystem :: Sys , "version" )
83
91
. ok_or ( CoordinatorError :: NoCommandWithName ) ?;
92
+ let mut lock = self . serial . lock ( ) . unwrap ( ) ;
84
93
let send = UnpiPacket :: from_command_to_serial_async (
85
94
command. id ,
86
95
command,
87
96
& [ ] ,
88
97
( MessageType :: SREQ , Subsystem :: Sys ) ,
89
- & mut * self . serial ,
98
+ & mut * * lock ,
90
99
) ;
91
- // let wait = self.wait_for(
92
- // "version",
93
- // MessageType::SRESP,
94
- // Subsystem::Sys,
95
- // command.id,
96
- // None,
97
- // );
98
- // let r = futures::try_join!(send, wait)?;
100
+ let wait = self . wait_for ( "version" , MessageType :: SRESP , Subsystem :: Sys , None ) ;
101
+ let r = futures:: try_join!( send, wait) ?;
99
102
Ok ( 0 )
100
103
}
101
104
102
- async fn reset ( & mut self , reset_type : ResetType ) -> Result < ( ) , CoordinatorError > {
105
+ async fn reset ( & self , reset_type : ResetType ) -> Result < ( ) , CoordinatorError > {
103
106
let command = get_command_by_name ( & Subsystem :: Sys , "reset_req" )
104
107
. ok_or ( CoordinatorError :: NoCommandWithName ) ?;
105
108
let parameters = match reset_type {
106
109
ResetType :: Soft => & [ ( "type" , ParameterValue :: U8 ( 1 ) ) ] ,
107
110
ResetType :: Hard => & [ ( "type" , ParameterValue :: U8 ( 0 ) ) ] ,
108
111
} ;
109
112
113
+ let mut lock = self . serial . lock ( ) . unwrap ( ) ;
110
114
UnpiPacket :: from_command_to_serial (
111
115
command. id ,
112
116
command,
113
117
parameters,
114
118
( MessageType :: SREQ , Subsystem :: Util ) ,
115
- & mut * self . serial ,
119
+ & mut * * lock ,
116
120
) ?;
117
121
118
122
Ok ( ( ) )
119
123
}
120
124
121
- async fn set_led ( & mut self , led_status : LedStatus ) -> Result < ( ) , CoordinatorError > {
125
+ async fn set_led ( & self , led_status : LedStatus ) -> Result < ( ) , CoordinatorError > {
122
126
let command = get_command_by_name ( & Subsystem :: Util , "led_control" )
123
127
. ok_or ( CoordinatorError :: NoCommandWithName ) ?;
124
128
//TODO: const firmwareControlsLed = parseInt(this.version.revision) >= 20211029;
125
129
let firmware_controls_led = true ;
130
+ let mut lock = self . serial . lock ( ) . unwrap ( ) ;
126
131
let parameters = match led_status {
127
132
LedStatus :: Disable => {
128
133
if firmware_controls_led {
@@ -152,13 +157,13 @@ impl Coordinator for CC2531X {
152
157
command,
153
158
parameters,
154
159
( MessageType :: SREQ , Subsystem :: Util ) ,
155
- & mut * self . serial ,
160
+ & mut * * lock ,
156
161
) ?;
157
162
158
163
Ok ( ( ) )
159
164
}
160
165
161
- async fn change_channel ( & mut self , channel : u8 ) -> Result < ( ) , CoordinatorError > {
166
+ async fn change_channel ( & self , channel : u8 ) -> Result < ( ) , CoordinatorError > {
162
167
let parameters = & [
163
168
( "dst_addr" , ParameterValue :: U16 ( 0xffff ) ) ,
164
169
(
@@ -181,31 +186,33 @@ impl Coordinator for CC2531X {
181
186
182
187
let command = get_command_by_name ( & Subsystem :: Zdo , "management_network_update_request" )
183
188
. ok_or ( CoordinatorError :: NoCommandWithName ) ?;
189
+ let mut lock = self . serial . lock ( ) . unwrap ( ) ;
184
190
UnpiPacket :: from_command_to_serial (
185
191
command. id ,
186
192
command,
187
193
parameters,
188
194
( MessageType :: SREQ , Subsystem :: Zdo ) ,
189
- & mut * self . serial ,
195
+ & mut * * lock ,
190
196
) ?;
191
197
192
198
Ok ( ( ) )
193
199
}
194
200
195
- async fn set_transmit_power ( & mut self , power : i8 ) -> Result < ( ) , CoordinatorError > {
201
+ async fn set_transmit_power ( & self , power : i8 ) -> Result < ( ) , CoordinatorError > {
196
202
let parameters = & [
197
203
( "operation" , ParameterValue :: U8 ( 0 ) ) ,
198
204
( "value" , ParameterValue :: I8 ( power) ) ,
199
205
] ;
200
206
201
207
let command = get_command_by_name ( & Subsystem :: Zdo , "stack_tune" )
202
208
. ok_or ( CoordinatorError :: NoCommandWithName ) ?;
209
+ let mut lock = self . serial . lock ( ) . unwrap ( ) ;
203
210
UnpiPacket :: from_command_to_serial (
204
211
command. id ,
205
212
command,
206
213
parameters,
207
214
( MessageType :: SREQ , Subsystem :: Zdo ) ,
208
- & mut * self . serial ,
215
+ & mut * * lock ,
209
216
) ?;
210
217
Ok ( ( ) )
211
218
}
0 commit comments