bluetooth_server: a really young piece of meat, code not even to be looked at. Bad/fast code in some modules. But better here than in a crashed partition.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24282 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
2be1278e76
commit
30f1d1f363
93
src/servers/bluetooth/BPortNot.cpp
Normal file
93
src/servers/bluetooth/BPortNot.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||
*
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "BPortNot.h"
|
||||
#include "Output.h"
|
||||
|
||||
#include "BluetoothServer.h"
|
||||
#include "LocalDeviceImpl.h"
|
||||
|
||||
#include <bluetooth/HCI/btHCI_event.h>
|
||||
#include <bluetooth/HCI/btHCI_transport.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
BPortNot::BPortNot(BluetoothServer* app, const char* name) {
|
||||
|
||||
ourapp = (BluetoothServer*) app;
|
||||
|
||||
fPort = find_port(name);
|
||||
if ( fPort == B_NAME_NOT_FOUND )
|
||||
{
|
||||
fPort = create_port(256, name);
|
||||
Output::Instance()->Post("Event Listener Port Created\n",BLACKBOARD_GENERAL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BPortNot::loop()
|
||||
{
|
||||
size_t size;
|
||||
size_t ssize;
|
||||
int32 code;
|
||||
|
||||
struct hci_event_header *hdr;
|
||||
|
||||
LocalDeviceImpl* ld;
|
||||
|
||||
while (code != HCI_HAIKU_EVENT_SERVER_QUITTING) {
|
||||
|
||||
size = port_buffer_size(fPort);
|
||||
|
||||
/* TODO: Consider using snb_buff like structure here or
|
||||
max event size to prevent mallocs & frees */
|
||||
hdr = (struct hci_event_header *) malloc(size);
|
||||
ssize = read_port(fPort, &code, hdr, size);
|
||||
|
||||
if (size != ssize) {
|
||||
Output::Instance()->Post("Event size not matching", BLACKBOARD_GENERAL);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (size <= 0) {
|
||||
Output::Instance()->Post("Suspicious empty event", BLACKBOARD_GENERAL);
|
||||
continue;
|
||||
}
|
||||
|
||||
// we only handle events
|
||||
if (GET_PORTCODE_TYPE(code)!= BT_EVENT) {
|
||||
Output::Instance()->Post("Wrong type frame code", BLACKBOARD_GENERAL);
|
||||
continue;
|
||||
}
|
||||
|
||||
#if 0
|
||||
for (int i=0 ; i<ssize ; i++ ) {
|
||||
printf("%x:",((uint8*)hdr)[i]);
|
||||
}
|
||||
printf("$\n");
|
||||
|
||||
for (int i=0 ; i<ssize ; i++) {
|
||||
printf("%c",((uint8*)hdr)[i]);
|
||||
}
|
||||
printf("$\n");
|
||||
#endif
|
||||
|
||||
ld = ourapp->LocateLocalDeviceImpl(GET_PORTCODE_HID(code));
|
||||
if (ld == NULL) {
|
||||
Output::Instance()->Post("LocalDevice could not be fetched", BLACKBOARD_EVENTS);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
ld->HandleEvent(hdr);
|
||||
|
||||
|
||||
// free the event
|
||||
free(hdr);
|
||||
}
|
||||
|
||||
}
|
28
src/servers/bluetooth/BPortNot.h
Normal file
28
src/servers/bluetooth/BPortNot.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||
*
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _BT_PORT_NOTIFICATION
|
||||
#define _BT_PORT_NOTIFICATION
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
class BluetoothServer;
|
||||
|
||||
class BPortNot {
|
||||
|
||||
public:
|
||||
BPortNot(BluetoothServer* app, const char* name) ;
|
||||
void loop();
|
||||
|
||||
port_id fPort;
|
||||
port_id sdp_request_port;
|
||||
thread_id sdp_server_thread;
|
||||
|
||||
BluetoothServer* ourapp;
|
||||
};
|
||||
|
||||
#endif
|
559
src/servers/bluetooth/BluetoothServer.cpp
Normal file
559
src/servers/bluetooth/BluetoothServer.cpp
Normal file
@ -0,0 +1,559 @@
|
||||
/*
|
||||
* Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||
*
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
#include <Entry.h>
|
||||
#include <Path.h>
|
||||
#include <Message.h>
|
||||
#include <Directory.h>
|
||||
#include <String.h>
|
||||
#include <Roster.h>
|
||||
|
||||
|
||||
#include <TypeConstants.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <bluetoothserver_p.h>
|
||||
#include <bluetooth/HCI/btHCI_command.h>
|
||||
#include <bluetooth/bluetooth_util.h>
|
||||
|
||||
#include "LocalDeviceImpl.h"
|
||||
#include "BluetoothServer.h"
|
||||
#include "Output.h"
|
||||
|
||||
|
||||
BluetoothServer::BluetoothServer() : BApplication(BLUETOOTH_SIGNATURE)
|
||||
{
|
||||
Output::Instance()->Run();
|
||||
Output::Instance()->SetTitle("Bluetooth message gathering");
|
||||
|
||||
Output::Instance()->AddTab("General", BLACKBOARD_GENERAL);
|
||||
Output::Instance()->AddTab("Device Manager", BLACKBOARD_DEVICEMANAGER);
|
||||
Output::Instance()->AddTab("Events", BLACKBOARD_EVENTS);
|
||||
Output::Instance()->AddTab("Kit", BLACKBOARD_KIT);
|
||||
|
||||
|
||||
ShowWindow(Output::Instance());
|
||||
|
||||
fDeviceManager = new DeviceManager();
|
||||
fLocalDevicesList.MakeEmpty();
|
||||
|
||||
fEventListener = spawn_thread(notification_Thread, "BT port listener" , B_DISPLAY_PRIORITY , this);
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool BluetoothServer::QuitRequested(void)
|
||||
{
|
||||
// Finish quitting
|
||||
Output::Instance()->Lock();
|
||||
Output::Instance()->Quit();
|
||||
|
||||
|
||||
/* HCIDelegate *hd = NULL;
|
||||
while ((hd = (HCIDelegate *)fDelegatesList.RemoveItem((int32)0)) !=NULL)
|
||||
delete hd;
|
||||
*/
|
||||
|
||||
printf("Accepting quitting of the application\n");
|
||||
return BApplication::QuitRequested();
|
||||
}
|
||||
|
||||
void BluetoothServer::ArgvReceived(int32 argc, char **argv)
|
||||
{
|
||||
if (argc>1) {
|
||||
if (strcmp(argv[1], "--finish") == 0)
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
|
||||
else {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void BluetoothServer::ReadyToRun(void) {
|
||||
|
||||
fDeviceManager->StartMonitoringDevice("bluetooth/h2generic");
|
||||
|
||||
|
||||
// Launch the notifier thread
|
||||
if ( resume_thread(fEventListener) != B_OK )
|
||||
{
|
||||
Output::Instance()->Post("Bluetooth port listener failed\n", BLACKBOARD_GENERAL);
|
||||
}
|
||||
|
||||
Output::Instance()->Post("Bluetooth server Ready\n", BLACKBOARD_GENERAL);
|
||||
}
|
||||
|
||||
void BluetoothServer::AppActivated(bool act) {
|
||||
|
||||
printf("Activated %d\n",act);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BluetoothServer::MessageReceived(BMessage *message)
|
||||
{
|
||||
BMessage reply;
|
||||
status_t status = B_WOULD_BLOCK; // mark somehow.. do not reply anything
|
||||
|
||||
switch(message->what)
|
||||
{
|
||||
|
||||
case BT_MSG_ADD_DEVICE:
|
||||
{
|
||||
BString str;
|
||||
message->FindString("name", &str);
|
||||
BPath path(str.String());
|
||||
|
||||
(Output::Instance()->Post( str.String(), BLACKBOARD_GENERAL));
|
||||
(Output::Instance()->Post(" requested LocalDevice\n", BLACKBOARD_GENERAL));
|
||||
|
||||
LocalDeviceImpl* ldi = LocalDeviceImpl::CreateTransportAccessor(&path);
|
||||
|
||||
if (ldi->GetID() >= 0) {
|
||||
fLocalDevicesList.AddItem(ldi);
|
||||
Output::Instance()->AddTab("Local Device", BLACKBOARD_LD_OFFSET + ldi->GetID());
|
||||
(Output::Instance()->Post( str.String(), BLACKBOARD_LD_OFFSET + ldi->GetID()));
|
||||
(Output::Instance()->Post(" LocalDevice added\n", BLACKBOARD_LD_OFFSET + ldi->GetID()));
|
||||
|
||||
|
||||
} else {
|
||||
(Output::Instance()->Post("Adding LocalDevice failed\n", BLACKBOARD_GENERAL));
|
||||
}
|
||||
|
||||
status = B_WOULD_BLOCK;
|
||||
}
|
||||
|
||||
case BT_MSG_COUNT_LOCAL_DEVICES:
|
||||
status = HandleLocalDevicesCount(message, &reply);
|
||||
break;
|
||||
|
||||
case BT_MSG_ADQUIRE_LOCAL_DEVICE:
|
||||
status = HandleAcquireLocalDevice(message, &reply);
|
||||
break;
|
||||
|
||||
case BT_MSG_GET_FRIENDLY_NAME:
|
||||
status = HandleGetFriendlyName(message, &reply);
|
||||
break;
|
||||
|
||||
case BT_MSG_GET_ADDRESS:
|
||||
status = HandleGetAddress(message, &reply);
|
||||
break;
|
||||
|
||||
case BT_MSG_HANDLE_SIMPLE_REQUEST:
|
||||
status = HandleSimpleRequest(message, &reply);
|
||||
break;
|
||||
|
||||
|
||||
/* Handle if the bluetooth preferences is running */
|
||||
case B_SOME_APP_LAUNCHED:
|
||||
{
|
||||
const char *signature;
|
||||
// TODO: what's this for?
|
||||
if (message->FindString("be:signature", &signature)==B_OK) {
|
||||
printf("input_server : %s\n", signature);
|
||||
if (strcmp(signature, "application/x-vnd.Be-TSKB")==0) {
|
||||
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
BApplication::MessageReceived(message);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Can we reply right now? */
|
||||
if (status != B_WOULD_BLOCK) {
|
||||
reply.AddInt32("status", status);
|
||||
message->SendReply(&reply);
|
||||
printf("Sending reply message\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
LocalDeviceImpl*
|
||||
BluetoothServer::LocateDelegateFromMessage(BMessage* message)
|
||||
{
|
||||
LocalDeviceImpl* ldi = NULL;
|
||||
hci_id hid;
|
||||
|
||||
if (message->FindInt32("hci_id", &hid) == B_OK)
|
||||
{
|
||||
/* Try to find out when a ID was specified */
|
||||
int index;
|
||||
|
||||
for (index = 0; index < fLocalDevicesList.CountItems() ; index ++) {
|
||||
|
||||
ldi = fLocalDevicesList.ItemAt(index);
|
||||
if (ldi->GetID() == hid) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ldi;
|
||||
}
|
||||
|
||||
LocalDeviceImpl*
|
||||
BluetoothServer::LocateLocalDeviceImpl(hci_id hid)
|
||||
{
|
||||
|
||||
/* Try to find out when a ID was specified */
|
||||
int index;
|
||||
|
||||
for (index = 0; index < fLocalDevicesList.CountItems() ; index ++) {
|
||||
|
||||
LocalDeviceImpl* ldi = fLocalDevicesList.ItemAt(index);
|
||||
if (ldi->GetID() == hid) {
|
||||
return ldi;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
#pragma - Messages reply
|
||||
#endif
|
||||
|
||||
status_t
|
||||
BluetoothServer::HandleLocalDevicesCount(BMessage* message, BMessage* reply)
|
||||
{
|
||||
return reply->AddInt32("count", fLocalDevicesList.CountItems());
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BluetoothServer::HandleAcquireLocalDevice(BMessage* message, BMessage* reply)
|
||||
{
|
||||
hci_id hid;
|
||||
ssize_t size;
|
||||
bdaddr_t bdaddr;
|
||||
LocalDeviceImpl* ldi = NULL;
|
||||
int32 index = 0;
|
||||
|
||||
if (message->FindInt32("hci_id", &hid) == B_OK)
|
||||
{
|
||||
Output::Instance()->Post("GetLocalDevice requested with id\n", BLACKBOARD_KIT);
|
||||
ldi = LocateDelegateFromMessage(message);
|
||||
|
||||
} else if (message->FindData("bdaddr", B_ANY_TYPE, (const void**)&bdaddr, &size ) == B_OK)
|
||||
{
|
||||
/* Try to find out when the user specified the address */
|
||||
Output::Instance()->Post("GetLocalDevice requested with bdaddr\n", BLACKBOARD_KIT);
|
||||
for (index = 0; index < fLocalDevicesList.CountItems() ; index ++) {
|
||||
|
||||
bdaddr_t local;
|
||||
ldi = fLocalDevicesList.ItemAt(index);
|
||||
if ((ldi->GetAddress(&local, message) == B_OK) && bacmp(&local, &bdaddr)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else
|
||||
{
|
||||
/* Careless, any device not performing operations will be fine */
|
||||
Output::Instance()->Post("GetLocalDevice requested\n", BLACKBOARD_KIT);
|
||||
for (index = 0; index < fLocalDevicesList.CountItems() ; index ++) {
|
||||
|
||||
ldi = fLocalDevicesList.ItemAt(index);
|
||||
printf("Requesting local device %ld\n", ldi->GetID());
|
||||
if (ldi != NULL && ldi->Available())
|
||||
{
|
||||
printf("dev ours %ld\n", ldi->GetID());
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (index <= fLocalDevicesList.CountItems() && ldi != NULL && ldi->Available())
|
||||
{
|
||||
Output::Instance()->Post("Device acquired\n", BLACKBOARD_KIT);
|
||||
ldi->Acquire();
|
||||
return reply->AddInt32("hci_id", hid);
|
||||
}
|
||||
|
||||
return B_ERROR;
|
||||
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BluetoothServer::HandleGetFriendlyName(BMessage* message, BMessage* reply)
|
||||
{
|
||||
LocalDeviceImpl* ldi = LocateDelegateFromMessage(message);
|
||||
BString name;
|
||||
|
||||
if (ldi == NULL)
|
||||
return B_ERROR;
|
||||
|
||||
/* If the device was ocupied... Autlock?->LocalDeviceImpl will decide */
|
||||
if (ldi->GetFriendlyName(name, DetachCurrentMessage()) == B_OK) {
|
||||
|
||||
return reply->AddString("friendlyname", name);
|
||||
}
|
||||
|
||||
return B_WOULD_BLOCK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BluetoothServer::HandleGetAddress(BMessage* message, BMessage* reply)
|
||||
{
|
||||
LocalDeviceImpl* ldi = LocateDelegateFromMessage(message);
|
||||
bdaddr_t bdaddr;
|
||||
|
||||
if (ldi == NULL)
|
||||
return B_ERROR;
|
||||
|
||||
/* If the device was ocupied... Autlock?->LocalDeviceImpl will decide */
|
||||
status_t status = ldi->GetAddress(&bdaddr, DetachCurrentMessage());
|
||||
if ( status == B_OK) {
|
||||
|
||||
return reply->AddData("bdaddr", B_ANY_TYPE, &bdaddr, sizeof(bdaddr_t));
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BluetoothServer::HandleSimpleRequest(BMessage* message, BMessage* reply)
|
||||
{
|
||||
|
||||
LocalDeviceImpl* ldi = LocateDelegateFromMessage(message);
|
||||
BString propertyRequested;
|
||||
|
||||
// Find out if there is a property being requested,
|
||||
if (message->FindString("property", &propertyRequested) == B_OK) {
|
||||
// Check if the property has been already retrieved
|
||||
|
||||
if (ldi->IsPropertyAvailable(propertyRequested)) {
|
||||
|
||||
// Dump everything
|
||||
reply->AddMessage("properties",ldi->GetPropertiesMessage());
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// we are gonna need issue the command ...
|
||||
if (ldi->ProcessSimpleRequest(DetachCurrentMessage()) == B_OK)
|
||||
return B_WOULD_BLOCK;
|
||||
else
|
||||
return B_ERROR;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
|
||||
int32
|
||||
BluetoothServer::notification_Thread(void* data)
|
||||
{
|
||||
BPortNot notifierd( (BluetoothServer*) data , BT_USERLAND_PORT_NAME);
|
||||
|
||||
notifierd.loop();
|
||||
return B_NO_ERROR;
|
||||
}
|
||||
|
||||
int32
|
||||
BluetoothServer::sdp_server_Thread(void* data)
|
||||
{
|
||||
|
||||
return B_NO_ERROR;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
void BluetoothServer::DevicesWatching(void) {
|
||||
|
||||
BDirectory* hdoses;
|
||||
BEntry entrada;
|
||||
BPath path;
|
||||
|
||||
//status_t err;
|
||||
int fd1 = -1;
|
||||
|
||||
// only cheks the actual driver which we have
|
||||
hdoses = new BDirectory("/dev/bus/bluetooth/h2/");
|
||||
// hdoses = new BDirectory("/dev/bus/bluetooth/h3/...");
|
||||
// hdoses = new BDirectory("/dev/bus/bluetooth/h4/...");
|
||||
Output::Instance()->Post("Exploring present devices ...\n",1);
|
||||
|
||||
while (hdoses->GetNextEntry(&entrada,true) == B_OK) {
|
||||
Output::Instance()->Post((char*)path.Path(), 1);
|
||||
entrada.GetPath(&path);
|
||||
if (entrada.IsDirectory()) {
|
||||
Output::Instance()->Post((char*)path.Path(),1);
|
||||
BDirectory* driver_directory = new BDirectory(path.Path());
|
||||
BEntry driver_entry;
|
||||
|
||||
syslog(LOG_ALERT, "Bluetooth driver %s\n",path.Path());
|
||||
fprintf(stderr, "Bluetooth driver %s\n",path.Path());
|
||||
|
||||
while (driver_directory->GetNextEntry(&driver_entry,true) == B_OK) {
|
||||
Output::Instance()->Post((char*)path.Path(),1);
|
||||
driver_entry.GetPath(&path);
|
||||
fd1 = open(path.Path(), O_RDWR);
|
||||
|
||||
|
||||
|
||||
// TODO: Watching all folders under and set some kind of internal structure that hold all
|
||||
// LocalDevices.
|
||||
// devloop = new DeviceLooper();
|
||||
// devloop->StartMonitoringDevice("bus/bluetooth/h2");
|
||||
|
||||
if (fd1 < 0) {
|
||||
syslog(LOG_ALERT,BT "Error opening device %s\n",path.Path());
|
||||
fprintf(stderr, "Error opening device %s\n",path.Path());
|
||||
}
|
||||
else
|
||||
{
|
||||
struct {
|
||||
size_t size;
|
||||
struct hci_command_header header;
|
||||
//struct hci_rp_read_bd_addr body;
|
||||
} __attribute__ ((packed)) cm1;
|
||||
|
||||
struct {
|
||||
size_t size;
|
||||
struct hci_command_header header;
|
||||
struct hci_cp_inquiry body;
|
||||
} __attribute__ ((packed)) cm2;
|
||||
|
||||
struct {
|
||||
size_t size;
|
||||
struct hci_command_header header;
|
||||
struct hci_remote_name_request body;
|
||||
} __attribute__ ((packed)) cm3;
|
||||
|
||||
struct {
|
||||
size_t size;
|
||||
struct hci_command_header header;
|
||||
struct hci_cp_create_conn body;
|
||||
} __attribute__ ((packed)) cm4;
|
||||
|
||||
|
||||
syslog(LOG_ALERT,BT "Registering device %s\n",path.Path());
|
||||
fprintf(stderr, "Opening %s\n",path.Path());
|
||||
|
||||
cm1.size = sizeof(struct hci_command_header);
|
||||
cm1.header.opcode = B_HOST_TO_LENDIAN_INT16(hci_opcode_pack(OGF_CONTROL_BASEBAND, OCF_RESET));
|
||||
cm1.header.clen = 0;
|
||||
ioctl(fd1, ISSUE_BT_COMMAND, &cm1, sizeof(cm1));
|
||||
|
||||
/*cm1.size = sizeof(struct hci_command_header);
|
||||
cm1.header.opcode = B_HOST_TO_LENDIAN_INT16(hci_opcode_pack(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME));
|
||||
cm1.header.clen = 0;
|
||||
ioctl(fd1, ISSUE_BT_COMMAND, &cm1, sizeof(cm1));
|
||||
|
||||
cm1.size = sizeof(struct hci_command_header);
|
||||
cm1.header.opcode = B_HOST_TO_LENDIAN_INT16(hci_opcode_pack(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR));
|
||||
cm1.header.clen = 0;
|
||||
ioctl(fd1, ISSUE_BT_COMMAND, &cm1, sizeof(cm1));
|
||||
|
||||
cm2.size = sizeof(struct hci_command_header)+sizeof(struct hci_cp_inquiry);
|
||||
cm2.header.opcode = B_HOST_TO_LENDIAN_INT16(hci_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY));
|
||||
cm2.body.lap[0] = ((B_BT_GIAC & 0x000000FF));
|
||||
cm2.body.lap[1] = ((B_BT_GIAC & 0x0000FF00) >> 8);
|
||||
cm2.body.lap[2] = ((B_BT_GIAC & 0x00FF0000) >> 16);
|
||||
cm2.body.length = 0x15;
|
||||
cm2.body.num_rsp = 8;
|
||||
cm2.header.clen = 5;
|
||||
ioctl(fd1, ISSUE_BT_COMMAND, &cm2, sizeof(cm1));
|
||||
snooze(60*1000*1000);*/
|
||||
cm3.size = sizeof(struct hci_command_header)+sizeof(struct hci_remote_name_request);
|
||||
cm3.header.opcode = B_HOST_TO_LENDIAN_INT16(hci_opcode_pack(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST));
|
||||
cm3.body.bdaddr.b[0] = 0x92;
|
||||
cm3.body.bdaddr.b[1] = 0xd3;
|
||||
cm3.body.bdaddr.b[2] = 0xaf;
|
||||
cm3.body.bdaddr.b[3] = 0xd9;
|
||||
cm3.body.bdaddr.b[4] = 0x0a;
|
||||
cm3.body.bdaddr.b[5] = 0x00;
|
||||
cm3.body.pscan_rep_mode = 1;
|
||||
cm3.body.clock_offset = 0xc7;
|
||||
cm3.header.clen = 10;
|
||||
ioctl(fd1, ISSUE_BT_COMMAND, &cm3, sizeof(cm3));
|
||||
/*
|
||||
cm4.size = sizeof(struct hci_command_header)+sizeof(struct hci_cp_create_conn);
|
||||
cm4.header.opcode = B_HOST_TO_LENDIAN_INT16(hci_opcode_pack(OGF_LINK_CTL, OCF_CREATE_CONN));
|
||||
cm4.body.bdaddr.b[0] = 0x92;
|
||||
cm4.body.bdaddr.b[1] = 0xd3;
|
||||
cm4.body.bdaddr.b[2] = 0xaf;
|
||||
cm4.body.bdaddr.b[3] = 0xd9;
|
||||
cm4.body.bdaddr.b[4] = 0x0a;
|
||||
cm4.body.bdaddr.b[5] = 0x00;
|
||||
cm4.body.pkt_type = 0xFFFF;
|
||||
cm4.body.pscan_rep_mode = 1;
|
||||
cm4.body.pscan_mode = 0;
|
||||
cm4.body.clock_offset = 0xc7;
|
||||
cm4.body.role_switch = 1;
|
||||
cm4.header.clen = 13;
|
||||
ioctl(fd1, ISSUE_BT_COMMAND, &cm4, sizeof(cm4));
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
syslog(LOG_ALERT,BT "All devices registered\n");
|
||||
fprintf(stderr, "Waiting with opened devices\n");
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
BluetoothServer::ShowWindow(BWindow* pWindow)
|
||||
{
|
||||
pWindow->Lock();
|
||||
if (pWindow->IsHidden())
|
||||
pWindow->Show();
|
||||
else
|
||||
pWindow->Activate();
|
||||
pWindow->Unlock();
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
int
|
||||
main(int /*argc*/, char** /*argv*/)
|
||||
{
|
||||
setbuf(stdout,NULL);
|
||||
|
||||
BluetoothServer* bluetoothServer = new BluetoothServer;
|
||||
|
||||
bluetoothServer->Run();
|
||||
delete bluetoothServer;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
83
src/servers/bluetooth/BluetoothServer.h
Normal file
83
src/servers/bluetooth/BluetoothServer.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||
*
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _BLUETOOTH_SERVER_APP_H
|
||||
#define _BLUETOOTH_SERVER_APP_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <Application.h>
|
||||
#include <OS.h>
|
||||
#include <ObjectList.h>
|
||||
|
||||
#include "BPortNot.h"
|
||||
#include "HCIDelegate.h"
|
||||
#include "DeviceManager.h"
|
||||
#include "LocalDeviceImpl.h"
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/HCI/btHCI.h>
|
||||
#include <bluetooth/HCI/btHCI_transport.h>
|
||||
#include <bluetooth/HCI/btHCI_command.h>
|
||||
|
||||
|
||||
#define BT "bluetooth_server: "
|
||||
|
||||
#define BLACKBOARD_GENERAL 0
|
||||
#define BLACKBOARD_DEVICEMANAGER 1
|
||||
#define BLACKBOARD_EVENTS 2
|
||||
#define BLACKBOARD_KIT 3
|
||||
#define BLACKBOARD_LD_OFFSET 4
|
||||
|
||||
typedef BObjectList<LocalDeviceImpl> LocalDevicesList;
|
||||
|
||||
|
||||
class BluetoothServer : public BApplication
|
||||
{
|
||||
public:
|
||||
|
||||
BluetoothServer();
|
||||
|
||||
virtual bool QuitRequested(void);
|
||||
virtual void ArgvReceived(int32 argc, char **argv);
|
||||
virtual void ReadyToRun(void);
|
||||
|
||||
|
||||
virtual void AppActivated(bool act);
|
||||
virtual void MessageReceived(BMessage *message);
|
||||
|
||||
|
||||
static int32 notification_Thread(void* data);
|
||||
static int32 sdp_server_Thread(void* data);
|
||||
|
||||
/* Messages reply */
|
||||
status_t HandleLocalDevicesCount(BMessage* message, BMessage* reply);
|
||||
status_t HandleAcquireLocalDevice(BMessage* message, BMessage* reply);
|
||||
status_t HandleGetFriendlyName(BMessage* message, BMessage* reply);
|
||||
status_t HandleGetAddress(BMessage* message, BMessage* reply);
|
||||
|
||||
status_t HandleSimpleRequest(BMessage* message, BMessage* reply);
|
||||
|
||||
|
||||
LocalDeviceImpl* LocateLocalDeviceImpl(hci_id hid);
|
||||
|
||||
private:
|
||||
|
||||
LocalDeviceImpl* LocateDelegateFromMessage(BMessage* message);
|
||||
|
||||
void ShowWindow(BWindow* pWindow);
|
||||
|
||||
LocalDevicesList fLocalDevicesList;
|
||||
// UI
|
||||
|
||||
// Notification system
|
||||
thread_id fEventListener;
|
||||
DeviceManager* fDeviceManager;
|
||||
|
||||
BPoint fCenter;
|
||||
};
|
||||
|
||||
#endif
|
109
src/servers/bluetooth/CommandManager.cpp
Normal file
109
src/servers/bluetooth/CommandManager.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||
*
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/HCI/btHCI_command.h>
|
||||
|
||||
#include <malloc.h>
|
||||
|
||||
#include "CommandManager.h"
|
||||
|
||||
|
||||
inline void* buildCommand(uint8 ogf, uint8 ocf, void** param, size_t psize, size_t* outsize)
|
||||
{
|
||||
struct hci_command_header* header;
|
||||
|
||||
#ifdef BT_IOCTLS_PASS_SIZE
|
||||
header = (struct hci_command_header*) malloc(psize + sizeof(struct hci_command_header));
|
||||
*outsize = psize + sizeof(struct hci_command_header);
|
||||
#else
|
||||
size_t* size = (size_t*)malloc(psize + sizeof(struct hci_command_header) + sizeof(size_t));
|
||||
*outsize = psize + sizeof(struct hci_command_header) + sizeof(size_t);
|
||||
|
||||
*size = psize + sizeof(struct hci_command_header);
|
||||
header = (struct hci_command_header*) (((uint8*)size)+4);
|
||||
#endif
|
||||
|
||||
|
||||
if (header != NULL) {
|
||||
|
||||
header->opcode = B_HOST_TO_LENDIAN_INT16(PACK_OPCODE(ogf, ocf));
|
||||
header->clen = psize;
|
||||
|
||||
if (param != NULL && psize != 0) {
|
||||
*param = ((uint8*)header) + sizeof(struct hci_command_header);
|
||||
}
|
||||
}
|
||||
#ifdef BT_IOCTLS_PASS_SIZE
|
||||
return header;
|
||||
#else
|
||||
return (void*)size;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* CONTROL BASEBAND */
|
||||
void* buildReset(size_t* outsize)
|
||||
{
|
||||
return buildCommand(OGF_CONTROL_BASEBAND, OCF_RESET, NULL, 0, outsize);
|
||||
}
|
||||
|
||||
|
||||
void* buildReadLocalName(size_t* outsize)
|
||||
{
|
||||
return buildCommand(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME, NULL, 0, outsize);
|
||||
}
|
||||
|
||||
|
||||
/* LINK CONTROL */
|
||||
void* buildRemoteNameRequest(bdaddr_t bdaddr,uint8 pscan_rep_mode, uint16 clock_offset, size_t* outsize)
|
||||
{
|
||||
|
||||
struct hci_remote_name_request* param;
|
||||
void* command = buildCommand(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST, (void**) ¶m, sizeof(struct hci_remote_name_request), outsize);
|
||||
|
||||
if (command != NULL) {
|
||||
param->bdaddr = bdaddr;
|
||||
param->pscan_rep_mode = pscan_rep_mode;
|
||||
param->clock_offset = clock_offset;
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
|
||||
void* buildInquiry(uint32 lap, uint8 length, uint8 num_rsp, size_t* outsize)
|
||||
{
|
||||
|
||||
struct hci_cp_inquiry* param;
|
||||
void* command = buildCommand(OGF_LINK_CONTROL, OCF_INQUIRY, (void**) ¶m, sizeof(struct hci_cp_inquiry), outsize);
|
||||
|
||||
if (command != NULL) {
|
||||
|
||||
param->lap[2] = (lap >> 16) & 0xFF;
|
||||
param->lap[1] = (lap >> 8) & 0xFF;
|
||||
param->lap[0] = (lap >> 0) & 0xFF;
|
||||
param->length = length;
|
||||
param->num_rsp = num_rsp;
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
|
||||
/* OGF_INFORMATIONAL_PARAM */
|
||||
void* buildReadBufferSize(size_t* outsize)
|
||||
{
|
||||
return buildCommand(OGF_INFORMATIONAL_PARAM, OCF_READ_BUFFER_SIZE, NULL, 0, outsize);
|
||||
}
|
||||
|
||||
|
||||
void* buildReadBdAddr(size_t* outsize)
|
||||
{
|
||||
return buildCommand(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR, NULL, 0, outsize);
|
||||
}
|
25
src/servers/bluetooth/CommandManager.h
Normal file
25
src/servers/bluetooth/CommandManager.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||
*
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _COMMAND_MANAGER_H
|
||||
#define _COMMAND_MANAGER_H
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
|
||||
/* CONTROL BASEBAND */
|
||||
void* buildReset(size_t* outsize);
|
||||
void* buildReadLocalName(size_t* outsize);
|
||||
|
||||
/* LINK CONTROL */
|
||||
void* buildRemoteNameRequest(bdaddr_t bdaddr,uint8 pscan_rep_mode, uint16 clock_offset, size_t* outsize);
|
||||
void* buildInquiry(uint32 lap, uint8 length, uint8 num_rsp, size_t* outsize);
|
||||
|
||||
/* OGF_INFORMATIONAL_PARAM */
|
||||
void* buildReadBufferSize(size_t* outsize);
|
||||
void* buildReadBdAddr(size_t* outsize);
|
||||
|
||||
#endif
|
329
src/servers/bluetooth/DeviceManager.cpp
Normal file
329
src/servers/bluetooth/DeviceManager.cpp
Normal file
@ -0,0 +1,329 @@
|
||||
/*
|
||||
** Copyright 2004, the Haiku project. All rights reserved.
|
||||
** Distributed under the terms of the Haiku License.
|
||||
**
|
||||
**
|
||||
** Author : Jérôme Duval
|
||||
** Original authors: Marcus Overhagen, Axel Dörfler
|
||||
**
|
||||
** Bluetooth adaptation: Oliver Ruiz Dorantes
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#include <Application.h>
|
||||
#include <Autolock.h>
|
||||
#include <String.h>
|
||||
|
||||
#include <Directory.h>
|
||||
#include <Entry.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Path.h>
|
||||
#include <NodeMonitor.h>
|
||||
|
||||
|
||||
#include <image.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "DeviceManager.h"
|
||||
#include "LocalDeviceImpl.h"
|
||||
|
||||
#include "Output.h"
|
||||
#include "BluetoothServer.h"
|
||||
|
||||
#include <bluetoothserver_p.h>
|
||||
|
||||
|
||||
void
|
||||
DeviceManager::MessageReceived(BMessage * msg)
|
||||
{
|
||||
if (msg->what == B_NODE_MONITOR) {
|
||||
int32 opcode;
|
||||
if (msg->FindInt32("opcode", &opcode) == B_OK) {
|
||||
switch (opcode) {
|
||||
case B_ENTRY_CREATED:
|
||||
case B_ENTRY_REMOVED:
|
||||
case B_ENTRY_MOVED:
|
||||
{
|
||||
node_ref dir_nref;
|
||||
const char *name;
|
||||
BDirectory dir;
|
||||
|
||||
(Output::Instance()->Post("Bus changing ...\n", BLACKBOARD_DEVICEMANAGER));
|
||||
|
||||
if ((msg->FindInt32("device", &dir_nref.device)!=B_OK)
|
||||
|| (msg->FindInt64("directory", &dir_nref.node)!=B_OK)
|
||||
|| (msg->FindString("name", &name) != B_OK))
|
||||
return;
|
||||
|
||||
// Check if the entry is a File or a directory
|
||||
if (dir.SetTo(&dir_nref) == B_OK) {
|
||||
(Output::Instance()->Post(name, BLACKBOARD_DEVICEMANAGER));
|
||||
(Output::Instance()->Post(" adding folder...\n", BLACKBOARD_DEVICEMANAGER));
|
||||
AddDirectory(&dir_nref);
|
||||
} else {
|
||||
// Then it is a device!
|
||||
// post it to server
|
||||
// msg->what = BT_MSG_ADD_DEVICE;
|
||||
// be_app_messenger.SendMessage(msg);
|
||||
// (Output::Instance()->Post("New bluetooth device on bus ...\n", BLACKBOARD_DEVICEMANAGER));
|
||||
}
|
||||
}
|
||||
case B_STAT_CHANGED:
|
||||
case B_ATTR_CHANGED:
|
||||
case B_DEVICE_MOUNTED:
|
||||
case B_DEVICE_UNMOUNTED:
|
||||
default:
|
||||
BLooper::MessageReceived(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DeviceManager::AddDirectory(node_ref *nref)
|
||||
{
|
||||
BDirectory directory(nref);
|
||||
status_t status = directory.InitCheck();
|
||||
if (status != B_OK) {
|
||||
(Output::Instance()->Post("AddDirectory::Initcheck Failed\n", BLACKBOARD_DEVICEMANAGER));
|
||||
return status;
|
||||
}
|
||||
|
||||
status = watch_node(nref, B_WATCH_DIRECTORY, this);
|
||||
if (status != B_OK) {
|
||||
(Output::Instance()->Post("AddDirectory::watch_node Failed\n", BLACKBOARD_DEVICEMANAGER));
|
||||
return status;
|
||||
}
|
||||
|
||||
BEntry entry;
|
||||
while (directory.GetNextEntry(&entry, true) == B_OK) {
|
||||
|
||||
// its suposed to be devices ...
|
||||
entry_ref ref;
|
||||
entry.GetRef(&ref);
|
||||
BPath path(new BEntry(&ref));
|
||||
BString* str = new BString(path.Path());
|
||||
|
||||
BMessage* msg = new BMessage(BT_MSG_ADD_DEVICE);
|
||||
msg->AddInt32("opcode", B_ENTRY_CREATED);
|
||||
msg->AddInt32("device", nref->device);
|
||||
msg->AddInt64("directory", nref->node);
|
||||
msg->AddString("name", *str );
|
||||
|
||||
be_app_messenger.SendMessage(msg);
|
||||
|
||||
|
||||
(Output::Instance()->Post( path.Path(), BLACKBOARD_DEVICEMANAGER));
|
||||
(Output::Instance()->Post(" Entry added\n", BLACKBOARD_DEVICEMANAGER));
|
||||
|
||||
}
|
||||
(Output::Instance()->Post("Finished exploring entries\n", BLACKBOARD_DEVICEMANAGER));
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DeviceManager::RemoveDirectory(node_ref* nref)
|
||||
{
|
||||
BDirectory directory(nref);
|
||||
status_t status = directory.InitCheck();
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = watch_node(nref, B_STOP_WATCHING, this);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
BEntry entry;
|
||||
while (directory.GetNextEntry(&entry, true) == B_OK) {
|
||||
entry_ref ref;
|
||||
entry.GetRef(&ref);
|
||||
BMessage msg(B_NODE_MONITOR);
|
||||
msg.AddInt32("opcode", B_ENTRY_REMOVED);
|
||||
msg.AddInt32("device", nref->device);
|
||||
msg.AddInt64("directory", nref->node);
|
||||
msg.AddString("name", ref.name);
|
||||
//addon->fDevice->Control(NULL, NULL, msg.what, &msg);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
DeviceManager::DeviceManager()
|
||||
:
|
||||
fLock("device manager")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DeviceManager::~DeviceManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DeviceManager::LoadState()
|
||||
{
|
||||
|
||||
if (!Lock())
|
||||
return;
|
||||
Run();
|
||||
Unlock();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DeviceManager::SaveState()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DeviceManager::StartMonitoringDevice(const char *device)
|
||||
{
|
||||
|
||||
status_t err;
|
||||
node_ref nref;
|
||||
BDirectory directory;
|
||||
BPath path("/dev");
|
||||
|
||||
/* Build the path */
|
||||
if ((err = path.Append(device)) != B_OK) {
|
||||
printf("DeviceManager::StartMonitoringDevice BPath::Append() error %s: %s\n", path.Path(), strerror(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Check the path */
|
||||
if ((err = directory.SetTo(path.Path())) != B_OK) {
|
||||
/* Entry not there ... */
|
||||
if (err != B_ENTRY_NOT_FOUND) { // something else we cannot handle
|
||||
printf("DeviceManager::StartMonitoringDevice SetTo error %s: %s\n", path.Path(), strerror(err));
|
||||
return err;
|
||||
}
|
||||
/* Create it */
|
||||
if ((err = create_directory(path.Path(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) != B_OK
|
||||
|| (err = directory.SetTo(path.Path())) != B_OK) {
|
||||
printf("DeviceManager::StartMonitoringDevice CreateDirectory error %s: %s\n", path.Path(), strerror(err));
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/* get noderef */
|
||||
if ((err = directory.GetNodeRef(&nref)) != B_OK) {
|
||||
printf("DeviceManager::StartMonitoringDevice GetNodeRef error %s: %s\n", path.Path(), strerror(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
// test if already monitored in any add-on
|
||||
|
||||
(Output::Instance()->Post(device, BLACKBOARD_DEVICEMANAGER));
|
||||
(Output::Instance()->Post(" Being monitorized\n", BLACKBOARD_DEVICEMANAGER));
|
||||
|
||||
bool alreadyMonitored = false;
|
||||
#if 0
|
||||
HCIDelegate *tmphd = NULL;
|
||||
int32 i = 0;
|
||||
|
||||
// TODO!! ask the server if this needs to be monitored
|
||||
|
||||
while ((tmphd = (HCIDelegate *)fDelegatesList.ItemAt(i++)) !=NULL) {
|
||||
|
||||
/* Find out the reference*/
|
||||
node_ref *dnref = (node_ref *)tmphd->fMonitoredRefs ;
|
||||
if (*dnref == nref) {
|
||||
printf("StartMonitoringDevice already monitored\n");
|
||||
alreadyMonitored = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
// monitor if needed
|
||||
if (!alreadyMonitored) {
|
||||
if ((err = AddDirectory(&nref)) != B_OK)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* // add addon in list
|
||||
if (!fDeviceAddons.HasItem(addon))
|
||||
fDeviceAddons.AddItem(addon);
|
||||
|
||||
// add dir ref in list
|
||||
int32 j=0;
|
||||
node_ref *dnref = NULL;
|
||||
alreadyMonitored = false; // why rechecking?
|
||||
while ((dnref = (node_ref *)addon->fMonitoredRefs.ItemAt(j++)) != NULL) {
|
||||
if (*dnref == nref) {
|
||||
alreadyMonitored = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!alreadyMonitored) {
|
||||
addon->fMonitoredRefs.AddItem(new node_ref(nref));
|
||||
}
|
||||
*/
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DeviceManager::StopMonitoringDevice(const char *device)
|
||||
{
|
||||
status_t err;
|
||||
node_ref nref;
|
||||
BDirectory directory;
|
||||
BPath path("/dev");
|
||||
if (((err = path.Append(device)) != B_OK)
|
||||
|| ((err = directory.SetTo(path.Path())) != B_OK)
|
||||
|| ((err = directory.GetNodeRef(&nref)) != B_OK))
|
||||
return err;
|
||||
|
||||
// test if still monitored
|
||||
bool stillMonitored = false;
|
||||
/*
|
||||
int32 i = 0;
|
||||
while ((tmpaddon = (_BDeviceAddOn_ *)fDeviceAddons.ItemAt(i++)) !=NULL) {
|
||||
if (addon == tmpaddon)
|
||||
continue;
|
||||
|
||||
int32 j=0;
|
||||
node_ref *dnref = NULL;
|
||||
while ((dnref = (node_ref *)tmpaddon->fMonitoredRefs.ItemAt(j++)) != NULL) {
|
||||
if (*dnref == nref) {
|
||||
stillMonitored = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (stillMonitored)
|
||||
break;
|
||||
}
|
||||
|
||||
// remove from list
|
||||
node_ref *dnref = NULL;
|
||||
int32 j=0;
|
||||
while ((dnref = (node_ref *)addon->fMonitoredRefs.ItemAt(j)) != NULL) {
|
||||
if (*dnref == nref) {
|
||||
addon->fMonitoredRefs.RemoveItem(j);
|
||||
delete dnref;
|
||||
break;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
|
||||
// stop monitoring if needed
|
||||
if (!stillMonitored) {
|
||||
if ((err = RemoveDirectory(&nref, addon)) != B_OK)
|
||||
return err;
|
||||
}
|
||||
*/
|
||||
return B_OK;
|
||||
}
|
43
src/servers/bluetooth/DeviceManager.h
Normal file
43
src/servers/bluetooth/DeviceManager.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
** Copyright 2004, the Haiku project. All rights reserved.
|
||||
** Distributed under the terms of the Haiku License.
|
||||
**
|
||||
** Author : Jérôme Duval
|
||||
** Original authors: Marcus Overhagen, Axel Dörfler
|
||||
*/
|
||||
#ifndef _DEVICE_MANAGER_H
|
||||
#define _DEVICE_MANAGER_H
|
||||
|
||||
// Manager for devices monitoring
|
||||
|
||||
#include <Handler.h>
|
||||
#include <Node.h>
|
||||
#include <Looper.h>
|
||||
#include <Locker.h>
|
||||
/*#include <InputServerDevice.h>
|
||||
#include <InputServerFilter.h>
|
||||
#include <InputServerMethod.h>
|
||||
#include "TList.h"
|
||||
*/
|
||||
|
||||
class DeviceManager : public BLooper {
|
||||
public:
|
||||
DeviceManager();
|
||||
~DeviceManager();
|
||||
|
||||
void LoadState();
|
||||
void SaveState();
|
||||
|
||||
status_t StartMonitoringDevice(const char *device);
|
||||
status_t StopMonitoringDevice(const char *device);
|
||||
|
||||
void MessageReceived(BMessage *msg);
|
||||
|
||||
private:
|
||||
status_t AddDirectory(node_ref *nref);
|
||||
status_t RemoveDirectory(node_ref *nref);
|
||||
|
||||
BLocker fLock;
|
||||
};
|
||||
|
||||
#endif // _DEVICE_MANAGER_H
|
19
src/servers/bluetooth/HCIControllerAccessor.cpp
Normal file
19
src/servers/bluetooth/HCIControllerAccessor.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
#include "HCIControllerAccessor.h"
|
||||
|
||||
HCIControllerAccessor::HCIControllerAccessor(BPath* path) : HCIDelegate(path)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
status_t
|
||||
HCIControllerAccessor::IssueCommand(raw_command* rc, size_t size)
|
||||
{
|
||||
|
||||
if (GetID() < 0)
|
||||
return B_ERROR;
|
||||
|
||||
|
||||
return B_ERROR;
|
||||
}
|
16
src/servers/bluetooth/HCIControllerAccessor.h
Normal file
16
src/servers/bluetooth/HCIControllerAccessor.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* */
|
||||
|
||||
#ifndef _HCICONTROLLER_ACCESSOR_H_
|
||||
#define _HCICONTROLLER_ACCESSOR_H_
|
||||
|
||||
#include "HCIDelegate.h"
|
||||
|
||||
|
||||
class HCIControllerAccessor : public HCIDelegate {
|
||||
|
||||
public:
|
||||
HCIControllerAccessor(BPath* path);
|
||||
status_t IssueCommand(raw_command* rc, size_t size);
|
||||
};
|
||||
|
||||
#endif
|
59
src/servers/bluetooth/HCIDelegate.h
Normal file
59
src/servers/bluetooth/HCIDelegate.h
Normal file
@ -0,0 +1,59 @@
|
||||
#ifndef _HCIDELEGATE_H_
|
||||
#define _HCIDELEGATE_H_
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <Path.h>
|
||||
|
||||
#include <bluetooth/HCI/btHCI_transport.h>
|
||||
|
||||
|
||||
typedef void* raw_command;
|
||||
|
||||
|
||||
class HCIDelegate {
|
||||
|
||||
public:
|
||||
HCIDelegate(BPath* path)
|
||||
{
|
||||
status_t status;
|
||||
|
||||
fFD = open (path->Path(), O_RDWR);
|
||||
printf("## fdesc %d\n", fFD);
|
||||
if (fFD > 0) {
|
||||
// find out which ID was assigned
|
||||
status = ioctl(fFD, GET_HCI_ID, &fHID, 0);
|
||||
printf("## id fdesc %ld ### %ld\n", fHID, status);
|
||||
|
||||
}
|
||||
else {
|
||||
fHID = B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
hci_id GetID(void)
|
||||
{
|
||||
return fHID;
|
||||
}
|
||||
|
||||
virtual status_t IssueCommand(raw_command rc, size_t size)
|
||||
{
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
hci_id fHID;
|
||||
int fFD;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
28
src/servers/bluetooth/HCITransportAccessor.cpp
Normal file
28
src/servers/bluetooth/HCITransportAccessor.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
#include <String.h>
|
||||
|
||||
#include "BluetoothServer.h"
|
||||
#include "HCITransportAccessor.h"
|
||||
#include "Output.h"
|
||||
|
||||
HCITransportAccessor::HCITransportAccessor(BPath* path) : HCIDelegate(path)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
status_t
|
||||
HCITransportAccessor::IssueCommand(raw_command rc, size_t size)
|
||||
{
|
||||
if (GetID() < 0 || fFD < 0)
|
||||
return B_ERROR;
|
||||
|
||||
printf("Command going: len = %d\n", size);
|
||||
for (int16 index = 0 ; index < size; index++ ) {
|
||||
printf("%x:",((uint8*)rc)[index]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
|
||||
return ioctl(fFD, ISSUE_BT_COMMAND, rc, size);
|
||||
}
|
16
src/servers/bluetooth/HCITransportAccessor.h
Normal file
16
src/servers/bluetooth/HCITransportAccessor.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* */
|
||||
|
||||
#ifndef _HCITRANSPORT_ACCESSOR_H_
|
||||
#define _HCITRANSPORT_ACCESSOR_H_
|
||||
|
||||
#include "HCIDelegate.h"
|
||||
|
||||
|
||||
class HCITransportAccessor : public HCIDelegate {
|
||||
|
||||
public:
|
||||
HCITransportAccessor(BPath* path);
|
||||
status_t IssueCommand(raw_command rc, size_t size);
|
||||
};
|
||||
|
||||
#endif
|
22
src/servers/bluetooth/Jamfile
Normal file
22
src/servers/bluetooth/Jamfile
Normal file
@ -0,0 +1,22 @@
|
||||
SubDir HAIKU_TOP src servers bluetooth ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
UsePrivateHeaders shared bluetooth net kernel ;
|
||||
|
||||
AddResources bluetooth_server : server-bluetooth.rdef ;
|
||||
|
||||
Server bluetooth_server
|
||||
:
|
||||
BPortNot.cpp
|
||||
BluetoothServer.cpp
|
||||
CommandManager.cpp
|
||||
DeviceManager.cpp
|
||||
HCIControllerAccessor.cpp
|
||||
HCITransportAccessor.cpp
|
||||
LocalDeviceHandler.cpp
|
||||
LocalDeviceImpl.cpp
|
||||
Output.cpp
|
||||
: be
|
||||
$(TARGET_LIBSTDC++)
|
||||
;
|
161
src/servers/bluetooth/LocalDeviceHandler.cpp
Normal file
161
src/servers/bluetooth/LocalDeviceHandler.cpp
Normal file
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||
*
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "LocalDeviceHandler.h"
|
||||
|
||||
|
||||
|
||||
LocalDeviceHandler::LocalDeviceHandler(HCIDelegate* hd)
|
||||
{
|
||||
fHCIDelegate = hd;
|
||||
fProperties = new BMessage();
|
||||
|
||||
}
|
||||
|
||||
LocalDeviceHandler::~LocalDeviceHandler()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
hci_id
|
||||
LocalDeviceHandler::GetID()
|
||||
{
|
||||
return fHCIDelegate->GetID();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
LocalDeviceHandler::Available() {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LocalDeviceHandler::Acquire(void) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
LocalDeviceHandler::IsPropertyAvailable(const BString& property) {
|
||||
|
||||
type_code typeFound;
|
||||
int32 countFound;
|
||||
|
||||
return (fProperties->GetInfo(property.String(), &typeFound, &countFound) == B_OK );
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LocalDeviceHandler::AddWantedEvent(BMessage* msg)
|
||||
{
|
||||
fEventsWanted.Lock();
|
||||
// TODO: review why it is neede to replicate the msg
|
||||
fEventsWanted.AddMessage(msg);
|
||||
fEventsWanted.Unlock();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LocalDeviceHandler::ClearWantedEvent(BMessage* msg, uint16 event = 0, uint16 opcode = 0)
|
||||
{
|
||||
// Remove the whole petition from queue
|
||||
fEventsWanted.Lock();
|
||||
/*
|
||||
if (event == 0) {
|
||||
fEventsWanted.RemoveMessage(msg);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
int16 eventFound;
|
||||
int16 opcodeFound;
|
||||
int32 eventIndex;
|
||||
|
||||
for (int32 index = 0 ; index < fEventsWanted.CountMessages() ; index++) {
|
||||
|
||||
BMessage* msg = fEventsWanted.FindMessage(index);
|
||||
|
||||
eventIndex = 0;
|
||||
// for each Event
|
||||
while (msg->FindInt16("eventExpected", eventIndex, &eventFound) == B_OK ) {
|
||||
if (eventFound == event) {
|
||||
|
||||
// there is an opcode specified
|
||||
if (opcde != 0)
|
||||
|
||||
// The opcode matches
|
||||
if ( (msg->FindInt16("opcodeExpected", eventIndex, &opcodeFound) == B_OK) &&
|
||||
((uint16)opcodeFound != opcode) ) {
|
||||
|
||||
fEventsWanted.RemoveMessage(msg);
|
||||
goto bail;
|
||||
}
|
||||
} else {
|
||||
// Event matches so far
|
||||
fEventsWanted.RemoveMessage(msg);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
}
|
||||
eventIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
bail: */
|
||||
fEventsWanted.Unlock();
|
||||
|
||||
fEventsWanted.RemoveMessage(msg);
|
||||
}
|
||||
|
||||
|
||||
BMessage*
|
||||
LocalDeviceHandler::FindPetition(uint16 event, uint16 opcode = 0)
|
||||
{
|
||||
int16 eventFound;
|
||||
int16 opcodeFound;
|
||||
int32 eventIndex;
|
||||
|
||||
fEventsWanted.Lock();
|
||||
// for each Petition
|
||||
for (int32 index = 0 ; index < fEventsWanted.CountMessages() ; index++) {
|
||||
BMessage* msg = fEventsWanted.FindMessage(index);
|
||||
|
||||
printf("Petition %ld ... of %ld msg #%p\n", index, fEventsWanted.CountMessages(), msg);
|
||||
msg->PrintToStream();
|
||||
eventIndex = 0;
|
||||
// for each Event
|
||||
while (msg->FindInt16("eventExpected", eventIndex, &eventFound) == B_OK ) {
|
||||
if (eventFound == event) {
|
||||
|
||||
printf("Event found %ld\n", eventIndex);
|
||||
// there is an opcode specified..
|
||||
if (msg->FindInt16("opcodeExpected", eventIndex, &opcodeFound) == B_OK) {
|
||||
|
||||
// ensure the opcode
|
||||
if ((uint16)opcodeFound != opcode) {
|
||||
printf("opcode does not match %d\n", opcode);
|
||||
break;
|
||||
}
|
||||
printf("Opcdodes match %d %d \n", opcode , opcodeFound);
|
||||
}
|
||||
|
||||
fEventsWanted.Unlock();
|
||||
return msg;
|
||||
|
||||
|
||||
}
|
||||
eventIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
fEventsWanted.Unlock();
|
||||
return NULL;
|
||||
}
|
50
src/servers/bluetooth/LocalDeviceHandler.h
Normal file
50
src/servers/bluetooth/LocalDeviceHandler.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||
*
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LOCALDEVICE_HANDLER_H_
|
||||
#define _LOCALDEVICE_HANDLER_H_
|
||||
|
||||
#include <String.h>
|
||||
|
||||
#include <MessageQueue.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
|
||||
#include "HCIDelegate.h"
|
||||
|
||||
class LocalDeviceHandler {
|
||||
|
||||
public:
|
||||
|
||||
virtual hci_id GetID();
|
||||
|
||||
virtual bool Available();
|
||||
void Acquire(void);
|
||||
|
||||
BMessage* GetPropertiesMessage(void) { return fProperties; }
|
||||
bool IsPropertyAvailable(const BString& property);
|
||||
|
||||
|
||||
protected:
|
||||
LocalDeviceHandler (HCIDelegate* hd);
|
||||
virtual ~LocalDeviceHandler();
|
||||
|
||||
HCIDelegate* fHCIDelegate;
|
||||
BMessage* fProperties;
|
||||
|
||||
void AddWantedEvent(BMessage* msg);
|
||||
void ClearWantedEvent(BMessage* msg, uint16 code, uint16 opcode = 0);
|
||||
BMessage* FindPetition(uint16 event, uint16 opcode = 0);
|
||||
|
||||
private:
|
||||
|
||||
BMessageQueue fEventsWanted;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
396
src/servers/bluetooth/LocalDeviceImpl.cpp
Normal file
396
src/servers/bluetooth/LocalDeviceImpl.cpp
Normal file
@ -0,0 +1,396 @@
|
||||
/*
|
||||
* Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||
*
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "BluetoothServer.h"
|
||||
|
||||
#include "LocalDeviceImpl.h"
|
||||
#include "CommandManager.h"
|
||||
#include "Output.h"
|
||||
|
||||
#include <bluetooth/bluetooth_error.h>
|
||||
#include <bluetooth/HCI/btHCI_event.h>
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
// Factory methods
|
||||
LocalDeviceImpl*
|
||||
LocalDeviceImpl::CreateControllerAccessor(BPath* path)
|
||||
{
|
||||
HCIDelegate* hd = new HCIControllerAccessor(path);
|
||||
|
||||
if ( hd != NULL)
|
||||
return new LocalDeviceImpl(hd);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
LocalDeviceImpl*
|
||||
LocalDeviceImpl::CreateTransportAccessor(BPath* path)
|
||||
{
|
||||
HCIDelegate* hd = new HCITransportAccessor(path);
|
||||
|
||||
if ( hd != NULL)
|
||||
return new LocalDeviceImpl(hd);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
LocalDeviceImpl::LocalDeviceImpl(HCIDelegate* hd) : LocalDeviceHandler(hd)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
#pragma mark - Class methods -
|
||||
#endif
|
||||
|
||||
void
|
||||
LocalDeviceImpl::HandleEvent(struct hci_event_header* event)
|
||||
{
|
||||
// Check if it was a non requested events
|
||||
switch (event->ecode) {
|
||||
case HCI_EVENT_HARDWARE_ERROR:
|
||||
//HardwareError(event);
|
||||
return;
|
||||
default:
|
||||
// lets go on
|
||||
break;
|
||||
}
|
||||
|
||||
printf("Event comming: len = %d\n", event->elen);
|
||||
for (int16 index = 0 ; index < event->elen + 2; index++ ) {
|
||||
printf("%x:",((uint8*)event)[index]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
|
||||
BMessage* request = NULL;
|
||||
|
||||
// Check if its a requested one
|
||||
if ( event->ecode == HCI_EVENT_CMD_COMPLETE ) {
|
||||
|
||||
(Output::Instance()->Post("Incoming Command Complete\n", BLACKBOARD_EVENTS));
|
||||
request = FindPetition(event->ecode, ((struct hci_ev_cmd_complete*)(event+1))->opcode );
|
||||
|
||||
} else
|
||||
// TODO: Command status should also be considered
|
||||
{
|
||||
request = FindPetition(event->ecode);
|
||||
}
|
||||
|
||||
if ( request == NULL) {
|
||||
(Output::Instance()->Post("Event could not be understood or delivered\n", BLACKBOARD_EVENTS));
|
||||
return;
|
||||
}
|
||||
|
||||
// we are waiting for a reply
|
||||
switch (event->ecode) {
|
||||
case HCI_EVENT_INQUIRY_COMPLETE:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_INQUIRY_RESULT:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_CONN_COMPLETE:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_CONN_REQUEST:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_AUTH_COMPLETE:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_ENCRYPT_CHANGE:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_CHANGE_CONN_LINK_KEY_COMPLETE:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_MASTER_LINK_KEY_COMPL:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_RMT_FEATURES:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_RMT_VERSION:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_QOS_SETUP_COMPLETE:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_CMD_COMPLETE:
|
||||
CommandComplete((struct hci_ev_cmd_complete*)(event+1), request);
|
||||
break;
|
||||
|
||||
case HCI_EVENT_CMD_STATUS:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_FLUSH_OCCUR:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_ROLE_CHANGE:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_NUM_COMP_PKTS:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_MODE_CHANGE:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_RETURN_LINK_KEYS:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_PIN_CODE_REQ:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_LINK_KEY_REQ:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_LINK_KEY_NOTIFY:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_LOOPBACK_COMMAND:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_DATA_BUFFER_OVERFLOW:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_MAX_SLOT_CHANGE:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_READ_CLOCK_OFFSET_COMPL:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_CON_PKT_TYPE_CHANGED:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_QOS_VIOLATION:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_PAGE_SCAN_REP_MODE_CHANGE:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_FLOW_SPECIFICATION:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_REMOTE_EXTENDED_FEATURES:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETED:
|
||||
break;
|
||||
|
||||
case HCI_EVENT_SYNCHRONOUS_CONNECTION_CHANGED:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LocalDeviceImpl::CommandComplete(struct hci_ev_cmd_complete* event, BMessage* request) {
|
||||
|
||||
int16 opcodeExpected;
|
||||
BMessage reply;
|
||||
|
||||
Output::Instance()->Post(__FUNCTION__, BLACKBOARD_LD_OFFSET + GetID());
|
||||
Output::Instance()->Post("\n", BLACKBOARD_LD_OFFSET + GetID());
|
||||
|
||||
// Handle command complete information
|
||||
request->FindInt16("opcodeExpected", 0 /*REVIEW!*/, &opcodeExpected);
|
||||
|
||||
printf("Command complete ...%p\n",event);
|
||||
for (int16 index = 0 ; index < 10; index++ ) {
|
||||
printf("%x:",((uint8*)event)[index]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
|
||||
if (request->IsSourceWaiting() == false)
|
||||
Output::Instance()->Post("nobody waiting\n", BLACKBOARD_KIT);
|
||||
|
||||
|
||||
switch (opcodeExpected) {
|
||||
|
||||
case PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR):
|
||||
{
|
||||
struct hci_rp_read_bd_addr* readbdaddr = (struct hci_rp_read_bd_addr*)(event+1);
|
||||
|
||||
printf("read bdaddr ...%p\n", readbdaddr);
|
||||
for (int16 index = 0 ; index < 10; index++ ) {
|
||||
printf("%x:",((uint8*)readbdaddr)[index]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
|
||||
if (readbdaddr->status == BT_OK) {
|
||||
|
||||
|
||||
reply.AddData("bdaddr", B_ANY_TYPE, &readbdaddr->bdaddr, sizeof(bdaddr_t));
|
||||
reply.AddInt32("status", readbdaddr->status);
|
||||
|
||||
printf("Sending reply ... %ld\n",request->SendReply(&reply));
|
||||
reply.PrintToStream();
|
||||
|
||||
|
||||
Output::Instance()->Post("Positive reply for getAdress\n", BLACKBOARD_KIT);
|
||||
|
||||
} else {
|
||||
reply.AddInt8("status", readbdaddr->status);
|
||||
request->SendReply(&reply);
|
||||
Output::Instance()->Post("Negative reply for getAdress\n", BLACKBOARD_KIT);
|
||||
}
|
||||
|
||||
ClearWantedEvent(request, PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR));
|
||||
}
|
||||
break;
|
||||
|
||||
case PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME):
|
||||
{
|
||||
struct hci_rp_read_local_name* readLocalName = (struct hci_rp_read_local_name*)(event+1);
|
||||
|
||||
printf("read bdaddr ...%p\n", readLocalName);
|
||||
for (int16 index = 0 ; index < 10; index++ ) {
|
||||
printf("%x:",((uint8*)readLocalName)[index]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
reply.AddInt8("status", readLocalName->status);
|
||||
|
||||
if (readLocalName->status == BT_OK) {
|
||||
|
||||
reply.AddString("friendlyname", (const char*)readLocalName->local_name );
|
||||
Output::Instance()->Post("Positive reply for friendly name\n", BLACKBOARD_KIT);
|
||||
|
||||
} else {
|
||||
|
||||
Output::Instance()->Post("Negative reply for friendly name\n", BLACKBOARD_KIT);
|
||||
|
||||
}
|
||||
|
||||
printf("Sending reply ... %ld\n",request->SendReply(&reply));
|
||||
reply.PrintToStream();
|
||||
|
||||
ClearWantedEvent(request, PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Output::Instance()->Post("Command Complete not handled\n", BLACKBOARD_KIT);
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
#pragma mark - Request Methods -
|
||||
#endif
|
||||
|
||||
|
||||
status_t
|
||||
LocalDeviceImpl::GetAddress(bdaddr_t* bdaddr, BMessage* request)
|
||||
{
|
||||
ssize_t size;
|
||||
|
||||
if (fProperties->FindData("bdaddr", B_ANY_TYPE, 0, (const void **)bdaddr, &size) == B_OK) {
|
||||
|
||||
(Output::Instance()->Post("BDADDR already present in server\n", BLACKBOARD_EVENTS));
|
||||
/* We have this info, returning back */
|
||||
return B_OK;
|
||||
|
||||
} else {
|
||||
size_t size;
|
||||
|
||||
void* command = buildReadBdAddr(&size);
|
||||
|
||||
/* Adding a wanted event in the queue */
|
||||
request->AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
|
||||
request->AddInt16("opcodeExpected", PACK_OPCODE(OGF_INFORMATIONAL_PARAM, OCF_READ_BD_ADDR));
|
||||
|
||||
printf("Adding request... %p\n", request);
|
||||
AddWantedEvent(request);
|
||||
request->PrintToStream();
|
||||
|
||||
if (((HCITransportAccessor*)fHCIDelegate)->IssueCommand(command, size) == B_ERROR)
|
||||
(Output::Instance()->Post("Command issue error\n", BLACKBOARD_EVENTS));
|
||||
|
||||
(Output::Instance()->Post("Command issued for GetAddress\n", BLACKBOARD_EVENTS));
|
||||
return B_WOULD_BLOCK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
LocalDeviceImpl::GetFriendlyName(BString str, BMessage* request)
|
||||
{
|
||||
|
||||
if (fProperties->FindString("friendlyname", &str) == B_OK) {
|
||||
|
||||
(Output::Instance()->Post("Friendly name already present in server\n", BLACKBOARD_EVENTS));
|
||||
/* We have this info, returning back */
|
||||
return B_OK;
|
||||
|
||||
} else {
|
||||
size_t size;
|
||||
|
||||
void* command = buildReadLocalName(&size);
|
||||
|
||||
/* Adding a wanted event in the queue */
|
||||
request->AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
|
||||
request->AddInt16("opcodeExpected", PACK_OPCODE(OGF_CONTROL_BASEBAND, OCF_READ_LOCAL_NAME));
|
||||
|
||||
printf("Adding request... %p\n", request);
|
||||
AddWantedEvent(request);
|
||||
request->PrintToStream();
|
||||
|
||||
if (((HCITransportAccessor*)fHCIDelegate)->IssueCommand(command, size) == B_ERROR)
|
||||
(Output::Instance()->Post("Command issue error\n", BLACKBOARD_EVENTS));
|
||||
|
||||
(Output::Instance()->Post("Command issued for GetFriendlyname\n", BLACKBOARD_EVENTS));
|
||||
|
||||
return B_WOULD_BLOCK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
LocalDeviceImpl::ProcessSimpleRequest(BMessage* request)
|
||||
{
|
||||
ssize_t size;
|
||||
void* command = NULL;
|
||||
|
||||
if (request->FindData("raw command", B_ANY_TYPE, 0, (const void **)command, &size) == B_OK)
|
||||
if (((HCITransportAccessor*)fHCIDelegate)->IssueCommand(command, size) == B_ERROR)
|
||||
(Output::Instance()->Post("Command issue error\n", BLACKBOARD_EVENTS));
|
||||
else
|
||||
{
|
||||
AddWantedEvent(request);
|
||||
return B_OK;
|
||||
}
|
||||
else {
|
||||
(Output::Instance()->Post("No command specified for simple request\n", BLACKBOARD_KIT));
|
||||
}
|
||||
|
||||
return B_ERROR;
|
||||
}
|
44
src/servers/bluetooth/LocalDeviceImpl.h
Normal file
44
src/servers/bluetooth/LocalDeviceImpl.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||
*
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LOCALDEVICE_IMPL_H_
|
||||
#define _LOCALDEVICE_IMPL_H_
|
||||
|
||||
#include <String.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
|
||||
#include "LocalDeviceHandler.h"
|
||||
|
||||
#include "HCIDelegate.h"
|
||||
#include "HCIControllerAccessor.h"
|
||||
#include "HCITransportAccessor.h"
|
||||
|
||||
class LocalDeviceImpl : public LocalDeviceHandler {
|
||||
|
||||
private:
|
||||
LocalDeviceImpl(HCIDelegate* hd);
|
||||
|
||||
public:
|
||||
|
||||
// Factory methods
|
||||
static LocalDeviceImpl* CreateControllerAccessor(BPath* path);
|
||||
static LocalDeviceImpl* CreateTransportAccessor(BPath* path);
|
||||
|
||||
void HandleEvent(struct hci_event_header* event);
|
||||
|
||||
/* Request handling */
|
||||
status_t GetAddress(bdaddr_t* bdaddr, BMessage* request);
|
||||
status_t GetFriendlyName(BString str, BMessage* request);
|
||||
status_t ProcessSimpleRequest(BMessage* request);
|
||||
|
||||
/* Events handling */
|
||||
void CommandComplete(struct hci_ev_cmd_complete* event, BMessage* request);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
179
src/servers/bluetooth/Output.cpp
Normal file
179
src/servers/bluetooth/Output.cpp
Normal file
@ -0,0 +1,179 @@
|
||||
#ifndef _Output_h
|
||||
#include "Output.h"
|
||||
#endif
|
||||
|
||||
#include <Looper.h>
|
||||
#include <String.h>
|
||||
|
||||
/*
|
||||
#ifndef _Preferences_h
|
||||
#include "Preferences.h"
|
||||
#endif
|
||||
*/
|
||||
|
||||
/****************************************************************/
|
||||
/* OutputView */
|
||||
/****************************************************************/
|
||||
|
||||
OutputView::OutputView(BRect frame) :
|
||||
BView(frame, "OutputView", B_FOLLOW_ALL_SIDES, B_WILL_DRAW)
|
||||
{
|
||||
SetViewColor(216,216,216);
|
||||
rgb_color color = {255,255,255};
|
||||
|
||||
BRect b = Bounds();
|
||||
AddChild(m_pTextView = new BTextView(BRect(b.left+5,b.top+5,b.right-B_V_SCROLL_BAR_WIDTH-6,b.bottom-5), "Output", BRect(b.left+5,b.top+5,b.right-B_V_SCROLL_BAR_WIDTH-6,b.bottom-5), NULL, &color, B_FOLLOW_ALL_SIDES, B_WILL_DRAW));
|
||||
m_pTextView->SetViewColor(0,0,100);
|
||||
m_pTextView->MakeEditable(false);
|
||||
|
||||
AddChild(m_pScrollBar = new BScrollBar(BRect(b.right-B_V_SCROLL_BAR_WIDTH-5,b.top+5,b.right-5, b.bottom-5), "outputScroll", m_pTextView, 0, 0, B_VERTICAL));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
OutputView::FrameResized(float width, float height)
|
||||
{
|
||||
BView::FrameResized(width, height);
|
||||
m_pTextView->SetTextRect(BRect(0,0,width,height));
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Output */
|
||||
/****************************************************************/
|
||||
|
||||
// Singleton implementation
|
||||
Output* Output::m_instance = 0;
|
||||
|
||||
Output::Output() :
|
||||
BWindow(BRect(200,200,600,600), "Output", B_TITLED_WINDOW, B_NOT_RESIZABLE)
|
||||
{
|
||||
BRect b = Bounds();
|
||||
|
||||
fTabsList = new BList(20);
|
||||
fOutputViewsList = new BList(20);
|
||||
|
||||
BView* resetView = new BView(BRect(b.left,b.bottom-25,b.right,b.bottom), "resetView", B_FOLLOW_ALL_SIDES, B_WILL_DRAW);
|
||||
resetView->SetViewColor(216,216,216);
|
||||
resetView->AddChild(m_pReset = new BButton(BRect(1,1,61,20), "reset all", "Clear", new BMessage(MSG_OUTPUT_RESET), B_FOLLOW_BOTTOM));
|
||||
resetView->AddChild(m_pResetAll = new BButton(BRect(70,1,130,20), "reset", "Clear all", new BMessage(MSG_OUTPUT_RESET_ALL), B_FOLLOW_BOTTOM));
|
||||
AddChild(resetView);
|
||||
|
||||
fTabView = new BTabView(BRect(b.left,b.top,b.right,b.bottom-25), "tab_view", B_WIDTH_FROM_LABEL /*,B_FOLLOW_ALL_SIDES, B_FULL_UPDATE_ON_RESIZE*/);
|
||||
fTabView->SetViewColor(216,216,216);
|
||||
|
||||
fBounds = fTabView->Bounds();
|
||||
fBounds.bottom -= fTabView->TabHeight();
|
||||
|
||||
fTabView->AddTab(m_pAll = new OutputView(fBounds), m_pAllTab = new BTab());
|
||||
m_pAllTab->SetLabel("All");
|
||||
|
||||
AddChild(fTabView);
|
||||
/*
|
||||
MoveTo( Preferences::Instance()->OutputX(),
|
||||
Preferences::Instance()->OutputY());
|
||||
*/
|
||||
}
|
||||
|
||||
void
|
||||
Output::AddTab(const char* text, int32 index)
|
||||
{
|
||||
OutputView* customOutput;
|
||||
BTab* customTab;
|
||||
|
||||
Lock();
|
||||
fTabView->AddTab(customOutput = new OutputView(fBounds), customTab = new BTab());
|
||||
customTab->SetLabel( text );
|
||||
fTabView->Invalidate();
|
||||
Unlock();
|
||||
|
||||
fTabsList->AddItem(customTab, index);
|
||||
fOutputViewsList->AddItem(customOutput, index);
|
||||
|
||||
}
|
||||
|
||||
Output::~Output()
|
||||
{
|
||||
/* BWindow::~BWindow();*/
|
||||
|
||||
delete fTabsList;
|
||||
delete fOutputViewsList;
|
||||
}
|
||||
|
||||
|
||||
Output*
|
||||
Output::Instance()
|
||||
{
|
||||
if (!m_instance)
|
||||
m_instance = new Output;
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Output::QuitRequested()
|
||||
{
|
||||
Hide();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Output::MessageReceived(BMessage* msg)
|
||||
{
|
||||
switch(msg->what)
|
||||
{
|
||||
case MSG_OUTPUT_RESET:
|
||||
|
||||
for (int32 index = 0 ; index<fTabsList->CountItems() ; index++) {
|
||||
if (fTabsList->ItemAt(index) != NULL && ((BTab*)fTabsList->ItemAt(index))->IsSelected() )
|
||||
((OutputView*)fOutputViewsList->ItemAt(index))->Clear();
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
case MSG_OUTPUT_RESET_ALL:
|
||||
m_pAll->Clear();
|
||||
|
||||
for (int32 index = 0 ; index<fTabsList->CountItems() ; index++) {
|
||||
if (fTabsList->ItemAt(index) != NULL )
|
||||
((OutputView*)fOutputViewsList->ItemAt(index))->Clear();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BWindow::MessageReceived(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Output::FrameMoved(BPoint point)
|
||||
{
|
||||
/* Preferences::Instance()->OutputX(point.x);
|
||||
Preferences::Instance()->OutputY(point.y);
|
||||
*/
|
||||
}
|
||||
|
||||
void
|
||||
Output::Post(const char* text, uint32 index)
|
||||
{
|
||||
Lock();
|
||||
OutputView* view = (OutputView*) fOutputViewsList->ItemAt(index);
|
||||
|
||||
if (view != NULL)
|
||||
Add(text, view );
|
||||
else
|
||||
// Note that the view should be added before this!
|
||||
// Dropping twice to the main
|
||||
Add(text, m_pAll );
|
||||
|
||||
Unlock();
|
||||
}
|
||||
|
||||
void
|
||||
Output::Add(const char* text, OutputView* view)
|
||||
{
|
||||
view->Add(text);
|
||||
m_pAll->Add(text);
|
||||
}
|
63
src/servers/bluetooth/Output.h
Normal file
63
src/servers/bluetooth/Output.h
Normal file
@ -0,0 +1,63 @@
|
||||
#ifndef _Output_h
|
||||
#define _Output_h
|
||||
|
||||
#include <Window.h>
|
||||
#include <TextView.h>
|
||||
#include <ScrollBar.h>
|
||||
#include <Button.h>
|
||||
#include <TabView.h>
|
||||
|
||||
const uint32 MSG_OUTPUT_RESET = 'outr';
|
||||
const uint32 MSG_OUTPUT_RESET_ALL = 'opra';
|
||||
|
||||
class OutputView : public BView
|
||||
{
|
||||
public:
|
||||
OutputView(BRect frame);
|
||||
virtual void FrameResized(float width, float height);
|
||||
|
||||
void Add(const char* text) {m_pTextView->Insert(text);}
|
||||
void Clear() {m_pTextView->Delete(0,m_pTextView->TextLength());}
|
||||
|
||||
private:
|
||||
BTextView* m_pTextView;
|
||||
BScrollBar* m_pScrollBar;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class Output : public BWindow
|
||||
{
|
||||
public:
|
||||
static Output* Instance();
|
||||
~Output();
|
||||
virtual bool QuitRequested();
|
||||
virtual void MessageReceived(BMessage* msg);
|
||||
virtual void FrameMoved(BPoint point);
|
||||
|
||||
void AddTab(const char* text, int32 index);
|
||||
|
||||
void Post(const char* text, uint32 index);
|
||||
|
||||
private: // functions
|
||||
Output();
|
||||
void Add(const char* text, OutputView* view);
|
||||
|
||||
private: // data
|
||||
static Output* m_instance;
|
||||
BTab* m_pAllTab;
|
||||
|
||||
OutputView* m_pAll;
|
||||
|
||||
BButton* m_pReset;
|
||||
BButton* m_pResetAll;
|
||||
|
||||
BTabView* fTabView;
|
||||
|
||||
BList* fTabsList;
|
||||
BList* fOutputViewsList;
|
||||
BRect fBounds; // Bounds for tabs
|
||||
};
|
||||
|
||||
|
||||
#endif // _Output_h
|
139
src/servers/bluetooth/server-bluetooth.rdef
Normal file
139
src/servers/bluetooth/server-bluetooth.rdef
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* bluetooth_server.rdef
|
||||
*/
|
||||
|
||||
resource app_signature "application/x-vnd.Be-bluetooth_server";
|
||||
|
||||
resource app_flags B_SINGLE_LAUNCH | B_BACKGROUND_APP;
|
||||
|
||||
resource app_version {
|
||||
major = 0,
|
||||
middle = 1,
|
||||
minor = 0,
|
||||
|
||||
variety = B_APPV_ALPHA,
|
||||
internal = 0,
|
||||
|
||||
short_info = "bluetooth_server",
|
||||
long_info = "bluetooth_server ©2007-2008 Haiku"
|
||||
};
|
||||
|
||||
resource large_icon array {
|
||||
$"6E6369661204004C03FFCD9A01CD9966B204FFF2050004FFB204002B02000602"
|
||||
$"B430A6B1179CB1179C3430A6494C3D4865F300345E7EFF18334E02000602B3DD"
|
||||
$"36B09384B0938433DD3649544C4A60FF00345E7EFF18334E02000602B8E37133"
|
||||
$"395F33395F38E3714843E64A164600D5E0E6FF4977950200060832F6423E45F2"
|
||||
$"BE45F232F642C6D4714ACE2600FFFFFF1FFAFBFC46EBF0F36FD3DEE59BB1C5D2"
|
||||
$"C985A4B8F8517D99FF49779502000602394A6239E1E439E1E4B94A624AAE1A45"
|
||||
$"37F800497795FF18334E0200060238C213394110394110B8C2134AA1CD496B12"
|
||||
$"00345E7EFF18334E02000602B430D02C104F2C104F3430D04A410F4905520034"
|
||||
$"5E7EFF18334E02000602B35905319AC6319AC63359054A22224AB4AC00345E7E"
|
||||
$"FF18334E020006053ABE7DB70C89370C893ABE7D4A249047970000AAC7D62BA2"
|
||||
$"C0D0708BADC1C5668FA8FF49779502000602B62927B6FCA8B6FCA8362927483B"
|
||||
$"8347620500608DACFF345E7E0318334E22021CCC1DBE91CC33BE50CC1DBE91CB"
|
||||
$"92BF87CB92BF87CB92BF87CB60C01CCB60C01CCB79C093CB53C11CCB53C0DACB"
|
||||
$"53C16ECAFCC21DCB3AC1B0CA8DC2DEC665C719C786C5F7C665C719C0ACCCAFC0"
|
||||
$"ACCCAFBFCFCD9BBE36CD9CBECFCDC2BDDECD86BD91CD1CBDA1CD57BD7FCCD8BD"
|
||||
$"49CC0BBCEFCC62BCA0CCD9BAE0CCD9BB94CCFABA4CCCBFB912CBC4B92FCC19B9"
|
||||
$"0D5EB909CB8EB909CB8EB7E3CC8CB605CBCBB685CC55B5E2CBA6B549CB22B549"
|
||||
$"CB4DB549CAE9B62CC9D3B62CC9D3B5BDCA41BD28C018BD28C018BD28C018BD9B"
|
||||
$"BED8BD9BBED8BD9BBDFCBC41BDE2BCB2BDEABC41BDE2B858BECDB858BECDB800"
|
||||
$"BECDB792BE87B7BDBEB5B763BE55B759BDE4B759BE13B759BD3CB87BBC80B7D5"
|
||||
$"BC80B87BBC80C5F0BB43C5F0BB43C5F0BB43C5F8BB3CC5F8BB3CC5FEBB37C784"
|
||||
$"BAEDC68CBAB9CA15BB78CC20BD0CCBA2BC2FCC41BD46CC4DBDB5CC4DBD7ECC4D"
|
||||
$"BE050617EBFFBEFFBE3FC6DFB96BCD02BAB6C5BBB92EC513B9CBC3B6BA7AC27C"
|
||||
$"BA11C30CBA0BC27CBA11B7FCBA11B7FCBA11B67CBA11B7D9BCEEB5CEBCEEB7D9"
|
||||
$"BCEEBB88BCEEBB88BCEEBC18BCF9BC9FBD9DBC9FBD11BC9FBD9DBC36BEB4B3C2"
|
||||
$"C6E1B3C2C6E1B243C861B5ABC8CAB4A5C9D0B5ABC8CAB5B0C8CBB542C933B542"
|
||||
$"C933B3C3CAB3B889CA84B67ECC4AB889CA84B8E3CA25B8E3CA25B7F0CBCDBCC7"
|
||||
$"CB03BB5ACCC2BCC7CB03BD11CABABD19CABCBD19CABCBB5CCC6EC02ACBA7BE42"
|
||||
$"63C02ACBA7C5E4C610CA86C105C9FBC1F9CB12C011CAA9BE6ECAEFBFCBCAA9BE"
|
||||
$"6ECB9EBD9CCB9EBD9CCBE8BCAD0609DFFB03C3A9BAC1C3A9BAC1C3E4BACDC533"
|
||||
$"BBFAC533BB67C533BBFABC4AC583BC42C583BC42C71FBC16C9AABE0EC9AABCA1"
|
||||
$"C9AABE0EC97DBCE7C9E0BCE5C9E0BCE5C931BBD7C58EBBE5C72EBBD0C545BAFC"
|
||||
$"C3C2BA33C3E9BA3AC3C2BA330608BEBFB76FBC5ABCEDBC0EBCEDBC0EBDEABD9C"
|
||||
$"C099BD53BE7BBE08C257BCBEC38FBC9FC0E1BE74C226BDE4BF9CBF05BBF0BF4D"
|
||||
$"BE0EBF29BC0EBE51BC5DBD0BBD31BD28B9C7BCB2B7D9BCEE0609FEBF03C074C4"
|
||||
$"AAC105C5A7C14DC53BC0BDC614BE9FC7C5BEC3C735BDC6C856BCA5CA08BCEDC9"
|
||||
$"77BC5CCA98BA3ECAE0BACFCAE0B9AECAE0BA1ACBDDB98ACBDDBAABCBDDBCC7CB"
|
||||
$"03BC10CBB6BCC7CB03C1B9C614C2DAC5A7C26EC55FC226C55F0609FEBF03BC38"
|
||||
$"C3D2BCC9C4CFBD11C462BC81C53BBA6352BA87C65CB98AC77DB869C92FB8B1C8"
|
||||
$"9EB820C9BFB602CA08B693CA08B572CA08B5DECB04B55ACACBB6B6CB63B88BCA"
|
||||
$"2AB7D4CADDB88BCA2ABD7DC53BBE9FC4CEBE32C486BDEAC4860609FEBF03BA63"
|
||||
$"C1B4BAF3C2B1BB3BC244BAABC31DB88DC4CFB8B1C43EB7B4C55FB693C711B6DB"
|
||||
$"C680B64BC7A1B42DC7EAB535C869B3AAC7ABB409C8E6B378C8E6B499C8E6B6B5"
|
||||
$"C80CB5FEC8BFB6B5C80CBBA8C31DBCC9C2B0BC5CC268BC14C2680205BD35BFBA"
|
||||
$"BD35BFBABE32BFDEC0E1C123C050C0B7C171C190C3FCC268C3B3C190C323C1D8"
|
||||
$"C129C1D8C22BC238C008C16BBE7BC0DBBF0BC123BDEAC0930202BE0EBF29BF9C"
|
||||
$"41BF53BF29C3FCBE2CC323BEE1C2B7BF710203C0E1C28CC14DC2B0C226C2D5C3"
|
||||
$"8FC2F9C323C2B1C3FCC341C420C3F6C420C3F6C347C3890608FFAAB40BC7B5B3"
|
||||
$"D0C75DB481C77BB5A5C63DB56BC6B3B5E0C5C7B6AEC517B61BC56FB741C4BEB8"
|
||||
$"FBC322B8C0C398B936C2ACBA04C1DEBAB2C189BB7CBFBEB427C6B30608FFAAB5"
|
||||
$"D7C9C8B59CC96FB64DC98DB772C84FB737C8C5B7ADC7D9B87BC729B7E8C781B9"
|
||||
$"0EC6D1BAC7C534BA8DC5AABB02C4BFBBD0C3F1BCDBC3BFBC0BC2E8B5F3C8C506"
|
||||
$"08FFEAB96DCAC8B8EBCA51B9E3CA8DBB0858BACDC9C5BB42C8DABC10C829BB7D"
|
||||
$"C882BC7FC7E7BDFDC6A8BD72C731BE2CC67BBDB3C6A8BC09C7EBBB73C7E7B989"
|
||||
$"C9C5B989C9C5B989C9C50606FF0EBD54CBBBBC54CB85BDC9CB80BEEECA43BEB3"
|
||||
$"CAB8BF29C9CDBFF7C91CBF64C975C059C8E2C1AFC7CDC122C84DC1F7C78BC090"
|
||||
$"C7ACBD70CAB8BD70CAB8BD70CAB8021ECC2ABC78CC2ABCE0CC2ABC2DCBEABB89"
|
||||
$"CC19BBDCCB54BA82C6EEB924C9B3B9BAC5C4B8E5C4ECB98EC50FB970C4E2B993"
|
||||
$"C3B8BA28C3F0BA0CC37ABA05C279B9C9C2F4B9C4C279B9C9B7FCB9C9B7FCB9C9"
|
||||
$"2AB9C9B64ABBBDB64ABAD0B64ABC25B6AABCC3B66BBC80B6DBBCF8B7DABD36B7"
|
||||
$"38BD36B7DABD36BB88BD36BB88BD36BC2CBD43BC55BD94BC51BD61BC4ABDB0BB"
|
||||
$"F8BE8BBC02BE72BBE1BEA1B390C6AEB390C6AEB327C71620C7DD20C77F20C843"
|
||||
$"B36EC8DBB32FC89DB3C3C931B4C0C968B442C965B472C9EFB4E7CAF2B47DCA80"
|
||||
$"B59FCBB8B876CAEBB72CCBDAB879CAF9B880CB12B87CCB06B8AECB9DBA12CC2C"
|
||||
$"B945CC06BAB3CC49BC49CBCCBB8FCC39BC4ACBE2BC51CC06BC4DCBF6BC6FCC75"
|
||||
$"BD5FCCECBCD2CCC9BE1ECD1CC05FCBD83FCCF0C05DCBDAC616C644C616C644C6"
|
||||
$"42C618CAC5C129CA36C223CB12C0A1CB2FBFE0CB2FC045CB2FBF8ECB03BEBDCB"
|
||||
$"1CBF37CB03BEBDCBDCBDC6CBDCBDC6CBDCBDC60635FBFFBFFABFAFFEBFEAEFFF"
|
||||
$"BFFE03CB69BD56CB7FBD14CB69BD56CA5ABE53CA76BEDACA76BEDACA8EBF51CA"
|
||||
$"9EBFE0CA9EBF9ECA9EC033CA48C0E1CA86C074C9D9C1A3C5B1C5DDC6D2C4BCC5"
|
||||
$"B1C5DDBFF7CB73BFF7CB73BF1BCC5FBD82CC60BE1BCC86BD2ACC4ABCDDCBE0BC"
|
||||
$"ECCC1BBCCACB9DBD4BCAF0BCF1CB47BD4BCAF0BD46CAEBBD46CAEBBE62C9D7C2"
|
||||
$"6EC5E5C164C5B3C19BC5E9BC94CACFBC94CACFBBECCB9DBA2BCB9EBAE0CBBEB9"
|
||||
$"98CB83B909CAE4B926CB3AB903CAD4B901CAB5B901CAC5B901CA92B91ECA50B9"
|
||||
$"0DCA70B96CC9FFB9C9C99DB9C3C997B9C3C997BAC1C8A0BDF9C580BD52C622BE"
|
||||
$"12C568BE98C52CBD7DC4B2BD93C519B8F6C995B8F6C995B8D7C9B7B8ADC9F6B8"
|
||||
$"C0C9D7B8ADC9F6B855CA52B855CA52B72FCB50B551CA90B5D1CB19B52ECA6AB5"
|
||||
$"1CCA16B51CCA41B51CC9DDB575C966B53AC9A1B576C966BBFFC345BB6FC27CBB"
|
||||
$"46C346B57CC89BB578C897B578C897B509C906B3D4C875B43FC8E0B36FC810B3"
|
||||
$"F6C715B37BC78FB3F6C715BC74BEDCBCE7BD9CBCE7BD9CBCE7BCC1BB8DBCA6BB"
|
||||
$"FEBCAFBB8DBCA6B7DABCA6B7DABCA6B781BCA6B713BC60B73FBC8EB6E4BC2EB6"
|
||||
$"DABBBDB6DABBECB6DABB15B7FCBA59B757BA59B7FCBA59C27CBA59C27CBA59C2"
|
||||
$"E1BA55C38EBAB6C364BA9BC38EBAB6C3B1BACDC53CBA07C544BA00C544BA00C5"
|
||||
$"4AB9FBC6D0B9B2C5D8B97DC961BA3CCB6CBBD1CAEEBAF3CB8DBC0ACB99BC79CB"
|
||||
$"99BC43CB99BCC90207C3EFBDBFC49EBCD1C46EBD50C55CBC72C49EBC92C61ABC"
|
||||
$"52C904BD01C826BC23C855BD01C6F8BE6DC708BDDFC6E9BEFCC65ABEADC699BE"
|
||||
$"DCC61ABE7DC5EBBD9FC5EBBDEFC5EBBD50C6C9BCD1C65ABCE1C5ABBCF10610FF"
|
||||
$"ABBAFFCAA9BE6ECAA9BE6ECB9EBD9CCA7ABAC9CCBCBBA2CAE6BBA2C97DBCE7CA"
|
||||
$"0DBCE7C97DBD78C880C0B7CA0DBEE1C82CC11AC796C1C9C7DEC175C62CC1FFC4"
|
||||
$"25C1A2C434C3A8C408C393C407C51CC051C7B1C283C7C5C283C7C5C19CC8BCC0"
|
||||
$"99C9BFBE32CBDDBEC3CBDDBDA2CBDDBDA2CC92BCEDCC92BE57CC92C202C9BFBF"
|
||||
$"9CCC25C468C759CAE6BFDECAC2C18FCB0ABE2C0612BAAEEBBA0ABFF4B304BB6C"
|
||||
$"B4F1BB6CB596BB6CB56EBB3AB5A8B990B63DB823B729BB08BCC6BAE7BC85BACE"
|
||||
$"BCEBB83EBE93B9ABC156BB6BC07EBB0FC0AABB6BC0F5BB6CC4E4BCF5C6B4C166"
|
||||
$"C44FC166C44FC169C44EC515C1F1C534C1DCC273BC63C293BCA3C2ACBC3DC548"
|
||||
$"BA89C17FB32CBFFE200203BD4BB80EBD4BB8EFBDFFB96BBEDBBB15BE79BA59BE"
|
||||
$"A7BB37BD4BBC18BDF9BBA7BD4BBA2D0203BD4BBFB8BD4BC182BDECC0F0BEC5C2"
|
||||
$"95BE94C237BE67C2D2BD4BC38ABDF7C31ABD4BC2B5060EAEEBE90ABC14B560BC"
|
||||
$"14BB25BC14B86EBB0DB929B9DAB6D5B8FEB763BBE3BD00BA72BA35BA82BDE4B9"
|
||||
$"19BECDB9F5C078BC14BF19BB1FBFB7BC14C1ABC4A6BD1DC5E0C07DC3B2BD9BBE"
|
||||
$"1CBEC7C062BED6BD51C093BC32BD1DB57D0203BD4BB80EBD4BB8EFBDFFB96BBE"
|
||||
$"DBBB15BE79BA59BEA7BB37BD4BBC18BDF9BBA7BD4BBA2D0203BD4BBFB8BD4BC1"
|
||||
$"82BDECC0F0BEC5C295BE94C237BE67C2D2BD4BC38ABDF7C31ABD4BC2B5060EBE"
|
||||
$"EFEF0FBC6CBC86B9BAB74DBA02B7DAB996B765B96BB780B98CB76BB9ABB7FBBC"
|
||||
$"51BD1DB986BEEBB9F0BEA6B9ACBF34BA15BFFFB9E9BFA9BA87BFB6BC67BE7FBC"
|
||||
$"67C487BC67C44DBC83C4A8BD2EC571BCF3C52DBD90C532C010C395BFAAC3D6BF"
|
||||
$"D0C31ABD2EBDFFC025BC15BFBABC5ABFE7BB9BBCE7B5CCBD0DB615BCC3B5C8BC"
|
||||
$"67B5BEBCA2B5C4BC67B6620A03BCF7B6C5BF48BB33BCF7BCB20A03BCFCBE5CBF"
|
||||
$"32C2B3BCF7C4240A04BD1DB57DC112B3C8C46EBA4FC093BC320A04BD9BBE1CC1"
|
||||
$"9ABC28C45BC1A1C07DC3B20A04BD9BBE1CC093BC32C46EBA4FC19ABC280A04BD"
|
||||
$"1DC5E0C07DC3B2C45BC1A1C112C3BE0A04BC14B560BD1DB57DC112B3C8C017B3"
|
||||
$"AB0A03B9DAB6D5BC14BB25BC14B60D0A03B9F5C078BC13BF74BC14BF191E0A00"
|
||||
$"0100000A010101000A020102000A020103000A020104000A020105000A020106"
|
||||
$"000A020107000A020108000A020109000A03010A000A03010B000A03010C000A"
|
||||
$"03010D000A04020E0F000A050110000A020111000A0600000A040112000A0701"
|
||||
$"13000A080114000A0903151617000A0A0318191A000A0B011B000A0C011C000A"
|
||||
$"0D011D000A0E011E000A0F011F000A100120000A11012100"
|
||||
};
|
Loading…
Reference in New Issue
Block a user