@@ -48,29 +48,55 @@ void UsbAdbDevice::Start(StartRequestView request, StartCompleter::Sync& complet
48
48
return CompleteTxn (completer, ZX_ERR_ALREADY_BOUND);
49
49
}
50
50
51
+ // Reset interface and configure endpoints as adb binding is set now.
52
+ zx_status_t status = function_.SetInterface (this , &usb_function_interface_protocol_ops_);
53
+ if (status != ZX_OK && status != ZX_ERR_ALREADY_BOUND) {
54
+ zxlogf (ERROR, " SetInterface failed %s" , zx_status_get_string (status));
55
+ CompleteTxn (completer, status);
56
+ return ;
57
+ }
51
58
adb_binding_.emplace (fdf::Dispatcher::GetCurrent ()->async_dispatcher (),
52
59
std::move (request->interface ), this , [this ](fidl::UnbindInfo info) {
53
60
zxlogf (INFO, " Device closed with reason '%s'" ,
54
61
info.FormatDescription ().c_str ());
55
62
Stop ();
56
63
});
57
- // Reset interface and configure endpoints as adb binding is set now.
58
- zx_status_t status = function_.SetInterface (this , &usb_function_interface_protocol_ops_);
59
- if (status != ZX_OK && status != ZX_ERR_ALREADY_BOUND) {
60
- zxlogf (ERROR, " SetInterface failed %s" , zx_status_get_string (status));
61
- CompleteTxn (completer, status);
64
+ CompleteTxn (completer, ZX_OK);
65
+
66
+ Start ();
67
+ }
68
+
69
+ void UsbAdbDevice::Start () {
70
+ if (!Online () || !adb_binding_) {
62
71
return ;
63
72
}
73
+
64
74
auto result = fidl::WireSendEvent (adb_binding_.value ())
65
75
->OnStatusChanged (Online () ? fadb::StatusFlags::kOnline : fadb::StatusFlags (0 ));
66
76
if (!result.ok ()) {
67
77
zxlogf (ERROR, " Could not call AdbInterface Status." );
68
- CompleteTxn (completer, result.error ().status ());
69
78
return ;
70
79
}
71
- CompleteTxn (completer, status);
72
80
73
- // Run receive to pass up messages received while disconnected.
81
+ // queue RX requests
82
+ std::vector<fuchsia_hardware_usb_request::Request> requests;
83
+ while (auto req = bulk_out_ep_.GetRequest ()) {
84
+ req->reset_buffers (bulk_out_ep_.GetMapped ());
85
+ auto status = req->CacheFlushInvalidate (bulk_out_ep_.GetMapped ());
86
+ if (status != ZX_OK) {
87
+ zxlogf (ERROR, " Cache flush and invalidate failed %d" , status);
88
+ }
89
+
90
+ requests.emplace_back (req->take_request ());
91
+ }
92
+ if (!requests.empty ()) {
93
+ auto result = bulk_out_ep_->QueueRequests (std::move (requests));
94
+ if (result.is_error ()) {
95
+ zxlogf (ERROR, " Failed to QueueRequests %s" , result.error_value ().FormatDescription ().c_str ());
96
+ return ;
97
+ }
98
+ }
99
+
74
100
std::lock_guard<std::mutex> _ (bulk_out_ep_.mutex ());
75
101
ReceiveLocked ();
76
102
}
@@ -89,23 +115,10 @@ void UsbAdbDevice::Stop() {
89
115
adb_binding_.reset ();
90
116
}
91
117
92
- // Cancel all requests in the pipeline -- the completion handler will free these requests as they
93
- // come in.
94
- //
95
- // Do not hold locks when calling this method. It might result in deadlock as completion callbacks
96
- // could be invoked during this call.
97
- bulk_out_ep_->CancelAll ().Then ([](fidl::Result<fendpoint::Endpoint::CancelAll>& result) {
98
- if (result.is_error ()) {
99
- zxlogf (ERROR, " Failed to cancel all for bulk out endpoint %s" ,
100
- result.error_value ().FormatDescription ().c_str ());
101
- }
102
- });
103
- bulk_in_ep_->CancelAll ().Then ([](fidl::Result<fendpoint::Endpoint::CancelAll>& result) {
104
- if (result.is_error ()) {
105
- zxlogf (ERROR, " Failed to cancel all for bulk in endpoint %s" ,
106
- result.error_value ().FormatDescription ().c_str ());
107
- }
108
- });
118
+ zx_status_t status = ConfigureEndpoints (false );
119
+ if (status != ZX_OK) {
120
+ zxlogf (ERROR, " Failed to unconifgure endpoints %s." , zx_status_get_string (status));
121
+ }
109
122
110
123
{
111
124
std::lock_guard<std::mutex> _ (bulk_out_ep_.mutex ());
@@ -127,7 +140,7 @@ void UsbAdbDevice::Stop() {
127
140
}
128
141
}
129
142
130
- zx_status_t status = function_.SetInterface (nullptr , nullptr );
143
+ status = function_.SetInterface (nullptr , nullptr );
131
144
if (status != ZX_OK) {
132
145
zxlogf (ERROR, " SetInterface failed %s" , zx_status_get_string (status));
133
146
}
@@ -137,13 +150,9 @@ void UsbAdbDevice::Stop() {
137
150
ShutdownComplete ();
138
151
}
139
152
140
- zx::result<> UsbAdbDevice::SendLocked () {
141
- if (tx_pending_reqs_.empty ()) {
142
- return zx::ok ();
143
- }
144
-
145
- if (!Online ()) {
146
- return zx::error (ZX_ERR_BAD_STATE);
153
+ void UsbAdbDevice::SendLocked () {
154
+ if (!Online () || tx_pending_reqs_.empty ()) {
155
+ return ;
147
156
}
148
157
149
158
auto & current = tx_pending_reqs_.front ();
@@ -184,12 +193,10 @@ zx::result<> UsbAdbDevice::SendLocked() {
184
193
CompleteTxn (current.completer , ZX_OK);
185
194
tx_pending_reqs_.pop ();
186
195
}
187
-
188
- return zx::ok ();
189
196
}
190
197
191
198
void UsbAdbDevice::ReceiveLocked () {
192
- if (pending_replies_.empty () || rx_requests_.empty ()) {
199
+ if (! Online () || pending_replies_.empty () || rx_requests_.empty ()) {
193
200
return ;
194
201
}
195
202
@@ -234,7 +241,7 @@ void UsbAdbDevice::ReceiveLocked() {
234
241
void UsbAdbDevice::QueueTx (QueueTxRequest& request, QueueTxCompleter::Sync& completer) {
235
242
size_t length = request.data ().size ();
236
243
237
- if (! Online () || length == 0 ) {
244
+ if (length == 0 ) {
238
245
zxlogf (INFO, " Invalid state - Online %d Length %zu" , Online (), length);
239
246
completer.Reply (fit::error (ZX_ERR_INVALID_ARGS));
240
247
return ;
@@ -244,19 +251,10 @@ void UsbAdbDevice::QueueTx(QueueTxRequest& request, QueueTxCompleter::Sync& comp
244
251
tx_pending_reqs_.emplace (
245
252
txn_req_t {.request = std::move (request), .start = 0 , .completer = completer.ToAsync ()});
246
253
247
- auto result = SendLocked ();
248
- if (result.is_error ()) {
249
- zxlogf (INFO, " SendLocked failed %d" , result.error_value ());
250
- }
254
+ SendLocked ();
251
255
}
252
256
253
257
void UsbAdbDevice::Receive (ReceiveCompleter::Sync& completer) {
254
- // Return early during shutdown.
255
- if (!Online ()) {
256
- completer.Reply (fit::error (ZX_ERR_BAD_STATE));
257
- return ;
258
- }
259
-
260
258
std::lock_guard<std::mutex> lock (bulk_out_ep_.mutex ());
261
259
rx_requests_.emplace (completer.ToAsync ());
262
260
ReceiveLocked ();
@@ -302,10 +300,7 @@ void UsbAdbDevice::TxComplete(fendpoint::Completion completion) {
302
300
return ;
303
301
}
304
302
305
- auto result = SendLocked ();
306
- if (result.is_error ()) {
307
- zxlogf (ERROR, " Failed to SendLocked %d" , result.error_value ());
308
- }
303
+ SendLocked ();
309
304
}
310
305
311
306
size_t UsbAdbDevice::UsbFunctionInterfaceGetDescriptorsSize () { return sizeof (descriptors_); }
@@ -329,10 +324,16 @@ zx_status_t UsbAdbDevice::UsbFunctionInterfaceControl(const usb_setup_t* setup,
329
324
}
330
325
331
326
zx_status_t UsbAdbDevice::ConfigureEndpoints (bool enable) {
332
- zx_status_t status;
333
- // Configure endpoint if not already done.
334
- if (enable && !bulk_out_ep_.RequestsEmpty ()) {
335
- status = function_.ConfigEp (&descriptors_.bulk_out_ep , nullptr );
327
+ {
328
+ std::lock_guard<std::mutex> _ (lock_);
329
+ if (status_ == fadb::StatusFlags (enable)) {
330
+ return ZX_OK;
331
+ }
332
+ status_ = fadb::StatusFlags (enable);
333
+ }
334
+
335
+ if (enable) {
336
+ zx_status_t status = function_.ConfigEp (&descriptors_.bulk_out_ep , nullptr );
336
337
if (status != ZX_OK) {
337
338
zxlogf (ERROR, " Failed to Config BULK OUT ep - %d." , status);
338
339
return status;
@@ -344,25 +345,10 @@ zx_status_t UsbAdbDevice::ConfigureEndpoints(bool enable) {
344
345
return status;
345
346
}
346
347
347
- // queue RX requests
348
- std::vector<fuchsia_hardware_usb_request::Request> requests;
349
- while (auto req = bulk_out_ep_.GetRequest ()) {
350
- req->reset_buffers (bulk_out_ep_.GetMapped ());
351
- auto status = req->CacheFlushInvalidate (bulk_out_ep_.GetMapped ());
352
- if (status != ZX_OK) {
353
- zxlogf (ERROR, " Cache flush and invalidate failed %d" , status);
354
- }
355
-
356
- requests.emplace_back (req->take_request ());
357
- }
358
- auto result = bulk_out_ep_->QueueRequests (std::move (requests));
359
- if (result.is_error ()) {
360
- zxlogf (ERROR, " Failed to QueueRequests %s" , result.error_value ().FormatDescription ().c_str ());
361
- return result.error_value ().status ();
362
- }
348
+ Start ();
363
349
zxlogf (INFO, " ADB endpoints configured." );
364
- } else if (!enable) {
365
- status = function_.DisableEp (bulk_out_addr ());
350
+ } else {
351
+ zx_status_t status = function_.DisableEp (bulk_out_addr ());
366
352
if (status != ZX_OK) {
367
353
zxlogf (ERROR, " Failed to disable BULK OUT ep - %d." , status);
368
354
return status;
@@ -373,27 +359,21 @@ zx_status_t UsbAdbDevice::ConfigureEndpoints(bool enable) {
373
359
zxlogf (ERROR, " Failed to disable BULK IN ep - %d." , status);
374
360
return status;
375
361
}
376
- }
377
362
378
- if (adb_binding_.has_value ()) {
379
- auto result = fidl::WireSendEvent (adb_binding_.value ())
380
- ->OnStatusChanged (enable ? fadb::StatusFlags::kOnline : fadb::StatusFlags (0 ));
381
- if (!result.ok ()) {
382
- zxlogf (ERROR, " Could not call AdbInterface Status." );
383
- return ZX_ERR_IO;
363
+ if (adb_binding_.has_value ()) {
364
+ auto result =
365
+ fidl::WireSendEvent (adb_binding_.value ())->OnStatusChanged (fadb::StatusFlags (0 ));
366
+ if (!result.ok ()) {
367
+ zxlogf (ERROR, " Could not call AdbInterface Status." );
368
+ return ZX_ERR_IO;
369
+ }
384
370
}
385
371
}
386
-
387
372
return ZX_OK;
388
373
}
389
374
390
375
zx_status_t UsbAdbDevice::UsbFunctionInterfaceSetConfigured (bool configured, usb_speed_t speed) {
391
376
zxlogf (INFO, " configured? - %d speed - %d." , configured, speed);
392
- {
393
- std::lock_guard<std::mutex> _ (lock_);
394
- status_ = fadb::StatusFlags (configured);
395
- }
396
-
397
377
return ConfigureEndpoints (configured);
398
378
}
399
379
@@ -403,19 +383,7 @@ zx_status_t UsbAdbDevice::UsbFunctionInterfaceSetInterface(uint8_t interface, ui
403
383
if (interface != descriptors_.adb_intf .b_interface_number || alt_setting > 1 ) {
404
384
return ZX_ERR_INVALID_ARGS;
405
385
}
406
-
407
- auto status = ConfigureEndpoints (alt_setting);
408
- if (status != ZX_OK) {
409
- zxlogf (ERROR, " ConfigureEndpoints failed %d" , status);
410
- return status;
411
- }
412
-
413
- {
414
- std::lock_guard<std::mutex> _ (lock_);
415
- status_ = alt_setting ? fadb::StatusFlags::kOnline : fadb::StatusFlags (0 );
416
- }
417
-
418
- return status;
386
+ return ConfigureEndpoints (alt_setting);
419
387
}
420
388
421
389
void UsbAdbDevice::ShutdownComplete () {
@@ -424,7 +392,8 @@ void UsbAdbDevice::ShutdownComplete() {
424
392
// Only call the callback if all requests are returned.
425
393
if (stop_completed_ && shutdown_callback_ && bulk_in_ep_.RequestsFull () &&
426
394
bulk_out_ep_.RequestsFull ()) {
427
- shutdown_callback_ ();
395
+ auto callback = std::move (shutdown_callback_);
396
+ callback ();
428
397
stop_completed_ = false ;
429
398
}
430
399
}
0 commit comments