1 /*
2 * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
3 * Copyright 2008 Mika Lindqvist, monni1995_at_gmail.com
4 * All rights reserved. Distributed under the terms of the MIT License.
5 *
6 */
7
8 #include "BluetoothServer.h"
9
10 #include "LocalDeviceImpl.h"
11 #include "CommandManager.h"
12 #include "Debug.h"
13
14 #include <bluetooth/bdaddrUtils.h>
15 #include <bluetooth/bluetooth_error.h>
16 #include <bluetooth/LinkKeyUtils.h>
17 #include <bluetooth/RemoteDevice.h>
18 #include <bluetooth/HCI/btHCI_event.h>
19
20 #include <bluetoothserver_p.h>
21 #include <ConnectionIncoming.h>
22 #include <PincodeWindow.h>
23
24 #include <stdio.h>
25 #include <new>
26
27
28 #if 0
29 #pragma mark - Class methods -
30 #endif
31
32
33 // Factory methods
34 LocalDeviceImpl*
CreateControllerAccessor(BPath * path)35 LocalDeviceImpl::CreateControllerAccessor(BPath* path)
36 {
37 HCIDelegate* delegate = new(std::nothrow) HCIControllerAccessor(path);
38 if (delegate == NULL)
39 return NULL;
40
41 LocalDeviceImpl* device = new(std::nothrow) LocalDeviceImpl(delegate);
42 if (device == NULL) {
43 delete delegate;
44 return NULL;
45 }
46
47 return device;
48 }
49
50
51 LocalDeviceImpl*
CreateTransportAccessor(BPath * path)52 LocalDeviceImpl::CreateTransportAccessor(BPath* path)
53 {
54 HCIDelegate* delegate = new(std::nothrow) HCITransportAccessor(path);
55 if (delegate == NULL)
56 return NULL;
57
58 LocalDeviceImpl* device = new(std::nothrow) LocalDeviceImpl(delegate);
59 if (device == NULL) {
60 delete delegate;
61 return NULL;
62 }
63
64 return device;
65 }
66
67
LocalDeviceImpl(HCIDelegate * hd)68 LocalDeviceImpl::LocalDeviceImpl(HCIDelegate* hd) : LocalDeviceHandler(hd)
69 {
70
71 }
72
73
~LocalDeviceImpl()74 LocalDeviceImpl::~LocalDeviceImpl()
75 {
76
77 }
78
79
80 void
Unregister()81 LocalDeviceImpl::Unregister()
82 {
83 BMessage* msg = new BMessage(BT_MSG_REMOVE_DEVICE);
84
85 msg->AddInt32("hci_id", fHCIDelegate->Id());
86
87 TRACE_BT("LocalDeviceImpl: Unregistering %" B_PRId32 "\n",
88 fHCIDelegate->Id());
89
90 be_app_messenger.SendMessage(msg);
91 }
92
93
94 #if 0
95 #pragma mark - Event handling methods -
96 #endif
97
98 template<typename T, typename Header>
99 inline T*
JumpEventHeader(Header * event)100 JumpEventHeader(Header* event)
101 {
102 return (T*)(event + 1);
103 }
104
105
106 void
HandleUnexpectedEvent(struct hci_event_header * event)107 LocalDeviceImpl::HandleUnexpectedEvent(struct hci_event_header* event)
108 {
109 // Events here might have not been initated by us
110 // TODO: ML mark as handled pass a reply by parameter and reply in common
111 switch (event->ecode) {
112 case HCI_EVENT_HARDWARE_ERROR:
113 HardwareError(
114 JumpEventHeader<struct hci_ev_hardware_error>(event));
115 break;
116
117 case HCI_EVENT_CONN_REQUEST:
118 ConnectionRequest(
119 JumpEventHeader<struct hci_ev_conn_request>(event), NULL);
120 break;
121
122 case HCI_EVENT_NUM_COMP_PKTS:
123 NumberOfCompletedPackets(
124 JumpEventHeader<struct hci_ev_num_comp_pkts>(event));
125 break;
126
127 case HCI_EVENT_DISCONNECTION_COMPLETE:
128 // should belong to a request? can be sporadic or initiated by us?
129 DisconnectionComplete(
130 JumpEventHeader
131 <struct hci_ev_disconnection_complete_reply>(event),
132 NULL);
133 break;
134 case HCI_EVENT_PIN_CODE_REQ:
135 PinCodeRequest(
136 JumpEventHeader<struct hci_ev_pin_code_req>(event), NULL);
137 break;
138 default:
139 // TODO: feedback unexpected not handled
140 break;
141 }
142 }
143
144
145 void
HandleExpectedRequest(struct hci_event_header * event,BMessage * request)146 LocalDeviceImpl::HandleExpectedRequest(struct hci_event_header* event,
147 BMessage* request)
148 {
149 // we are waiting for a reply
150 switch (event->ecode) {
151 case HCI_EVENT_INQUIRY_COMPLETE:
152 InquiryComplete(JumpEventHeader<uint8>(event), request);
153 break;
154
155 case HCI_EVENT_INQUIRY_RESULT:
156 InquiryResult(JumpEventHeader<uint8>(event), request);
157 break;
158
159 case HCI_EVENT_CONN_COMPLETE:
160 ConnectionComplete(
161 JumpEventHeader<struct hci_ev_conn_complete>(event), request);
162 break;
163
164 case HCI_EVENT_DISCONNECTION_COMPLETE:
165 // should belong to a request? can be sporadic or initiated by us?
166 DisconnectionComplete(
167 JumpEventHeader<struct hci_ev_disconnection_complete_reply>
168 (event), request);
169 break;
170
171 case HCI_EVENT_AUTH_COMPLETE:
172
173 break;
174
175 case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE:
176 RemoteNameRequestComplete(
177 JumpEventHeader
178 <struct hci_ev_remote_name_request_complete_reply>
179 (event), request);
180 break;
181
182 case HCI_EVENT_ENCRYPT_CHANGE:
183 break;
184
185 case HCI_EVENT_CHANGE_CONN_LINK_KEY_COMPLETE:
186 break;
187
188 case HCI_EVENT_MASTER_LINK_KEY_COMPL:
189 break;
190
191 case HCI_EVENT_RMT_FEATURES:
192 break;
193
194 case HCI_EVENT_RMT_VERSION:
195 break;
196
197 case HCI_EVENT_QOS_SETUP_COMPLETE:
198 break;
199
200 case HCI_EVENT_FLUSH_OCCUR:
201 break;
202
203 case HCI_EVENT_ROLE_CHANGE:
204 RoleChange(
205 JumpEventHeader<struct hci_ev_role_change>(event), request);
206 break;
207
208 case HCI_EVENT_MODE_CHANGE:
209 break;
210
211 case HCI_EVENT_RETURN_LINK_KEYS:
212 ReturnLinkKeys(
213 JumpEventHeader<struct hci_ev_return_link_keys>(event));
214 break;
215
216 case HCI_EVENT_LINK_KEY_REQ:
217 LinkKeyRequested(
218 JumpEventHeader<struct hci_ev_link_key_req>(event), request);
219 break;
220
221 case HCI_EVENT_LINK_KEY_NOTIFY:
222 LinkKeyNotify(
223 JumpEventHeader<struct hci_ev_link_key_notify>(event), request);
224 break;
225
226 case HCI_EVENT_LOOPBACK_COMMAND:
227 break;
228
229 case HCI_EVENT_DATA_BUFFER_OVERFLOW:
230 break;
231
232 case HCI_EVENT_MAX_SLOT_CHANGE:
233 MaxSlotChange(JumpEventHeader<struct hci_ev_max_slot_change>(event),
234 request);
235 break;
236
237 case HCI_EVENT_READ_CLOCK_OFFSET_COMPL:
238 break;
239
240 case HCI_EVENT_CON_PKT_TYPE_CHANGED:
241 break;
242
243 case HCI_EVENT_QOS_VIOLATION:
244 break;
245
246 case HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE:
247 PageScanRepetitionModeChange(
248 JumpEventHeader<struct hci_ev_page_scan_rep_mode_change>(event),
249 request);
250 break;
251
252 case HCI_EVENT_FLOW_SPECIFICATION:
253 break;
254
255 case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI:
256 break;
257
258 case HCI_EVENT_REMOTE_EXTENDED_FEATURES:
259 break;
260
261 case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETED:
262 break;
263
264 case HCI_EVENT_SYNCHRONOUS_CONNECTION_CHANGED:
265 break;
266 }
267 }
268
269
270 void
HandleEvent(struct hci_event_header * event)271 LocalDeviceImpl::HandleEvent(struct hci_event_header* event)
272 {
273 /*
274 printf("### Incoming event: len = %d\n", event->elen);
275 for (int16 index = 0; index < event->elen + 2; index++) {
276 printf("%x:", ((uint8*)event)[index]);
277 }
278 printf("### \n");
279 */
280 BMessage* request = NULL;
281 int32 eventIndexLocation;
282
283 // Check if it is a requested one
284 switch (event->ecode) {
285 case HCI_EVENT_CMD_COMPLETE:
286 {
287 struct hci_ev_cmd_complete* commandComplete
288 = JumpEventHeader<struct hci_ev_cmd_complete>(event);
289
290 TRACE_BT("LocalDeviceImpl: Incoming CommandComplete(%d) for %s\n", commandComplete->ncmd,
291 BluetoothCommandOpcode(commandComplete->opcode));
292
293 request = FindPetition(event->ecode, commandComplete->opcode,
294 &eventIndexLocation);
295
296 if (request != NULL)
297 CommandComplete(commandComplete, request, eventIndexLocation);
298
299 break;
300 }
301 case HCI_EVENT_CMD_STATUS:
302 {
303 struct hci_ev_cmd_status* commandStatus
304 = JumpEventHeader<struct hci_ev_cmd_status>(event);
305
306 TRACE_BT("LocalDeviceImpl: Incoming CommandStatus(%d)(%s) for %s\n", commandStatus->ncmd,
307 BluetoothError(commandStatus->status),
308 BluetoothCommandOpcode(commandStatus->opcode));
309
310 request = FindPetition(event->ecode, commandStatus->opcode,
311 &eventIndexLocation);
312 if (request != NULL)
313 CommandStatus(commandStatus, request, eventIndexLocation);
314
315 break;
316 }
317 default:
318 TRACE_BT("LocalDeviceImpl: Incoming %s event\n", BluetoothEvent(event->ecode));
319
320 request = FindPetition(event->ecode);
321 if (request != NULL)
322 HandleExpectedRequest(event, request);
323
324 break;
325 }
326
327 if (request == NULL) {
328 TRACE_BT("LocalDeviceImpl: Event %s could not be understood or delivered\n",
329 BluetoothEvent(event->ecode));
330 HandleUnexpectedEvent(event);
331 }
332 }
333
334
335 #if 0
336 #pragma mark -
337 #endif
338
339
340 void
CommandComplete(struct hci_ev_cmd_complete * event,BMessage * request,int32 index)341 LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event,
342 BMessage* request, int32 index)
343 {
344 int16 opcodeExpected;
345 BMessage reply;
346 status_t status;
347
348 // Handle command complete information
349 request->FindInt16("opcodeExpected", index, &opcodeExpected);
350
351 if (request->IsSourceWaiting() == false) {
352 TRACE_BT("LocalDeviceImpl: Nobody waiting for the event\n");
353 }
354
355 switch ((uint16)opcodeExpected) {
356
357 case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_LOCAL_VERSION):
358 {
359 struct hci_rp_read_loc_version* version
360 = JumpEventHeader<struct hci_rp_read_loc_version,
361 struct hci_ev_cmd_complete>(event);
362
363
364 if (version->status == BT_OK) {
365
366 if (!IsPropertyAvailable("hci_version"))
367 fProperties->AddInt8("hci_version", version->hci_version);
368
369 if (!IsPropertyAvailable("hci_revision")) {
370 fProperties->AddInt16("hci_revision",
371 version->hci_revision);
372 }
373
374 if (!IsPropertyAvailable("lmp_version"))
375 fProperties->AddInt8("lmp_version", version->lmp_version);
376
377 if (!IsPropertyAvailable("lmp_subversion")) {
378 fProperties->AddInt16("lmp_subversion",
379 version->lmp_subversion);
380 }
381
382 if (!IsPropertyAvailable("manufacturer")) {
383 fProperties->AddInt16("manufacturer",
384 version->manufacturer);
385 }
386 }
387
388 TRACE_BT("LocalDeviceImpl: Reply for Local Version %x\n", version->status);
389
390 reply.AddInt8("status", version->status);
391 status = request->SendReply(&reply);
392 //printf("Sending reply... %ld\n", status);
393 // debug reply.PrintToStream();
394
395 // This request is not gonna be used anymore
396 ClearWantedEvent(request);
397 break;
398 }
399
400 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_PG_TIMEOUT):
401 {
402 struct hci_rp_read_page_timeout* pageTimeout
403 = JumpEventHeader<struct hci_rp_read_page_timeout,
404 struct hci_ev_cmd_complete>(event);
405
406 if (pageTimeout->status == BT_OK) {
407 fProperties->AddInt16("page_timeout",
408 pageTimeout->page_timeout);
409
410 TRACE_BT("LocalDeviceImpl: Page Timeout=%x\n", pageTimeout->page_timeout);
411 }
412
413 reply.AddInt8("status", pageTimeout->status);
414 reply.AddInt32("result", pageTimeout->page_timeout);
415 status = request->SendReply(&reply);
416 //printf("Sending reply... %ld\n", status);
417 // debug reply.PrintToStream();
418
419 // This request is not gonna be used anymore
420 ClearWantedEvent(request);
421 break;
422 }
423
424 case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_LOCAL_FEATURES):
425 {
426 struct hci_rp_read_loc_features* features
427 = JumpEventHeader<struct hci_rp_read_loc_features,
428 struct hci_ev_cmd_complete>(event);
429
430 if (features->status == BT_OK) {
431
432 if (!IsPropertyAvailable("features")) {
433 fProperties->AddData("features", B_ANY_TYPE,
434 &features->features, 8);
435
436 uint16 packetType = HCI_DM1 | HCI_DH1 | HCI_HV1;
437
438 bool roleSwitch
439 = (features->features[0] & LMP_RSWITCH) != 0;
440 bool encryptCapable
441 = (features->features[0] & LMP_ENCRYPT) != 0;
442
443 if (features->features[0] & LMP_3SLOT)
444 packetType |= (HCI_DM3 | HCI_DH3);
445
446 if (features->features[0] & LMP_5SLOT)
447 packetType |= (HCI_DM5 | HCI_DH5);
448
449 if (features->features[1] & LMP_HV2)
450 packetType |= (HCI_HV2);
451
452 if (features->features[1] & LMP_HV3)
453 packetType |= (HCI_HV3);
454
455 fProperties->AddInt16("packet_type", packetType);
456 fProperties->AddBool("role_switch_capable", roleSwitch);
457 fProperties->AddBool("encrypt_capable", encryptCapable);
458
459 TRACE_BT("LocalDeviceImpl: Packet type %x role switch %d encrypt %d\n",
460 packetType, roleSwitch, encryptCapable);
461 }
462
463 }
464
465 TRACE_BT("LocalDeviceImpl: Reply for Local Features %x\n", features->status);
466
467 reply.AddInt8("status", features->status);
468 status = request->SendReply(&reply);
469 //printf("Sending reply... %ld\n", status);
470 // debug reply.PrintToStream();
471
472 // This request is not gonna be used anymore
473 ClearWantedEvent(request);
474 break;
475 }
476
477 case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BUFFER_SIZE):
478 {
479 struct hci_rp_read_buffer_size* buffer
480 = JumpEventHeader<struct hci_rp_read_buffer_size,
481 struct hci_ev_cmd_complete>(event);
482
483 if (buffer->status == BT_OK) {
484
485 if (!IsPropertyAvailable("acl_mtu"))
486 fProperties->AddInt16("acl_mtu", buffer->acl_mtu);
487
488 if (!IsPropertyAvailable("sco_mtu"))
489 fProperties->AddInt8("sco_mtu", buffer->sco_mtu);
490
491 if (!IsPropertyAvailable("acl_max_pkt"))
492 fProperties->AddInt16("acl_max_pkt", buffer->acl_max_pkt);
493
494 if (!IsPropertyAvailable("sco_max_pkt"))
495 fProperties->AddInt16("sco_max_pkt", buffer->sco_max_pkt);
496
497 }
498
499 TRACE_BT("LocalDeviceImpl: Reply for Read Buffer Size %x\n", buffer->status);
500
501
502 reply.AddInt8("status", buffer->status);
503 status = request->SendReply(&reply);
504 //printf("Sending reply... %ld\n", status);
505 // debug reply.PrintToStream();
506
507 // This request is not gonna be used anymore
508 ClearWantedEvent(request);
509 }
510 break;
511
512 case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR):
513 {
514 struct hci_rp_read_bd_addr* readbdaddr
515 = JumpEventHeader<struct hci_rp_read_bd_addr,
516 struct hci_ev_cmd_complete>(event);
517
518 if (readbdaddr->status == BT_OK) {
519 reply.AddData("bdaddr", B_ANY_TYPE, &readbdaddr->bdaddr,
520 sizeof(bdaddr_t));
521 }
522
523 TRACE_BT("LocalDeviceImpl: Read bdaddr status = %x\n", readbdaddr->status);
524
525 reply.AddInt8("status", readbdaddr->status);
526 status = request->SendReply(&reply);
527 //printf("Sending reply... %ld\n", status);
528 // debug reply.PrintToStream();
529
530 // This request is not gonna be used anymore
531 ClearWantedEvent(request);
532 }
533 break;
534
535
536 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_CLASS_OF_DEV):
537 {
538 struct hci_read_dev_class_reply* classDev
539 = JumpEventHeader<struct hci_read_dev_class_reply,
540 struct hci_ev_cmd_complete>(event);
541
542 if (classDev->status == BT_OK) {
543 reply.AddData("devclass", B_ANY_TYPE, &classDev->dev_class,
544 sizeof(classDev->dev_class));
545 }
546
547 TRACE_BT("LocalDeviceImpl: Read DeviceClass status = %x DeviceClass = [%x][%x][%x]\n",
548 classDev->status, classDev->dev_class[0],
549 classDev->dev_class[1], classDev->dev_class[2]);
550
551
552 reply.AddInt8("status", classDev->status);
553 status = request->SendReply(&reply);
554 //printf("Sending reply... %ld\n", status);
555 // debug reply.PrintToStream();
556
557 // This request is not gonna be used anymore
558 ClearWantedEvent(request);
559 break;
560 }
561
562 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME):
563 {
564 struct hci_rp_read_local_name* readLocalName
565 = JumpEventHeader<struct hci_rp_read_local_name,
566 struct hci_ev_cmd_complete>(event);
567
568
569 if (readLocalName->status == BT_OK) {
570 reply.AddString("friendlyname",
571 (const char*)readLocalName->local_name);
572 }
573
574 TRACE_BT("LocalDeviceImpl: Friendly name status %x\n", readLocalName->status);
575
576 reply.AddInt8("status", readLocalName->status);
577 status = request->SendReply(&reply);
578 //printf("Sending reply... %ld\n", status);
579 // debug reply.PrintToStream();
580
581 // This request is not gonna be used anymore
582 ClearWantedEvent(request);
583 break;
584 }
585
586 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_PIN_CODE_REPLY):
587 {
588 uint8* statusReply = (uint8*)(event + 1);
589
590 // TODO: This reply has to match the BDADDR of the outgoing message
591 TRACE_BT("LocalDeviceImpl: pincode accept status %x\n", *statusReply);
592
593 reply.AddInt8("status", *statusReply);
594 status = request->SendReply(&reply);
595 //printf("Sending reply... %ld\n", status);
596 // debug reply.PrintToStream();
597
598 // This request is not gonna be used anymore
599 //ClearWantedEvent(request, HCI_EVENT_CMD_COMPLETE, opcodeExpected);
600 ClearWantedEvent(request);
601 break;
602 }
603
604 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_PIN_CODE_NEG_REPLY):
605 {
606 uint8* statusReply = (uint8*)(event + 1);
607
608 // TODO: This reply might match the BDADDR of the outgoing message
609 // => FindPetition should be expanded....
610 TRACE_BT("LocalDeviceImpl: pincode reject status %x\n", *statusReply);
611
612 reply.AddInt8("status", *statusReply);
613 status = request->SendReply(&reply);
614 //printf("Sending reply... %ld\n", status);
615 // debug reply.PrintToStream();
616
617 // This request is not gonna be used anymore
618 ClearWantedEvent(request, HCI_EVENT_CMD_COMPLETE, opcodeExpected);
619 break;
620 }
621
622 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_STORED_LINK_KEY):
623 {
624 struct hci_read_stored_link_key_reply* linkKeyRetrieval
625 = JumpEventHeader<struct hci_read_stored_link_key_reply,
626 struct hci_ev_cmd_complete>(event);
627
628 TRACE_BT("LocalDeviceImpl: Status %s MaxKeys=%d, KeysRead=%d\n",
629 BluetoothError(linkKeyRetrieval->status),
630 linkKeyRetrieval->max_num_keys,
631 linkKeyRetrieval->num_keys_read);
632
633 reply.AddInt8("status", linkKeyRetrieval->status);
634 status = request->SendReply(&reply);
635 //printf("Sending reply... %ld\n", status);
636 // debug reply.PrintToStream();
637
638 ClearWantedEvent(request);
639 break;
640 }
641
642 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_LINK_KEY_NEG_REPLY):
643 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_LINK_KEY_REPLY):
644 {
645 struct hci_cp_link_key_reply_reply* linkKeyReply
646 = JumpEventHeader<struct hci_cp_link_key_reply_reply,
647 struct hci_ev_cmd_complete>(event);
648
649 TRACE_BT("LocalDeviceImpl: Status %s addresss=%s\n", BluetoothError(linkKeyReply->status),
650 bdaddrUtils::ToString(linkKeyReply->bdaddr).String());
651
652 ClearWantedEvent(request, HCI_EVENT_CMD_COMPLETE, opcodeExpected);
653 break;
654 }
655
656 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_SCAN_ENABLE):
657 {
658 struct hci_read_scan_enable* scanEnable
659 = JumpEventHeader<struct hci_read_scan_enable,
660 struct hci_ev_cmd_complete>(event);
661
662 if (scanEnable->status == BT_OK) {
663 fProperties->AddInt8("scan_enable", scanEnable->enable);
664
665 TRACE_BT("LocalDeviceImpl: enable = %x\n", scanEnable->enable);
666 }
667
668 reply.AddInt8("status", scanEnable->status);
669 reply.AddInt8("scan_enable", scanEnable->enable);
670 status = request->SendReply(&reply);
671 printf("Sending reply. scan_enable = %d\n", scanEnable->enable);
672 // debug reply.PrintToStream();
673
674 // This request is not gonna be used anymore
675 ClearWantedEvent(request);
676 break;
677 }
678
679 // place here all CC that just replies a uint8 status
680 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_RESET):
681 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_SCAN_ENABLE):
682 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_CLASS_OF_DEV):
683 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_PG_TIMEOUT):
684 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_CA_TIMEOUT):
685 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_AUTH_ENABLE):
686 case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_LOCAL_NAME):
687 case PACK_OPCODE(OGF_VENDOR_CMD, OCF_WRITE_BCM2035_BDADDR):
688 {
689 reply.AddInt8("status", *(uint8*)(event + 1));
690
691 TRACE_BT("LocalDeviceImpl: %s for %s status %x\n", __FUNCTION__,
692 BluetoothCommandOpcode(opcodeExpected), *(uint8*)(event + 1));
693
694 status = request->SendReply(&reply);
695 printf("%s: Sending reply write...\n", __func__);
696 if (status < B_OK)
697 printf("%s: Error sending reply write!\n", __func__);
698
699 ClearWantedEvent(request);
700 break;
701 }
702
703 default:
704 TRACE_BT("LocalDeviceImpl: Command Complete not handled\n");
705 break;
706 }
707 }
708
709
710 void
CommandStatus(struct hci_ev_cmd_status * event,BMessage * request,int32 index)711 LocalDeviceImpl::CommandStatus(struct hci_ev_cmd_status* event,
712 BMessage* request, int32 index)
713 {
714 int16 opcodeExpected;
715 BMessage reply;
716
717 // Handle command complete information
718 request->FindInt16("opcodeExpected", index, &opcodeExpected);
719
720 if (request->IsSourceWaiting() == false) {
721 TRACE_BT("LocalDeviceImpl: Nobody waiting for the event\n");
722 }
723
724 switch (opcodeExpected) {
725
726 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY):
727 {
728 reply.what = BT_MSG_INQUIRY_STARTED;
729
730 TRACE_BT("LocalDeviceImpl: Inquiry status %x\n", event->status);
731
732 reply.AddInt8("status", event->status);
733 request->SendReply(&reply);
734 //printf("Sending reply... %ld\n", status);
735 // debug reply.PrintToStream();
736
737 ClearWantedEvent(request, HCI_EVENT_CMD_STATUS,
738 PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY));
739 }
740 break;
741
742 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST):
743 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_CREATE_CONN):
744 {
745 if (event->status == BT_OK) {
746 ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, opcodeExpected);
747 } else {
748 TRACE_BT("LocalDeviceImpl: Command Status for remote friendly name %x\n",
749 event->status);
750
751 reply.AddInt8("status", event->status);
752 request->SendReply(&reply);
753 //printf("Sending reply... %ld\n", status);
754 // debug reply.PrintToStream();
755
756 ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, opcodeExpected);
757 }
758 }
759 break;
760 /*
761 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ):
762 {
763 ClearWantedEvent(request, HCI_EVENT_CMD_STATUS,
764 PACK_OPCODE(OGF_LINK_CONTROL, OCF_ACCEPT_CONN_REQ));
765 }
766 break;
767
768 case PACK_OPCODE(OGF_LINK_CONTROL, OCF_REJECT_CONN_REQ):
769 {
770 ClearWantedEvent(request, HCI_EVENT_CMD_STATUS,
771 PACK_OPCODE(OGF_LINK_CONTROL, OCF_REJECT_CONN_REQ));
772 }
773 break;*/
774
775 default:
776 TRACE_BT("LocalDeviceImpl: Command Status not handled\n");
777 break;
778 }
779 }
780
781
782 void
InquiryResult(uint8 * numberOfResponses,BMessage * request)783 LocalDeviceImpl::InquiryResult(uint8* numberOfResponses, BMessage* request)
784 {
785 BMessage reply(BT_MSG_INQUIRY_DEVICE);
786
787 uint8 responses = *numberOfResponses;
788
789 // skipping here the number of responses
790 reply.AddData("info", B_ANY_TYPE, numberOfResponses + 1,
791 (*numberOfResponses) * sizeof(struct inquiry_info) );
792
793 reply.AddInt8("count", *numberOfResponses);
794
795 TRACE_BT("LocalDeviceImpl: %s #responses=%d\n",
796 __FUNCTION__, *numberOfResponses);
797
798 struct inquiry_info* info = JumpEventHeader<struct inquiry_info, uint8>
799 (numberOfResponses);
800
801 while (responses > 0) {
802 TRACE_BT("LocalDeviceImpl: page_rep=%d scan_period=%d, scan=%d clock=%d\n",
803 info->pscan_rep_mode, info->pscan_period_mode, info->pscan_mode,
804 info->clock_offset);
805 responses--;
806 info++;
807 }
808
809 printf("%s: Sending reply...\n", __func__);
810 status_t status = request->SendReply(&reply);
811 if (status < B_OK)
812 printf("%s: Error sending reply!\n", __func__);
813 }
814
815
816 void
InquiryComplete(uint8 * status,BMessage * request)817 LocalDeviceImpl::InquiryComplete(uint8* status, BMessage* request)
818 {
819 BMessage reply(BT_MSG_INQUIRY_COMPLETED);
820
821 reply.AddInt8("status", *status);
822
823 printf("%s: Sending reply...\n", __func__);
824 status_t stat = request->SendReply(&reply);
825 if (stat < B_OK)
826 printf("%s: Error sending reply!\n", __func__);
827
828 ClearWantedEvent(request);
829 }
830
831
832 void
RemoteNameRequestComplete(struct hci_ev_remote_name_request_complete_reply * remotename,BMessage * request)833 LocalDeviceImpl::RemoteNameRequestComplete(
834 struct hci_ev_remote_name_request_complete_reply* remotename,
835 BMessage* request)
836 {
837 BMessage reply;
838
839 if (remotename->status == BT_OK) {
840 reply.AddString("friendlyname", (const char*)remotename->remote_name );
841 }
842
843 reply.AddInt8("status", remotename->status);
844
845 TRACE_BT("LocalDeviceImpl: %s for %s with status %s\n",
846 BluetoothEvent(HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE),
847 bdaddrUtils::ToString(remotename->bdaddr).String(),
848 BluetoothError(remotename->status));
849
850 status_t status = request->SendReply(&reply);
851 if (status < B_OK)
852 printf("%s: Error sending reply to BMessage request: %s!\n",
853 __func__, strerror(status));
854
855 // This request is not gonna be used anymore
856 ClearWantedEvent(request);
857 }
858
859
860 void
ConnectionRequest(struct hci_ev_conn_request * event,BMessage * request)861 LocalDeviceImpl::ConnectionRequest(struct hci_ev_conn_request* event,
862 BMessage* request)
863 {
864 size_t size;
865 void* command;
866
867 TRACE_BT("LocalDeviceImpl: Connection Incoming type %x from %s...\n",
868 event->link_type, bdaddrUtils::ToString(event->bdaddr).String());
869
870 // TODO: add a possible request in the queue
871 if (true) { // Check Preferences if we are to accept this connection
872
873 // Keep ourselves as slave
874 command = buildAcceptConnectionRequest(event->bdaddr, 0x01 , &size);
875
876 BMessage* newrequest = new BMessage;
877 newrequest->AddInt16("eventExpected", HCI_EVENT_CMD_STATUS);
878 newrequest->AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL,
879 OCF_ACCEPT_CONN_REQ));
880
881 newrequest->AddInt16("eventExpected", HCI_EVENT_CONN_COMPLETE);
882 newrequest->AddInt16("eventExpected", HCI_EVENT_PIN_CODE_REQ);
883 newrequest->AddInt16("eventExpected", HCI_EVENT_ROLE_CHANGE);
884 newrequest->AddInt16("eventExpected", HCI_EVENT_LINK_KEY_NOTIFY);
885 newrequest->AddInt16("eventExpected",
886 HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE);
887
888 #if 0
889 newrequest->AddInt16("eventExpected", HCI_EVENT_MAX_SLOT_CHANGE);
890 newrequest->AddInt16("eventExpected", HCI_EVENT_DISCONNECTION_COMPLETE);
891 #endif
892
893 AddWantedEvent(newrequest);
894
895 if ((fHCIDelegate)->IssueCommand(command, size) == B_ERROR) {
896 TRACE_BT("LocalDeviceImpl: Command issued error for Accepting connection\n");
897 // remove the request?
898 } else {
899 TRACE_BT("LocalDeviceImpl: Command issued for Accepting connection\n");
900 }
901 }
902 }
903
904
905 void
ConnectionComplete(struct hci_ev_conn_complete * event,BMessage * request)906 LocalDeviceImpl::ConnectionComplete(struct hci_ev_conn_complete* event,
907 BMessage* request)
908 {
909
910 if (event->status == BT_OK) {
911 uint8 cod[3] = {0, 0, 0};
912
913 // TODO: Review, this rDevice is leaked
914 ConnectionIncoming* iConnection = new ConnectionIncoming(
915 new RemoteDevice(event->bdaddr, cod));
916 iConnection->Show();
917
918 TRACE_BT("LocalDeviceImpl: %s: Address %s handle=%#x type=%d encrypt=%d\n", __FUNCTION__,
919 bdaddrUtils::ToString(event->bdaddr).String(), event->handle,
920 event->link_type, event->encrypt_mode);
921
922 } else {
923 TRACE_BT("LocalDeviceImpl: %s: failed with error %s\n", __FUNCTION__,
924 BluetoothError(event->status));
925 }
926
927 // it was expected
928 if (request != NULL) {
929 BMessage reply;
930 reply.AddInt8("status", event->status);
931
932 if (event->status == BT_OK)
933 reply.AddInt16("handle", event->handle);
934
935 printf("%s: Sending reply...\n", __func__);
936 status_t status = request->SendReply(&reply);
937 if (status < B_OK)
938 printf("%s: Error sending reply!\n", __func__);
939 // debug reply.PrintToStream();
940
941 // This request is not gonna be used anymore
942 ClearWantedEvent(request);
943 }
944
945 }
946
947
948 void
DisconnectionComplete(struct hci_ev_disconnection_complete_reply * event,BMessage * request)949 LocalDeviceImpl::DisconnectionComplete(
950 struct hci_ev_disconnection_complete_reply* event, BMessage* request)
951 {
952 TRACE_BT("LocalDeviceImpl: %s: Handle=%#x, reason=%s status=%x\n", __FUNCTION__, event->handle,
953 BluetoothError(event->reason), event->status);
954
955 if (request != NULL) {
956 BMessage reply;
957 reply.AddInt8("status", event->status);
958
959 printf("%s: Sending reply...\n", __func__);
960 status_t status = request->SendReply(&reply);
961 if (status < B_OK)
962 printf("%s: Error sending reply!\n", __func__);
963 // debug reply.PrintToStream();
964
965 ClearWantedEvent(request);
966 }
967 }
968
969
970 void
PinCodeRequest(struct hci_ev_pin_code_req * event,BMessage * request)971 LocalDeviceImpl::PinCodeRequest(struct hci_ev_pin_code_req* event,
972 BMessage* request)
973 {
974 PincodeWindow* iPincode = new PincodeWindow(event->bdaddr, GetID());
975 iPincode->Show();
976 }
977
978
979 void
RoleChange(hci_ev_role_change * event,BMessage * request)980 LocalDeviceImpl::RoleChange(hci_ev_role_change* event, BMessage* request)
981 {
982 TRACE_BT("LocalDeviceImpl: %s: Address %s role=%d status=%d\n", __FUNCTION__,
983 bdaddrUtils::ToString(event->bdaddr).String(), event->role, event->status);
984 }
985
986
987 void
PageScanRepetitionModeChange(struct hci_ev_page_scan_rep_mode_change * event,BMessage * request)988 LocalDeviceImpl::PageScanRepetitionModeChange(
989 struct hci_ev_page_scan_rep_mode_change* event, BMessage* request)
990 {
991 TRACE_BT("LocalDeviceImpl: %s: Address %s type=%d\n", __FUNCTION__,
992 bdaddrUtils::ToString(event->bdaddr).String(), event->page_scan_rep_mode);
993 }
994
995
996 void
LinkKeyNotify(hci_ev_link_key_notify * event,BMessage * request)997 LocalDeviceImpl::LinkKeyNotify(hci_ev_link_key_notify* event,
998 BMessage* request)
999 {
1000 TRACE_BT("LocalDeviceImpl: %s: Address %s, key=%s, type=%d\n", __FUNCTION__,
1001 bdaddrUtils::ToString(event->bdaddr).String(),
1002 LinkKeyUtils::ToString(event->link_key).String(), event->key_type);
1003 }
1004
1005
1006 void
LinkKeyRequested(struct hci_ev_link_key_req * keyRequested,BMessage * request)1007 LocalDeviceImpl::LinkKeyRequested(struct hci_ev_link_key_req* keyRequested,
1008 BMessage* request)
1009 {
1010 TRACE_BT("LocalDeviceImpl: %s: Address %s\n", __FUNCTION__,
1011 bdaddrUtils::ToString(keyRequested->bdaddr).String());
1012
1013 // TODO:
1014 // Here we are suposed to check the BDADDR received, look into the server
1015 // (RemoteDevice Database) if we have any pas link key interchanged with
1016 // the given address if we have we are to accept it will "Link key Request
1017 // Reply". As we dont not have such database yet, we will always deny it
1018 // forcing the remote device to start a pairing.
1019
1020 BluetoothCommand<typed_command(hci_cp_link_key_neg_reply)>
1021 linkKeyNegativeReply(OGF_LINK_CONTROL, OCF_LINK_KEY_NEG_REPLY);
1022
1023 bdaddrUtils::Copy(linkKeyNegativeReply->bdaddr, keyRequested->bdaddr);
1024
1025 if ((fHCIDelegate)->IssueCommand(linkKeyNegativeReply.Data(),
1026 linkKeyNegativeReply.Size()) == B_ERROR) {
1027 TRACE_BT("LocalDeviceImpl: Command issued error for reply %s\n", __FUNCTION__);
1028 } else {
1029 TRACE_BT("LocalDeviceImpl: Command issued in reply of %s\n", __FUNCTION__);
1030 }
1031
1032 if (request != NULL)
1033 ClearWantedEvent(request, HCI_EVENT_LINK_KEY_REQ);
1034
1035 }
1036
1037
1038 void
ReturnLinkKeys(struct hci_ev_return_link_keys * returnedKeys)1039 LocalDeviceImpl::ReturnLinkKeys(struct hci_ev_return_link_keys* returnedKeys)
1040 {
1041 TRACE_BT("LocalDeviceImpl: %s: #keys=%d\n",
1042 __FUNCTION__, returnedKeys->num_keys);
1043
1044 uint8 numKeys = returnedKeys->num_keys;
1045
1046 struct link_key_info* linkKeys = &returnedKeys->link_keys;
1047
1048 while (numKeys > 0) {
1049
1050 TRACE_BT("LocalDeviceImpl: Address=%s key=%s\n",
1051 bdaddrUtils::ToString(linkKeys->bdaddr).String(),
1052 LinkKeyUtils::ToString(linkKeys->link_key).String());
1053
1054 linkKeys++;
1055 }
1056 }
1057
1058
1059 void
MaxSlotChange(struct hci_ev_max_slot_change * event,BMessage * request)1060 LocalDeviceImpl::MaxSlotChange(struct hci_ev_max_slot_change* event,
1061 BMessage* request)
1062 {
1063 TRACE_BT("LocalDeviceImpl: %s: Handle=%#x, max slots=%d\n", __FUNCTION__,
1064 event->handle, event->lmp_max_slots);
1065 }
1066
1067
1068 void
HardwareError(struct hci_ev_hardware_error * event)1069 LocalDeviceImpl::HardwareError(struct hci_ev_hardware_error* event)
1070 {
1071 TRACE_BT("LocalDeviceImpl: %s: hardware code=%#x\n", __FUNCTION__, event->hardware_code);
1072 }
1073
1074
1075 void
NumberOfCompletedPackets(struct hci_ev_num_comp_pkts * event)1076 LocalDeviceImpl::NumberOfCompletedPackets(struct hci_ev_num_comp_pkts* event)
1077 {
1078 TRACE_BT("LocalDeviceImpl: %s: #Handles=%d\n", __FUNCTION__, event->num_hndl);
1079
1080 struct handle_and_number* numberPackets
1081 = JumpEventHeader<handle_and_number, hci_ev_num_comp_pkts>(event);
1082
1083 for (uint8 i = 0; i < event->num_hndl; i++) {
1084
1085 TRACE_BT("LocalDeviceImpl: %s: Handle=%d #packets=%d\n", __FUNCTION__, numberPackets->handle,
1086 numberPackets->num_completed);
1087
1088 numberPackets++;
1089 }
1090 }
1091
1092
1093 #if 0
1094 #pragma mark - Request Methods -
1095 #endif
1096
1097 status_t
ProcessSimpleRequest(BMessage * request)1098 LocalDeviceImpl::ProcessSimpleRequest(BMessage* request)
1099 {
1100 ssize_t size;
1101 void* command = NULL;
1102
1103 if (request->FindData("raw command", B_ANY_TYPE, 0,
1104 (const void **)&command, &size) == B_OK) {
1105
1106 // Give the chance of just issuing the command
1107 int16 eventFound;
1108 if (request->FindInt16("eventExpected", &eventFound) == B_OK)
1109 AddWantedEvent(request);
1110 // LEAK: is command buffer freed within the Message?
1111 if (((HCITransportAccessor*)fHCIDelegate)->IssueCommand(command, size)
1112 == B_ERROR) {
1113 // TODO:
1114 // Reply the request with error!
1115 // Remove the just added request
1116 TRACE_BT("LocalDeviceImpl: ## ERROR Command issue, REMOVING!\n");
1117 ClearWantedEvent(request);
1118
1119 } else {
1120 return B_OK;
1121 }
1122 } else {
1123 TRACE_BT("LocalDeviceImpl: No command specified for simple request\n");
1124 }
1125
1126 return B_ERROR;
1127 }
1128