xref: /haiku/src/servers/bluetooth/LocalDeviceImpl.cpp (revision 96490327ca254c5b2e989fb3fc20c4d36c2c6f93)
1 /*
2  * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
3  *
4  * All rights reserved. Distributed under the terms of the MIT License.
5  *
6  */
7 
8 
9 #include "BluetoothServer.h"
10 
11 #include "LocalDeviceImpl.h"
12 #include "CommandManager.h"
13 #include "Output.h"
14 
15 #include <bluetooth/bluetooth_error.h>
16 #include <bluetooth/HCI/btHCI_event.h>
17 
18 #include <bluetoothserver_p.h>
19 #include <ConnectionIncoming.h>
20 #include <PincodeWindow.h>
21 
22 #include <stdio.h>
23 
24 
25 #if 0
26 #pragma mark - Class methods -
27 #endif
28 
29 
30 // Factory methods
31 LocalDeviceImpl*
32 LocalDeviceImpl::CreateControllerAccessor(BPath* path)
33 {
34     HCIDelegate* hd = new HCIControllerAccessor(path);
35 
36     if ( hd != NULL)
37         return new LocalDeviceImpl(hd);
38     else
39         return NULL;
40 }
41 
42 
43 LocalDeviceImpl*
44 LocalDeviceImpl::CreateTransportAccessor(BPath* path)
45 {
46     HCIDelegate* hd = new HCITransportAccessor(path);
47 
48     if ( hd != NULL)
49         return new LocalDeviceImpl(hd);
50     else
51         return NULL;
52 }
53 
54 
55 LocalDeviceImpl::LocalDeviceImpl(HCIDelegate* hd) : LocalDeviceHandler(hd)
56 {
57 
58 }
59 
60 #if 0
61 #pragma mark - Event handling methods -
62 #endif
63 
64 void
65 LocalDeviceImpl::HandleEvent(struct hci_event_header* event)
66 {
67 
68 printf("### Event comming: len = %d\n", event->elen);
69 for (int16 index = 0 ; index < event->elen + 2; index++ ) {
70 	printf("%x:",((uint8*)event)[index]);
71 }
72 printf("### \n");
73 
74 	// Events here might have not been initated by us
75     switch (event->ecode) {
76 	        case HCI_EVENT_HARDWARE_ERROR:
77    				//HardwareError(event);
78    			return;
79 			case HCI_EVENT_CONN_REQUEST:
80 
81 			break;
82 
83 			case HCI_EVENT_CONN_COMPLETE:
84 				ConnectionComplete((struct hci_ev_conn_complete*)(event+1), NULL); // should belong to a request?
85 
86 			break;
87 
88 			case HCI_EVENT_PIN_CODE_REQ:
89 				PinCodeRequest((struct hci_ev_pin_code_req*)(event+1), NULL);
90 			break;
91 
92 
93    			default:
94    				// lets go on
95    			break;
96 	}
97 
98 
99 
100 	BMessage* request = NULL;
101 
102 	// Check if its a requested one
103 	if ( event->ecode == HCI_EVENT_CMD_COMPLETE ) {
104 
105 		(Output::Instance()->Post("Incoming Command Complete\n", BLACKBOARD_EVENTS));
106 		request = FindPetition(event->ecode, ((struct hci_ev_cmd_complete*)(event+1))->opcode );
107 
108 	} else if ( event->ecode == HCI_EVENT_CMD_STATUS ) {
109 
110 		(Output::Instance()->Post("Incoming Command Status\n", BLACKBOARD_EVENTS));
111 		request = FindPetition(event->ecode, ((struct hci_ev_cmd_status*)(event+1))->opcode );
112 
113 	} else
114 	{
115 		request = FindPetition(event->ecode);
116 	}
117 
118 	if ( request == NULL) {
119 		(Output::Instance()->Post("Event could not be understood or delivered\n", BLACKBOARD_EVENTS));
120 		return;
121 	}
122 
123 	// we are waiting for a reply
124 	switch (event->ecode) {
125 		case HCI_EVENT_INQUIRY_COMPLETE:
126     		InquiryComplete((uint8*)(event+1), request);
127     	break;
128 
129     	case HCI_EVENT_INQUIRY_RESULT:
130     		InquiryResult((uint8*)(event+1), request);
131 		break;
132 
133 		case HCI_EVENT_DISCONNECTION_COMPLETE:
134 
135 		break;
136 
137 		case HCI_EVENT_AUTH_COMPLETE:
138 		break;
139 
140 		case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE:
141 			RemoteNameRequestComplete((struct hci_remote_name_request_complete_reply*)(event+1), request);
142 		break;
143 
144 		case HCI_EVENT_ENCRYPT_CHANGE:
145 		break;
146 
147 		case HCI_EVENT_CHANGE_CONN_LINK_KEY_COMPLETE:
148 		break;
149 
150 		case HCI_EVENT_MASTER_LINK_KEY_COMPL:
151 		break;
152 
153 		case HCI_EVENT_RMT_FEATURES:
154 		break;
155 
156 		case HCI_EVENT_RMT_VERSION:
157 		break;
158 
159 		case HCI_EVENT_QOS_SETUP_COMPLETE:
160 		break;
161 
162 		case HCI_EVENT_CMD_COMPLETE:
163 			CommandComplete((struct hci_ev_cmd_complete*)(event+1), request);
164  		break;
165 
166  		case HCI_EVENT_CMD_STATUS:
167  			CommandStatus((struct hci_ev_cmd_status*)(event+1), request);
168 		break;
169 
170 		case HCI_EVENT_FLUSH_OCCUR:
171 		break;
172 
173 		case HCI_EVENT_ROLE_CHANGE:
174 		break;
175 
176 		case HCI_EVENT_NUM_COMP_PKTS:
177 		break;
178 
179 		case HCI_EVENT_MODE_CHANGE:
180 		break;
181 
182 		case HCI_EVENT_RETURN_LINK_KEYS:
183 		break;
184 
185 		case HCI_EVENT_LINK_KEY_REQ:
186 		break;
187 
188 		case HCI_EVENT_LINK_KEY_NOTIFY:
189 		break;
190 
191 		case HCI_EVENT_LOOPBACK_COMMAND:
192 		break;
193 
194 		case HCI_EVENT_DATA_BUFFER_OVERFLOW:
195 		break;
196 
197 		case HCI_EVENT_MAX_SLOT_CHANGE:
198 		break;
199 
200 		case HCI_EVENT_READ_CLOCK_OFFSET_COMPL:
201 		break;
202 
203 		case HCI_EVENT_CON_PKT_TYPE_CHANGED:
204 		break;
205 
206 		case HCI_EVENT_QOS_VIOLATION:
207 		break;
208 
209 		case HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE:
210 		break;
211 
212 		case HCI_EVENT_FLOW_SPECIFICATION:
213 		break;
214 
215 		case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI:
216 		break;
217 
218 		case HCI_EVENT_REMOTE_EXTENDED_FEATURES:
219 		break;
220 
221 		case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETED:
222 		break;
223 
224 		case HCI_EVENT_SYNCHRONOUS_CONNECTION_CHANGED:
225 
226 		break;
227 	}
228 
229 }
230 
231 
232 void
233 LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, BMessage* request) {
234 
235 	int16   opcodeExpected;
236 	BMessage reply;
237 
238     Output::Instance()->Post(__FUNCTION__, BLACKBOARD_LD_OFFSET + GetID());
239     Output::Instance()->Post("\n", BLACKBOARD_LD_OFFSET + GetID());
240 
241 	// Handle command complete information
242 	// FIX ME! the expected code might me in another
243 	// index as is relative to the event not the request
244     request->FindInt16("opcodeExpected", 0 /*REVIEW!*/, &opcodeExpected);
245 
246 
247 	if (request->IsSourceWaiting() == false)
248 		Output::Instance()->Post("Nobody waiting for the event\n", BLACKBOARD_KIT);
249 
250     switch (opcodeExpected) {
251 
252         case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR):
253         {
254         	struct hci_rp_read_bd_addr* readbdaddr = (struct hci_rp_read_bd_addr*)(event+1);
255 
256             if (readbdaddr->status == BT_OK) {
257 
258                 reply.AddData("bdaddr", B_ANY_TYPE, &readbdaddr->bdaddr, sizeof(bdaddr_t));
259                 reply.AddInt32("status", readbdaddr->status);
260 
261                 printf("Sending reply ... %ld\n",request->SendReply(&reply));
262                 reply.PrintToStream();
263 
264 			    Output::Instance()->Post("Positive reply for getAdress\n", BLACKBOARD_KIT);
265 
266             } else {
267                 reply.AddInt8("status", readbdaddr->status);
268                 request->SendReply(&reply);
269 			    Output::Instance()->Post("Negative reply for getAdress\n", BLACKBOARD_KIT);
270             }
271 
272  			// This request is not genna be used anymore
273             ClearWantedEvent(request);
274      	}
275         break;
276 
277         case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME):
278         {
279         	struct hci_rp_read_local_name* readLocalName = (struct hci_rp_read_local_name*)(event+1);
280 
281         	reply.AddInt8("status", readLocalName->status);
282 
283             if (readLocalName->status == BT_OK) {
284 
285                 reply.AddString("friendlyname", (const char*)readLocalName->local_name );
286 			    Output::Instance()->Post("Positive reply for friendly name\n", BLACKBOARD_KIT);
287 
288             } else {
289 
290 			    Output::Instance()->Post("Negative reply for friendly name\n", BLACKBOARD_KIT);
291 
292             }
293 
294             printf("Sending reply ... %ld\n",request->SendReply(&reply));
295             reply.PrintToStream();
296 
297  			// This request is not genna be used anymore
298             ClearWantedEvent(request);
299      	}
300         break;
301 
302         case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_WRITE_SCAN_ENABLE):
303         {
304         	uint8* statusReply = (uint8*)(event+1);
305 
306         	reply.AddInt8("status", *statusReply);
307 
308             if (*statusReply == BT_OK) {
309 
310                 Output::Instance()->Post("Positive reply for scanmode\n", BLACKBOARD_KIT);
311 
312             } else {
313 
314                 Output::Instance()->Post("Negative reply for scanmode\n", BLACKBOARD_KIT);
315 
316             }
317 
318             printf("Sending reply ... %ld\n",request->SendReply(&reply));
319             reply.PrintToStream();
320 
321  			// This request is not genna be used anymore
322             ClearWantedEvent(request);
323      	}
324         break;
325 
326 		default:
327 		    Output::Instance()->Post("Command Complete not handled\n", BLACKBOARD_KIT);
328 		break;
329 
330     }
331 }
332 
333 
334 void
335 LocalDeviceImpl::CommandStatus(struct hci_ev_cmd_status* event, BMessage* request) {
336 
337 	int16   opcodeExpected;
338 	BMessage reply;
339 
340     Output::Instance()->Post(__FUNCTION__, BLACKBOARD_LD_OFFSET + GetID());
341     Output::Instance()->Post("\n", BLACKBOARD_LD_OFFSET + GetID());
342 
343 	// Handle command complete information
344     request->FindInt16("opcodeExpected", 0 /*REVIEW!*/, &opcodeExpected);
345 
346 
347 	if (request->IsSourceWaiting() == false)
348 		Output::Instance()->Post("Nobody waiting for the event\n", BLACKBOARD_KIT);
349 
350 
351     switch (opcodeExpected) {
352 
353         case PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY):
354         {
355         	reply.what = BT_MSG_INQUIRY_STARTED;
356         	reply.AddInt8("status", event->status);
357 
358             if (event->status == BT_OK) {
359 			    Output::Instance()->Post("Positive reply for inquiry status\n", BLACKBOARD_KIT);
360             } else {
361 			    Output::Instance()->Post("Negative reply for inquiry status\n", BLACKBOARD_KIT);
362             }
363 
364             printf("Sending reply ... %ld\n", request->SendReply(&reply));
365             reply.PrintToStream();
366 
367             ClearWantedEvent(request, HCI_EVENT_CMD_STATUS, PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY));
368      	}
369         break;
370 
371 		default:
372 		    Output::Instance()->Post("Command Status not handled\n", BLACKBOARD_KIT);
373 		break;
374 	}
375 
376 }
377 
378 
379 void
380 LocalDeviceImpl::InquiryResult(uint8* numberOfResponses, BMessage* request)
381 {
382 
383 	BMessage reply(BT_MSG_INQUIRY_DEVICE);
384 
385 
386     reply.AddData("info", B_ANY_TYPE, numberOfResponses+1 // skiping here the number of responses
387                         , (*numberOfResponses) * sizeof(struct inquiry_info) );
388 
389     printf("%s: Sending reply ... %ld\n",__FUNCTION__, request->SendReply(&reply));
390 
391 }
392 
393 
394 void
395 LocalDeviceImpl::InquiryComplete(uint8* status, BMessage* request)
396 {
397 	BMessage reply(BT_MSG_INQUIRY_COMPLETED);
398 
399 	reply.AddInt8("status", *status);
400 
401 
402     printf("%s: Sending reply ... %ld\n",__FUNCTION__, request->SendReply(&reply));
403 //    (request->ReturnAddress()).SendMessage(&reply);
404 
405     ClearWantedEvent(request);
406 }
407 
408 
409 void
410 LocalDeviceImpl::RemoteNameRequestComplete(struct hci_remote_name_request_complete_reply* remotename, BMessage* request)
411 {
412 	BMessage reply;
413 
414   	reply.AddInt8("status", remotename->status);
415 
416     if (remotename->status == BT_OK) {
417 
418         reply.AddString("friendlyname", (const char*)remotename->remote_name );
419 	    Output::Instance()->Post("Positive reply for remote friendly name\n", BLACKBOARD_KIT);
420 
421     } else {
422 
423 	    Output::Instance()->Post("Negative reply for remote friendly name\n", BLACKBOARD_KIT);
424 
425     }
426 
427     printf("Sending reply ... %ld\n", request->SendReply(&reply));
428     reply.PrintToStream();
429 
430 	// This request is not genna be used anymore
431 	// Although there are many middle events that should be tracked todo: ticket 2377
432     ClearWantedEvent(request);
433 
434 }
435 
436 
437 void
438 LocalDeviceImpl::ConnectionComplete(struct hci_ev_conn_complete* event, BMessage* request)
439 {
440 	ConnectionIncoming* iConnection = new ConnectionIncoming(NULL);
441 	iConnection->Show();
442 
443 }
444 
445 
446 void
447 LocalDeviceImpl::PinCodeRequest(struct hci_ev_pin_code_req* event, BMessage* request)
448 {
449 	PincodeWindow* iPincode = new PincodeWindow(NULL);
450 	iPincode->Show();
451 
452 }
453 
454 #if 0
455 #pragma mark - Request Methods -
456 #endif
457 
458 
459 status_t
460 LocalDeviceImpl::GetAddress(bdaddr_t* bdaddr, BMessage* request)
461 {
462 	ssize_t size;
463 
464 	if (fProperties->FindData("bdaddr", B_ANY_TYPE, 0, (const void **)bdaddr, &size) == B_OK) {
465 
466 		(Output::Instance()->Post("BDADDR already present in server\n", BLACKBOARD_EVENTS));
467 	    /* We have this info, returning back */
468 	    return B_OK;
469 
470 	} else {
471 		size_t size;
472 
473 	    void* command = buildReadBdAddr(&size);
474 
475 	    /* Adding a wanted event in the queue */
476 	    request->AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
477 	    request->AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR));
478 
479 	    printf("Adding request... %p\n", request);
480 	    AddWantedEvent(request);
481 		request->PrintToStream();
482 
483 	    if (((HCITransportAccessor*)fHCIDelegate)->IssueCommand(command, size) == B_ERROR)
484 			(Output::Instance()->Post("Command issue error\n", BLACKBOARD_EVENTS));
485 
486 		(Output::Instance()->Post("Command issued for GetAddress\n", BLACKBOARD_EVENTS));
487 	    return B_WOULD_BLOCK;
488 	}
489 
490 }
491 
492 
493 status_t
494 LocalDeviceImpl::GetFriendlyName(BString str, BMessage* request)
495 {
496 
497 	if (fProperties->FindString("friendlyname", &str) == B_OK) {
498 
499 		(Output::Instance()->Post("Friendly name already present in server\n", BLACKBOARD_EVENTS));
500 	    /* We have this info, returning back */
501 	    return B_OK;
502 
503 	} else {
504 		size_t size;
505 
506 	    void* command = buildReadLocalName(&size);
507 
508 	    /* Adding a wanted event in the queue */
509 	    request->AddInt16("eventExpected",  HCI_EVENT_CMD_COMPLETE);
510 	    request->AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME));
511 
512 	    printf("Adding request... %p\n", request);
513 	    AddWantedEvent(request);
514 		request->PrintToStream();
515 
516 	    if (((HCITransportAccessor*)fHCIDelegate)->IssueCommand(command, size) == B_ERROR)
517 			(Output::Instance()->Post("Command issue error\n", BLACKBOARD_EVENTS));
518 
519 		(Output::Instance()->Post("Command issued for GetFriendlyname\n", BLACKBOARD_EVENTS));
520 
521 	    return B_WOULD_BLOCK;
522 	}
523 
524 }
525 
526 
527 status_t
528 LocalDeviceImpl::ProcessSimpleRequest(BMessage* request)
529 {
530 	ssize_t size;
531 	void* command = NULL;
532 
533 	if (request->FindData("raw command", B_ANY_TYPE, 0, (const void **)&command, &size) == B_OK)
534 	    if (((HCITransportAccessor*)fHCIDelegate)->IssueCommand(command, size) == B_ERROR)
535 			(Output::Instance()->Post("Command issue error\n", BLACKBOARD_EVENTS));
536 		else
537 		{
538 		    AddWantedEvent(request);
539 			return B_OK;
540 		}
541 	else {
542 		(Output::Instance()->Post("No command specified for simple request\n", BLACKBOARD_KIT));
543 	}
544 
545 	return B_ERROR;
546 }
547