diff -ur --exclude=po gnokii-20030421/common/devices/unixbluetooth.c gnokii/common/devices/unixbluetooth.c --- gnokii-20030421/common/devices/unixbluetooth.c Mon Apr 21 17:00:30 2003 +++ gnokii/common/devices/unixbluetooth.c Mon Apr 21 22:52:55 2003 @@ -79,6 +83,7 @@ int bluetooth_close(int fd, struct gn_statemachine *state) { + sleep(2); return close(fd); } diff -ur --exclude=po gnokii-20030421/common/links/fbus-phonet.c gnokii/common/links/fbus-phonet.c --- gnokii-20030421/common/links/fbus-phonet.c Mon Apr 21 17:00:31 2003 +++ gnokii/common/links/fbus-phonet.c Tue Apr 22 00:32:04 2003 @@ -45,6 +45,7 @@ #include "gnokii.h" #include "device.h" #include "links/fbus-phonet.h" +#include "links/fbus.h" #include "gnokii-internal.h" #ifdef HAVE_IRDA @@ -55,22 +56,51 @@ #define FBUSINST(s) ((phonet_incoming_message *)((s)->link.link_instance)) +#define FBUS_BLUEZ_INITSEQ 0xd0, 0x00, 0x01 /*--------------------------------------------*/ static bool phonet_open(struct gn_statemachine *state) { - int result; + int result, i, n, total = 0; + unsigned char init_sequence[] = { FBUS_BLUEZ_FRAME_ID, + FBUS_BLUEZ_DEVICE_PC, + FBUS_BLUEZ_DEVICE_PHONE, + FBUS_BLUEZ_INITSEQ, + 0x04}; + unsigned char init_resp[7]; + unsigned char init_pattern[7] = { FBUS_BLUEZ_FRAME_ID, + FBUS_BLUEZ_DEVICE_PHONE, + FBUS_BLUEZ_DEVICE_PC, + FBUS_BLUEZ_INITSEQ, + 0x05}; + + memset(&init_resp, 0, 7); /* Open device. */ - result = device_open(state->config.port_device, false, false, false, GN_CT_Irda, state); + result = device_open(state->config.port_device, false, false, false, + state->config.connection_type, state); if (!result) { perror(_("Couldn't open PHONET device")); return false; } - return (true); + if (state->config.connection_type == GN_CT_Bluetooth) { + device_write(&init_sequence, 7, state); + while (total < 7) { + n = device_read(&init_resp + total, 7 - total, state); + total += n; + } + for (i = 0; i < n; i++) { + if (init_resp[i] != init_pattern[i]) { + dprintf("Incorrect byte in the answer\n"); + return false; + } + } + } + + return true; } /* RX_State machine for receive handling. Called once for each character @@ -83,7 +113,8 @@ switch (i->state) { case FBUS_RX_Sync: - if (rx_byte == FBUS_PHONET_FRAME_ID) { + if (rx_byte == FBUS_PHONET_FRAME_ID || + rx_byte == FBUS_BLUEZ_FRAME_ID) { i->state = FBUS_RX_GetDestination; } break; @@ -93,9 +124,10 @@ i->message_destination = rx_byte; i->state = FBUS_RX_GetSource; - if (rx_byte != 0x0c) { + if (rx_byte != FBUS_DEVICE_PHONE && + rx_byte != FBUS_BLUEZ_DEVICE_PHONE) { i->state = FBUS_RX_Sync; - dprintf("The fbus stream is out of sync - expected 0x0c, got %2x\n", rx_byte); + dprintf("The fbus stream is out of sync - expected 0x0c, got 0x%2x\n", rx_byte); } break; @@ -104,11 +136,10 @@ i->message_source = rx_byte; i->state = FBUS_RX_GetType; - /* Source should be 0x00 */ - - if (rx_byte!=0x00) { + if (rx_byte != FBUS_DEVICE_PC && + rx_byte != FBUS_BLUEZ_DEVICE_PC) { i->state = FBUS_RX_Sync; - dprintf("The fbus stream is out of sync - expected 0x00, got %2x\n", rx_byte); + dprintf("The fbus stream is out of sync - expected 0x00, got 0x%2x\n", rx_byte); } break; @@ -199,9 +230,15 @@ /* Now construct the message header. */ - out_buffer[current++] = FBUS_PHONET_FRAME_ID; - out_buffer[current++] = FBUS_DEVICE_PHONE; /* Destination */ - out_buffer[current++] = FBUS_DEVICE_PC; /* Source */ + if (state->config.connection_type == GN_CT_Bluetooth) { + out_buffer[current++] = FBUS_BLUEZ_FRAME_ID; + out_buffer[current++] = FBUS_BLUEZ_DEVICE_PC; + out_buffer[current++] = FBUS_BLUEZ_DEVICE_PHONE; + } else { + out_buffer[current++] = FBUS_PHONET_FRAME_ID; + out_buffer[current++] = FBUS_DEVICE_PHONE; /* Destination */ + out_buffer[current++] = FBUS_DEVICE_PC; /* Source */ + } out_buffer[current++] = messagetype; /* Type */ @@ -239,6 +276,7 @@ gn_error phonet_initialise(struct gn_statemachine *state) { gn_error error = GN_ERR_FAILED; + bool connected; /* Fill in the link functions */ state->link.loop = &phonet_loop; @@ -247,10 +285,27 @@ if ((FBUSINST(state) = calloc(1, sizeof(phonet_incoming_message))) == NULL) return GN_ERR_MEMORYFULL; - if ((state->config.connection_type == GN_CT_Infrared) || (state->config.connection_type == GN_CT_Irda)) { - if (phonet_open(state) == true) { + switch (state->config.connection_type) { + case GN_CT_Infrared: + case GN_CT_Irda: + if (phonet_open(state) == true) error = GN_ERR_NONE; + break; + case GN_CT_Bluetooth: +#ifdef HAVE_BLUETOOTH + /* If there's no valid configuration in the .gnokiirc, try + * to connect over tty interface */ + if (!bacmp(BDADDR_ANY, &state->config.bt_address)) { + state->config.connection_type = GN_CT_Serial; + connected = fbus_initialise(0, state); + } else { + connected = phonet_open(state); } + if (connected) error = GN_ERR_NONE; +#endif + break; + default: + break; } if (error != GN_ERR_NONE) { free(FBUSINST(state)); diff -ur --exclude=po gnokii-20030421/common/links/fbus.c gnokii/common/links/fbus.c --- gnokii-20030421/common/links/fbus.c Mon Apr 21 17:00:31 2003 +++ gnokii/common/links/fbus.c Mon Apr 21 00:13:00 2003 @@ -577,15 +575,6 @@ default: break; } - break; - case GN_CT_Bluetooth: -#ifdef HAVE_BLUETOOTH - /* If there's no valid configuration in the .gnokiirc, try - * to connect over tty interface */ - if (!bacmp(BDADDR_ANY, &state->config.bt_address)) - state->config.connection_type = GN_CT_Serial; - connection = at2fbus_serial_open(state, state->config.connection_type); -#endif break; default: break; diff -ur --exclude=po gnokii-20030421/common/phones/nk6510.c gnokii/common/phones/nk6510.c --- gnokii-20030421/common/phones/nk6510.c Mon Apr 21 17:00:31 2003 +++ gnokii/common/phones/nk6510.c Tue Apr 22 00:16:44 2003 @@ -382,24 +382,46 @@ err = fbus_initialise(attempt++, state); break; case GN_CT_Bluetooth: - attempt = 2; - err = fbus_initialise(attempt++, state); - break; +#ifdef HAVE_BLUETOOTH + /* Quoting Marcel Holtmann from gnokii-ml: + * "I discovered some secrets of the Nokia Bluetooth support in the 6310 + * generation. They use a special SDP entry, which is not in the public + * browse group of their SDP database. And here it is: + * + * Attribute Identifier : 0x0 - ServiceRecordHandle + * Integer : 0x10006 + * Attribute Identifier : 0x1 - ServiceClassIDList + * Data Sequence + * UUID128 : 0x00005002-0000-1000-8000-0002ee00-0001 + * Attribute Identifier : 0x4 - ProtocolDescriptorList + * Data Sequence + * Data Sequence + * UUID16 : 0x0100 - L2CAP + * Data Sequence + * UUID16 : 0x0003 - RFCOMM + * Channel/Port (Integer) : 0xe + * + * The main secret of this is that they use RFCOMM channel 14 for their + * communication protocol." + */ + state->config.rfcomm_cn = 14; +#endif case GN_CT_Infrared: case GN_CT_Irda: err = phonet_initialise(state); + attempt = 3; break; default: return GN_ERR_NOTSUPPORTED; } - + if (err != GN_ERR_NONE) { dprintf("Error in link initialisation: %d\n", err); continue; } - + sm_initialise(state); - + /* Now test the link and get the model */ gn_data_clear(&data); data.model = model; diff -ur --exclude=po gnokii-20030421/include/links/fbus-phonet.h gnokii/include/links/fbus-phonet.h --- gnokii-20030421/include/links/fbus-phonet.h Mon Apr 21 17:00:32 2003 +++ gnokii/include/links/fbus-phonet.h Tue Apr 22 00:22:14 2003 @@ -42,6 +42,16 @@ /* This byte is at the beginning of all GSM Frames sent over PhoNet. */ #define FBUS_PHONET_FRAME_ID 0x14 +/* This byte is at the beginning of all GSM Frames sent over Bluetooth to Nokia 6310 + family phones. */ +#define FBUS_BLUEZ_FRAME_ID 0x19 + +/* Nokia mobile phone in the Nokia 6310 family over Bluetooth. */ +#define FBUS_BLUEZ_DEVICE_PHONE 0x10 + +/* Our PC in the Nokia 6310 family over Bluetooth. */ +#define FBUS_BLUEZ_DEVICE_PC 0x00 + gn_error phonet_initialise(struct gn_statemachine *state); typedef struct {