(iOS, BTstack) Handle case where device is disconnected; set leds to indicate the connected port.

This commit is contained in:
meancoot 2013-06-19 19:24:32 -04:00
parent d73e658473
commit c5d95dbbf7
4 changed files with 55 additions and 37 deletions

View File

@ -178,6 +178,7 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
btpad_connection[slot].has_address = true;
btpad_connection[slot].state = BTPAD_CONNECTING;
btpad_connection[slot].slot = slot;
btpad_queue_l2cap_create_channel(btpad_connection[slot].address, PSM_HID_CONTROL);
btpad_queue_l2cap_create_channel(btpad_connection[slot].address, PSM_HID_INTERRUPT);
@ -188,7 +189,7 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
case HCI_EVENT_INQUIRY_COMPLETE:
{
// TODO: Check performance and batter effect of this
// TODO: Check performance and battery effect of this
btpad_queue_hci_inquiry(HCI_INQUIRY_LAP, 3, 1);
}
break;
@ -211,6 +212,7 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
}
ios_add_log_message("BTpad: L2CAP channel opened: (Slot: %d, PSM: %02X)", slot, psm);
btpad_connection[slot].handle = handle;
if (psm == PSM_HID_CONTROL)
btpad_connection[slot].channels[0] = channel_id;
@ -251,6 +253,7 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
btpad_connection[slot].has_address = true;
btpad_connection[slot].handle = handle;
btpad_connection[slot].state = BTPAD_CONNECTING;
btpad_connection[slot].slot = slot;
}
else break;
}
@ -293,6 +296,26 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
btpad_queue_hci_pin_code_request_reply(event_addr, &packet[2]);
}
break;
case HCI_EVENT_DISCONNECTION_COMPLETE:
{
const uint32_t handle = READ_BT_16(packet, 3);
if (!packet[2])
{
const int32_t slot = btpad_find_slot_for(handle, 0);
if (slot >= 0)
{
btpad_connection[slot].handle = 0;
btpad_disconnect_pad(slot);
ios_add_log_message("BTpad: Device disconnected (Slot: %d)", slot);
}
}
else
ios_add_log_message("BTpad: Got failed 'Disconnection Complete' event (Status: %02X)", packet[2]);
}
break;
}
}

View File

@ -28,6 +28,7 @@ typedef struct
{
enum btpad_state state;
uint32_t slot;
uint16_t handle;
bool has_address;
@ -42,7 +43,6 @@ struct btpad_interface
{
void* (*connect)(const btpad_connection_t* connection);
void (*disconnect)(void* device);
void (*set_leds)(void* device, unsigned leds);
uint32_t (*get_buttons)(void* device);
int16_t (*get_axis)(void* device, unsigned axis);

View File

@ -31,35 +31,11 @@ struct btpad_ps3_data
uint32_t handle;
uint32_t channels[2];
uint32_t slot;
bool have_led;
};
static void btpad_ps3_setleds(struct btpad_ps3_data* device, unsigned leds);
static void* btpad_ps3_connect(const btpad_connection_t* connection)
{
struct btpad_ps3_data* device = malloc(sizeof(struct btpad_ps3_data));
memset(device, 0, sizeof(*device));
memcpy(device->address, connection->address, BD_ADDR_LEN);
device->handle = connection->handle;
device->channels[0] = connection->channels[0];
device->channels[1] = connection->channels[1];
// Magic packet to start reports
static uint8_t data[] = {0x53, 0xF4, 0x42, 0x03, 0x00, 0x00};
bt_send_l2cap_ptr(device->channels[0], data, 6);
// Without this the digital buttons won't be reported
btpad_ps3_setleds(device, 1);
return device;
}
static void btpad_ps3_disconnect(struct btpad_ps3_data* device)
{
}
static void btpad_ps3_setleds(struct btpad_ps3_data* device, unsigned leds)
static void btpad_ps3_send_control(struct btpad_ps3_data* device)
{
// TODO: Can this be modified to turn of motion tracking?
static uint8_t report_buffer[] = {
@ -74,10 +50,35 @@ static void btpad_ps3_setleds(struct btpad_ps3_data* device, unsigned leds)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
report_buffer[11] = (leds & 0xF) << 1;
report_buffer[11] = 1 << ((device->slot % 4) + 1);
bt_send_l2cap_ptr(device->channels[0], report_buffer, sizeof(report_buffer));
}
static void* btpad_ps3_connect(const btpad_connection_t* connection)
{
struct btpad_ps3_data* device = malloc(sizeof(struct btpad_ps3_data));
memset(device, 0, sizeof(*device));
memcpy(device->address, connection->address, BD_ADDR_LEN);
device->handle = connection->handle;
device->channels[0] = connection->channels[0];
device->channels[1] = connection->channels[1];
device->slot = connection->slot;
// Magic packet to start reports
static uint8_t data[] = {0x53, 0xF4, 0x42, 0x03, 0x00, 0x00};
bt_send_l2cap_ptr(device->channels[0], data, 6);
// Without this the digital buttons won't be reported
btpad_ps3_send_control(device);
return device;
}
static void btpad_ps3_disconnect(struct btpad_ps3_data* device)
{
}
static uint32_t btpad_ps3_get_buttons(struct btpad_ps3_data* device)
{
return device->data[3] | (device->data[4] << 8) | ((device->data[5] & 1) << 16);
@ -101,7 +102,7 @@ static void btpad_ps3_packet_handler(struct btpad_ps3_data* device, uint8_t pack
{
if (!device->have_led)
{
btpad_ps3_setleds(device, 1);
btpad_ps3_send_control(device);
device->have_led = true;
}
@ -113,7 +114,6 @@ struct btpad_interface btpad_ps3 =
{
(void*)&btpad_ps3_connect,
(void*)&btpad_ps3_disconnect,
(void*)&btpad_ps3_setleds,
(void*)&btpad_ps3_get_buttons,
(void*)&btpad_ps3_get_axis,
(void*)&btpad_ps3_packet_handler

View File

@ -31,6 +31,7 @@ static void* btpad_wii_connect(const btpad_connection_t* connection)
memcpy(device->addr, connection->address, BD_ADDR_LEN);
device->unid = connection->slot;
device->wiiMoteConHandle = connection->handle;
device->c_source_cid = connection->channels[0];
device->i_source_cid = connection->channels[1];
@ -46,11 +47,6 @@ static void btpad_wii_disconnect(struct wiimote_t* device)
{
}
static void btpad_wii_setleds(struct wiimote_t* device, unsigned leds)
{
// TODO
}
static uint32_t btpad_wii_get_buttons(struct wiimote_t* device)
{
return device->btns | (device->exp.classic.btns << 16);
@ -117,7 +113,6 @@ struct btpad_interface btpad_wii =
{
(void*)&btpad_wii_connect,
(void*)&btpad_wii_disconnect,
(void*)&btpad_wii_setleds,
(void*)&btpad_wii_get_buttons,
(void*)&btpad_wii_get_axis,
(void*)&btpad_wii_packet_handler