* [Bluez-devel] l2cap connection problems
@ 2004-07-13 21:50 becicka
2004-07-15 10:58 ` Marcel Holtmann
0 siblings, 1 reply; 4+ messages in thread
From: becicka @ 2004-07-13 21:50 UTC (permalink / raw)
To: bluez-devel
[-- Attachment #1: Type: text/plain, Size: 1476 bytes --]
I have written a client and server that need to be able to
communicate over Bluetooth. I am attempting to use L2CAP, but
am not able to consistently connect to the server. My
application requires the server socket that accepts L2CAP
connections to be non-blocking. On the client side, I am
using a non-blocking connect (connect with 2 second timeout).
However, in trying to debug the connection problem, I have
tried using non-blocking sockets at both ends. Even in this
situation, my results were the same. Sometimes the connection
is accepted immediately (roughly half the time), the server
begins streaming data to the client, and everything works
great. Just as frequently, the connection attempt times out
at the client (when the client uses a blocking connect), or
the connection succeeds after some number (potentially very
many) of non-blocking connect attempts. Occasionally the
connection attempt appears as if it will never succeed. I
have attached a file containing hcidump output for 3 cases
which are annotated in the file. In all 3 cases a blocking
accept is used at the server. It seems as if the HCI layer
events are identical regardless of whether or not the L2CAP
layer accept (server) and connect (client) succeed. Any
thoughts as to what the problem might be? For whatever it's
worth, I am using D-Link DBT120 USB adapters. Thanks in advance.
Troy K. Becicka
Graduate Student
University of Illinois at Urbana-Champaign
Computer Engineering
[-- Attachment #2: bt_con_debug --]
[-- Type: APPLICATION/OCTET-STREAM, Size: 5519 bytes --]
This is the hcidump output at the server when a blocking
connect is used and the connection is not accepted
(i.e. eventually times out).
> HCI Event: Connect Request(0x04) plen 10
< HCI Command: Accept Connection Request(0x01|0x0009) plen 7
> HCI Event: Command Status(0x0f) plen 4
> HCI Event: Connect Complete(0x03) plen 11
< HCI Command: Change Connection Packet Type(0x01|0x000f) plen 4
> HCI Event: Command Status(0x0f) plen 4
> HCI Event: Connection Packet Type Changed(0x1d) plen 5
> HCI Event: Max Slots Change(0x1b) plen 3
> ACL data: handle 0x0004 flags 0x02 dlen 12
L2CAP(s): Connect req: psm 100 scid 0x0040
< ACL data: handle 0x0004 flags 0x02 dlen 16
L2CAP(s): Connect rsp: dcid 0x0040 scid 0x0040 result 0 status 0
> HCI Event: Max Slots Change(0x1b) plen 3
> HCI Event: Number of Completed Packets(0x13) plen 5
This is the hcidump output at the server for one timeout
period (i.e. using a nonblocking connect) when the connection
is not accepted.
> HCI Event: Connect Request(0x04) plen 10
< HCI Command: Accept Connection Request(0x01|0x0009) plen 7
> HCI Event: Command Status(0x0f) plen 4
> HCI Event: Connect Complete(0x03) plen 11
< HCI Command: Change Connection Packet Type(0x01|0x000f) plen 4
> HCI Event: Command Status(0x0f) plen 4
> HCI Event: Connection Packet Type Changed(0x1d) plen 5
> HCI Event: Max Slots Change(0x1b) plen 3
> ACL data: handle 0x0004 flags 0x02 dlen 12
L2CAP(s): Connect req: psm 100 scid 0x0040
< ACL data: handle 0x0004 flags 0x02 dlen 16
L2CAP(s): Connect rsp: dcid 0x0040 scid 0x0040 result 0 status 0
> HCI Event: Max Slots Change(0x1b) plen 3
> HCI Event: Number of Completed Packets(0x13) plen 5
> HCI Event: Disconn Complete(0x05) plen 4
This is the hcidump output at the server when the connection is accepted.
[root@tale becicka]# hcidump
HCIDump - HCI packet analyzer ver 1.3
device: hci0 snap_len: 1028 filter: 0xffffffff
> HCI Event: Connect Request(0x04) plen 10
< HCI Command: Accept Connection Request(0x01|0x0009) plen 7
> HCI Event: Command Status(0x0f) plen 4
> HCI Event: Connect Complete(0x03) plen 11
< HCI Command: Change Connection Packet Type(0x01|0x000f) plen 4
> HCI Event: Command Status(0x0f) plen 4
> HCI Event: Connection Packet Type Changed(0x1d) plen 5
> HCI Event: Max Slots Change(0x1b) plen 3
> HCI Event: Max Slots Change(0x1b) plen 3
> ACL data: handle 0x0004 flags 0x02 dlen 12
L2CAP(s): Connect req: psm 100 scid 0x0040
< ACL data: handle 0x0004 flags 0x02 dlen 16
L2CAP(s): Connect rsp: dcid 0x0040 scid 0x0040 result 0 status 0
> HCI Event: Number of Completed Packets(0x13) plen 5
> ACL data: handle 0x0004 flags 0x02 dlen 12
L2CAP(s): Config req: dcid 0x0040 flags 0x0000 clen 0
< ACL data: handle 0x0004 flags 0x02 dlen 14
L2CAP(s): Config rsp: scid 0x0040 flags 0x0000 result 0 clen 0
< ACL data: handle 0x0004 flags 0x02 dlen 12
L2CAP(s): Config req: dcid 0x0040 flags 0x0000 clen 0
> HCI Event: Number of Completed Packets(0x13) plen 5
> ACL data: handle 0x0004 flags 0x02 dlen 14
L2CAP(s): Config rsp: scid 0x0040 flags 0x0000 result 0 clen 0
> ACL data: handle 0x0004 flags 0x02 dlen 6
L2CAP(d): cid 0x40 len 2 [psm 100]
< ACL data: handle 0x0004 flags 0x02 dlen 32
L2CAP(d): cid 0x40 len 28 [psm 100]
> HCI Event: Number of Completed Packets(0x13) plen 5
< ACL data: handle 0x0004 flags 0x02 dlen 32
L2CAP(d): cid 0x40 len 28 [psm 100]
> HCI Event: Number of Completed Packets(0x13) plen 5
< ACL data: handle 0x0004 flags 0x02 dlen 32
L2CAP(d): cid 0x40 len 28 [psm 100]
> HCI Event: Number of Completed Packets(0x13) plen 5
< ACL data: handle 0x0004 flags 0x02 dlen 32
L2CAP(d): cid 0x40 len 28 [psm 100]
< ACL data: handle 0x0004 flags 0x02 dlen 32
L2CAP(d): cid 0x40 len 28 [psm 100]
> HCI Event: Number of Completed Packets(0x13) plen 5
< ACL data: handle 0x0004 flags 0x02 dlen 32
L2CAP(d): cid 0x40 len 28 [psm 100]
> HCI Event: Number of Completed Packets(0x13) plen 5
< ACL data: handle 0x0004 flags 0x02 dlen 32
L2CAP(d): cid 0x40 len 28 [psm 100]
> HCI Event: Number of Completed Packets(0x13) plen 5
< ACL data: handle 0x0004 flags 0x02 dlen 32
L2CAP(d): cid 0x40 len 28 [psm 100]
> HCI Event: Number of Completed Packets(0x13) plen 5
< ACL data: handle 0x0004 flags 0x02 dlen 32
L2CAP(d): cid 0x40 len 28 [psm 100]
> HCI Event: Number of Completed Packets(0x13) plen 5
< ACL data: handle 0x0004 flags 0x02 dlen 32
L2CAP(d): cid 0x40 len 28 [psm 100]
> HCI Event: Number of Completed Packets(0x13) plen 5
< ACL data: handle 0x0004 flags 0x02 dlen 32
L2CAP(d): cid 0x40 len 28 [psm 100]
> HCI Event: Number of Completed Packets(0x13) plen 5
< ACL data: handle 0x0004 flags 0x02 dlen 32
L2CAP(d): cid 0x40 len 28 [psm 100]
> HCI Event: Number of Completed Packets(0x13) plen 5
< ACL data: handle 0x0004 flags 0x02 dlen 32
L2CAP(d): cid 0x40 len 28 [psm 100]
> HCI Event: Number of Completed Packets(0x13) plen 5
< ACL data: handle 0x0004 flags 0x02 dlen 32
L2CAP(d): cid 0x40 len 28 [psm 100]
> HCI Event: Number of Completed Packets(0x13) plen 5
< ACL data: handle 0x0004 flags 0x02 dlen 32
L2CAP(d): cid 0x40 len 28 [psm 100]
> HCI Event: Number of Completed Packets(0x13) plen 5
< ACL data: handle 0x0004 flags 0x02 dlen 32
L2CAP(d): cid 0x40 len 28 [psm 100]
> ACL data: handle 0x0004 flags 0x02 dlen 24
L2CAP(d): cid 0x40 len 20 [psm 100]
> HCI Event: Number of Completed Packets(0x13) plen 5
< ACL data: handle 0x0004 flags 0x02 dlen 32
L2CAP(d): cid 0x40 len 28 [psm 100]
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [Bluez-devel] l2cap connection problems
2004-07-13 21:50 [Bluez-devel] l2cap connection problems becicka
@ 2004-07-15 10:58 ` Marcel Holtmann
0 siblings, 0 replies; 4+ messages in thread
From: Marcel Holtmann @ 2004-07-15 10:58 UTC (permalink / raw)
To: becicka; +Cc: bluez-devel
Hi Troy,
> I have written a client and server that need to be able to
> communicate over Bluetooth. I am attempting to use L2CAP, but
> am not able to consistently connect to the server. My
> application requires the server socket that accepts L2CAP
> connections to be non-blocking. On the client side, I am
> using a non-blocking connect (connect with 2 second timeout).
> However, in trying to debug the connection problem, I have
> tried using non-blocking sockets at both ends. Even in this
> situation, my results were the same. Sometimes the connection
> is accepted immediately (roughly half the time), the server
> begins streaming data to the client, and everything works
> great. Just as frequently, the connection attempt times out
> at the client (when the client uses a blocking connect), or
> the connection succeeds after some number (potentially very
> many) of non-blocking connect attempts. Occasionally the
> connection attempt appears as if it will never succeed. I
> have attached a file containing hcidump output for 3 cases
> which are annotated in the file. In all 3 cases a blocking
> accept is used at the server. It seems as if the HCI layer
> events are identical regardless of whether or not the L2CAP
> layer accept (server) and connect (client) succeed. Any
> thoughts as to what the problem might be? For whatever it's
> worth, I am using D-Link DBT120 USB adapters. Thanks in advance.
I can't really follow you what you are trying to achieve. May you better
show us the source code.
>>From the dump I saw you use PSM 100. This PSM is not valid according to
the specification, because PSM values must be odd.
Regards
Marcel
-------------------------------------------------------
This SF.Net email is sponsored by BEA Weblogic Workshop
FREE Java Enterprise J2EE developer tools!
Get your free copy of BEA WebLogic Workshop 8.1 today.
http://ads.osdn.com/?ad_id=4721&alloc_id=10040&op=click
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Bluez-devel] l2cap connection problems
@ 2004-07-15 15:50 becicka
0 siblings, 0 replies; 4+ messages in thread
From: becicka @ 2004-07-15 15:50 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: bluez-devel
[-- Attachment #1: Type: text/plain, Size: 986 bytes --]
Never mind the non-blocking server/client for the moment. In
the meantime I am just working with some simple code to test
l2cap connections (attached init_bt_v2.c). The socket wrapper
functions and HCI wrapper functions I am using are defined in
the attached file hotdec_sock.c. I still am not able to
consistently establish L2CAP connections to the server. I
have tried switching the role of the server to master at
different places in the code without any luck. From the
hcidumps at the client and server, it looks like L2CAP
connection request and response packets are being dropped
quite frequently. Sometimes the L2CAP connect req is sent by
the client but not received at the server. Other times the
connect rsp is sent by the server and not received at the
client. Every once in a while everything goes through and the
connection succeeds. Also, what PSM values should I be using
and what HCI layer initialization do I need to perform?
Thanks in advance for your help.
[-- Attachment #2: hotdec_sock.c --]
[-- Type: application/octet-stream, Size: 14280 bytes --]
#define HOTDEC_SOCK_C
#include "hotdec_sock.h"
#define DEBUG
#ifdef DEBUG
#include <stdarg.h>
#include <errno.h>
// debug()
// a conditional printf() for debugging
void debug(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "DEBUG: ");
vfprintf(stderr, fmt, ap);
va_end(ap);
}
#else
void debug(char *fmt, ...)
{
;
}
#endif
// tcp_socket()
// returns a tcp socket
int tcp_socket()
{
return socket(AF_INET, SOCK_STREAM, 0);
}
// udp_socket()
// returns a udp socket
int udp_socket()
{
return socket(AF_INET, SOCK_DGRAM, 0);
}
int l2_socket()
{
return socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
}
int hci_socket()
{
struct sockaddr_hci addr;
int sock;
printf("Creating HCI socket...");
if ((sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) {
perror("socket");
}
printf("\t\tOK\n");
printf("Calling ioctl reset...");
if( ioctl(sock, HCIDEVRESET, 0) < 0 ){
printf("Reset failed\n");
exit(1);
}
printf("\t\tOK\n");
memset(&addr, 0, sizeof(addr));
printf("Binding socket...");
addr.hci_family = AF_BLUETOOTH;
addr.hci_dev = 0;
if ( bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind");
exit(1);
}
printf("\tOK\n");
printf("Bound at socket:%d, device: 0\n", sock);
return sock;
}
//hci_init()
//restarts hci layer (filters etc)
int hci_init(int dev)
{
int sock_bt;
char buff[100];
int j, i, opt, optsize;
struct sockaddr_hci addr;
struct hci_filter flt;
printf("Creating socket...");
if ((sock_bt = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) {
perror("socket");
exit(1);
}
printf("\t\tOK\n");
/*
printf("Binding socket...");
addr.hci_family = AF_BLUETOOTH;
addr.hci_dev = dev;
if ( bind(sock_bt, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind");
exit(1);
}
printf("\tOK\n");
printf("Bound at socket:%d, device: 0\n", sock_bt);
*/
printf("DOWN-ing device...");
if (ioctl(sock_bt, HCIDEVDOWN, 0)) {
perror("up");
exit(1);
}
printf("\tOK\n");
printf("UP-ing device...");
if (ioctl(sock_bt, HCIDEVUP, 0)) {
perror("up");
exit(1);
}
/*
printf("\tOK\n");
opt = 1;
printf("Setting socket options...");
if ((i = setsockopt(sock_bt, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt))) < 0) {
perror("setsockopt");
exit(1);
}
printf("\tOK\n");
*/
/*
printf("Setting filters...");
// filter out command packets
hci_filter_clear(&flt);
hci_filter_all_events(&flt);
hci_filter_all_ptypes(&flt);
for (i = 0; i < sizeof(flt); i++)
printf("%02x:", (unsigned char)(*((unsigned char *)(&flt) + i)));
if ( setsockopt(sock_bt, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
perror("setsockopt");
exit(1);
}
printf("\tOK\n");
printf("Setting raw...");
if ( ioctl(sock_bt, HCISETRAW, sizeof(addr)) < 0) {
perror("setraw");
exit(1);
}
printf("\tOK\n");
printf("Raw socket:%d\n", sock_bt);
*/
return sock_bt;
}
// hci_reset()
// resets bluetooth module
int hci_reset(int sock_bt)
{
int rt;
char rparam[3];
struct hci_request reset_req;
debug("in reset_ctrl\n");
reset_req.ogf = OGF_HOST_CTL;
reset_req.ocf = OCF_RESET;
reset_req.cparam = NULL;
reset_req.rparam = rparam;
reset_req.rlen = 3;
rt = hci_send_req(sock_bt, &reset_req, 1000);
perror("hci_reset");
return rt;
}
// hci_scan_enable()
// enable scans for connecting clients
int hci_scan_enable(int sock_bt)
{
int rt;
char cparam;
char rparam[3];
struct hci_request scan_req;
debug("in en_scan_ctrl\n");
scan_req.ogf = OGF_HOST_CTL;
scan_req.ocf = OCF_WRITE_SCAN_ENABLE;
cparam = SCAN_INQUIRY|SCAN_PAGE;
scan_req.cparam = &cparam;
scan_req.clen = 1;
scan_req.rparam = rparam;
scan_req.rlen = 3;
rt = hci_send_req(sock_bt, &scan_req, 2000);
if(!(rt < 0))
return 1;
return 0;
}
// hci_set_page_timeout
// Sets the time that a device will wait for a connection acceptance
// before sending a connection failure
int hci_set_page_timeout(int sock_bt, uint16_t timeout)
{
int rt;
char rparam[3];
write_page_timeout_cp write_TO;
struct hci_request req;
req.ogf = OGF_HOST_CTL;
req.ocf = OCF_WRITE_PAGE_TIMEOUT;
write_TO.timeout = timeout;
req.cparam = &write_TO;
req.clen = WRITE_PAGE_TIMEOUT_CP_SIZE;
req.rparam = rparam;
req.rlen = 3;
rt = hci_send_req(sock_bt, &req, 2000);
printf("\nsetting page timeout to %d\n", write_TO.timeout);
if(!(rt < 0))
return 1;
return 0;
}
// hci_read_page_timeout
// Reads the time that a device will wait for a connection acceptance
// before sending a connection failure
int hci_read_page_timeout(int sock_bt)
{
int rt;
char cparam;
read_page_timeout_rp read_TO;
struct hci_request req;
req.ogf = OGF_HOST_CTL;
req.ocf = OCF_READ_PAGE_TIMEOUT;
req.cparam = &cparam;
req.clen = 1;
req.rparam = &read_TO;
req.rlen = READ_PAGE_TIMEOUT_RP_SIZE;
rt = hci_send_req(sock_bt, &req, 2000);
printf("\npage timeout is %d\n", read_TO.timeout);
if(!(rt < 0))
return 1;
return 0;
}
// hci_set_connection_accept_timeout
// Sets the timeout before a device can deny or reject a connection request
int hci_set_connection_accept_timeout(int sock_bt, uint16_t timeout)
{
int rt;
char rparam[3];
uint16_t write_TO;
struct hci_request req;
req.ogf = OGF_HOST_CTL;
req.ocf = 0x0016;
write_TO = timeout;
req.cparam = &write_TO;
req.clen = sizeof(uint16_t);
req.rparam = rparam;
req.rlen = 3;
rt = hci_send_req(sock_bt, &req, 2000);
printf("\nsetting connection accept timeout to %d\n", write_TO);
if(!(rt < 0))
return 1;
return 0;
}
// hci_read_connection_accept_timeout
// Reads the timeout before a device can deny or reject a connection request
int hci_read_connection_accept_timeout(int sock_bt)
{
int rt;
char cparam;
uint16_t read_TO;
struct hci_request req;
req.ogf = OGF_HOST_CTL;
req.ocf = 0x0015;
req.cparam = &cparam;
req.clen = 1;
req.rparam = &read_TO;
req.rlen = sizeof(uint16_t);
rt = hci_send_req(sock_bt, &req, 2000);
printf("\nconnection accept timeout is %d\n", read_TO);
if(!(rt < 0))
return 1;
return 0;
}
// addr_parse()
// Splits a the string given in <parse_str> to two where the
// colon (":") character is found. The part before the colon
// goes to <host> and the part after the colon goes to <port>
int addrParse (char *parse_str, char *host,char *port)
{
char tmp_str[128];
char *tmp;
strcpy (tmp_str,parse_str);
tmp = (char *)strtok(tmp_str,":");
if ( tmp==NULL ) {
fprintf (stderr,"Usage is <host>:<portNo>\n");
return -1;
}
strcpy(host,tmp);
tmp = (char *)strtok(NULL,":");
if ( tmp==NULL ) {
fprintf (stderr,"Usage is <host>:<portNo>\n");
return -2;
}
strcpy(port,tmp);
return 0;
}
// bind_sock_local()
// binds a socket of <type> to the given <port> on local host
// returns result of default bind command
int bind_sock_local(int port, int type)
{
int sockd; //socket descriptor
int bound;
struct sockaddr_in socka; //socket address
struct sockaddr_l2 socka_bt; //socket address
if (type == TYPE_TCP) {
sockd = socket(AF_INET, SOCK_STREAM, 0);
socka.sin_family = AF_INET;
socka.sin_port = htons(port);
socka.sin_addr.s_addr = htonl(INADDR_ANY);
bound = bind(sockd, (struct sockaddr *) &socka, sizeof(struct sockaddr) );
}
else if (type == TYPE_UDP) {
sockd = socket(AF_INET, SOCK_DGRAM, 0);
socka.sin_family = AF_INET;
socka.sin_port = htons(port);
socka.sin_addr.s_addr = htonl(INADDR_ANY);
bound = bind(sockd, (struct sockaddr *) &socka, sizeof(struct sockaddr) );
}
else if (type == TYPE_BT) {
sockd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
perror("socket (TYPE_BT):");
memset(&socka_bt, 0, sizeof(socka_bt));
socka_bt.l2_family = AF_BLUETOOTH;
memcpy(socka_bt.l2_bdaddr.b, BDADDR_ANY, 6);
socka_bt.l2_psm = htobs(4097);
bound = bind(sockd, (struct sockaddr *) &socka_bt, sizeof(socka_bt));
}
if (bound >= 0) {
return sockd;
}
else {
perror("bind local");
return bound;
}
}
// bind_sock_local2()
// binds a socket of <type> to the given <port> on local host
// returns result of default bind command
int bind_sock_str2(char *addr_str, int type)
{
int sockd;
int bound;
char host[256], port[256]; //used for parsing out the host and port
struct hostent *entity;
struct sockaddr_l2 socka_bt; //bluetooth socket address
struct sockaddr_in socka; //inet socket address
if (type == TYPE_TCP) {
addrParse(addr_str, host, port);
sockd = socket(AF_INET, SOCK_STREAM, 0);
socka.sin_family = AF_INET;
socka.sin_port = htons(atoi(port));
entity = gethostbyname(host);
socka.sin_addr = *((struct in_addr *)entity->h_addr);
bound = bind(sockd, (struct sockaddr *) &socka, sizeof(struct sockaddr) );
}
else if (type == TYPE_UDP) {
addrParse(addr_str, host, port);
sockd = socket(AF_INET, SOCK_DGRAM, 0);
socka.sin_family = AF_INET;
socka.sin_port = htons(atoi(port));
entity = gethostbyname(host);
socka.sin_addr = *((struct in_addr *)entity->h_addr);
bound = bind(sockd, (struct sockaddr *) &socka, sizeof(struct sockaddr) );
}
else if (type == TYPE_BT) {
sockd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
memset(&socka_bt, 0, sizeof(socka_bt));
socka_bt.l2_family = AF_BLUETOOTH;
socka_bt.l2_psm = htobs(4097);
baswap(&socka_bt.l2_bdaddr, strtoba(addr_str));
printf("addr=%s\n",batostr(&socka_bt.l2_bdaddr));
bound = bind(sockd, (struct sockaddr *) &socka_bt, sizeof(socka));
}
if (bound >= 0) {
return sockd;
}
else {
printf("sockd = %d;", sockd);
perror("bind");
return bound;
}
}
// bind_sock_local()
// binds a socket of <type> to the given <port> on local host
// returns result of default bind command
int bind_sock_str(int *sockd, char *addr_str, int type)
{
int bound;
char host[256], port[256]; //used for parsing out the host and port
struct hostent *entity;
struct sockaddr_l2 socka_bt; //bluetooth socket address
struct sockaddr_in socka; //inet socket address
bzero(&socka, sizeof(struct sockaddr));
if (type == TYPE_TCP) {
addrParse(addr_str, host, port);
printf("host = %s, port = %s\n", host, port);
*sockd = socket(AF_INET, SOCK_STREAM, 0);
socka.sin_family = AF_INET;
socka.sin_port = htons(atoi(port));
entity = gethostbyname(host);
if (entity == NULL)
printf("null entity\n");
socka.sin_addr = *((struct in_addr *)(entity->h_addr));
bound = bind(*sockd, (struct sockaddr *) &socka, sizeof(struct sockaddr) );
}
else if (type == TYPE_UDP) {
addrParse(addr_str, host, port);
*sockd = socket(AF_INET, SOCK_DGRAM, 0);
socka.sin_family = AF_INET;
socka.sin_port = htons(atoi(port));
entity = gethostbyname(host);
socka.sin_addr = *((struct in_addr *)entity->h_addr);
bound = bind(*sockd, (struct sockaddr *) &socka, sizeof(struct sockaddr) );
}
else if (type == TYPE_BT) {
*sockd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
memset(&socka_bt, 0, sizeof(socka_bt));
socka_bt.l2_family = AF_BLUETOOTH;
socka_bt.l2_psm = htobs(4097);
baswap(&socka_bt.l2_bdaddr, strtoba(addr_str));
bound = bind(*sockd, (struct sockaddr *) &socka_bt, sizeof(socka));
}
if (bound >= 0) {
return *sockd;
}
else {
printf("sockd = %d;", *sockd);
printf(" error = %d;", errno);
perror("bind");
return bound;
}
}
// set_nonblock_sock()
// that's right!
int set_nonblock_sock(int sockd) {
int flags, i;
flags = fcntl(sockd, F_GETFL);
debug(" (get fctl returned %i) ", flags);
flags |= O_NONBLOCK;
i = fcntl(sockd, F_SETFL, flags);
debug(" (set fctl returned %i) ", i);
}
// listen_sock()
// makes a sock listen to given <port> for incoming connections of <type>
// will return the default return value of the listen unix cmd
// user can later run accept_sock() on that socket
// Assume that there was a call like:
// sockd = bind_sock_local(port, type);
// NOTE: backlog is 10 by default.
int listen_sock(int sockd, int type)
{
struct sockaddr_in socka; //socket address
if (type == TYPE_TCP) {
return listen(sockd, 10);
}
else if (type == TYPE_BT) {
return listen(sockd, 10);
;
}
}
// connect_sock()
// will connect to bluetooth socket
int connect_bt(int sock, struct sockaddr_l2 addr) {
return connect(sock, (struct sockaddr *)&addr, sizeof(addr));
}
// accept_sock()
// puts the accepted connection to socket number it returns
// and the source address in the parameter <src_addr>
// need a listening socket <sockd_listen>
// FIXME: will be a wrapper-function if problems arise
int accept_sock(int sockd_listen, struct sockaddr *addr, int *size)
{
return accept(sockd_listen, addr, size);
}
// make_bc()
// makes a socket broadcasting
int make_bc(int sockd)
{
const int on = 1;
return setsockopt(sockd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
}
// reuse_addr()
// makes a socket address shared
int reuse_addr(int sock)
{
int r;
int one = 5;
r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
perror("reuse_addr SO_REUSEADDR");
return r;
}
// assign_addr_str()
// creates an address structure for use and returns a pointer to it
void *addr_by_name(char *host, int port, int type)
{
int r;
struct hostent *entity;
struct sockaddr_in *socka;
struct sockaddr_l2 *socka_bt;
if (type == TYPE_TCP || type == TYPE_UDP) {
socka = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
entity = gethostbyname(host);
if (entity == NULL) {
perror("addr_by_name(): gethostbyname");
return (struct sockaddr_in *)(-1);
}
socka->sin_addr = *((struct in_addr *)(entity->h_addr));
socka->sin_family = AF_INET;
socka->sin_port = htons(port);
return socka;
}
else if (type == TYPE_BT) {
socka_bt = (struct sockaddr_l2 *)malloc(sizeof(struct sockaddr_l2));
socka_bt->l2_family = AF_BLUETOOTH;
socka_bt->l2_psm = htobs(4097);
baswap(&(socka_bt->l2_bdaddr), strtoba(host));
perror("baswap");
return socka_bt;
}
}
[-- Attachment #3: hotdec_sock.h --]
[-- Type: application/octet-stream, Size: 2137 bytes --]
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <bluetooth.h>
#include <resolv.h>
#include <l2cap.h>
#include <hci.h>
#include <hci_lib.h>
#include <fcntl.h>
// types for hotdec_sock.type
#define TYPE_UDP 1
#define TYPE_TCP 2
#define TYPE_BT 3
// connection status for hotdec_sock
#define STATUS_CONN 1
#define STATUS_DISC 2
struct hotdec_sock {
int type; // udp, tcp or bluetooth type
int status; // connected or not
int socket_no; // socket descriptor
int blocking; // = 1 if blocking, 0 else (blocking is default)
int sent_msg_count; // total no. of messages after initialization
int recv_msg_count;
struct sockaddr_in remoteAddr;
struct sockaddr_in localAddr;
};
// type of messages
#define CONTROL_MSG 1
#define STREAM_MSG 2
// direction
#define INCOMING_MSG 1
#define OUTGOINT_MSG 2
struct hotdec_msg {
int type; // control (real-time), or stream
int direction; // incoming or outgoing
int header_len; // length of header
int body_len; // length of main message
char *header;
char *body;
union {
struct hotdec_sock *dest;
struct hotdec_sock *src;
} sock;
};
#ifndef HOTDEC_SOCK_C
extern void debug(char *fmt, ...);
extern int udp_socket();
extern int l2_socket();
extern int hci_socket();
extern int hci_scan_enable(int sock_bt);
extern int hci_reset(int sock_bt);
extern int hci_init(int sock_bt);
extern int tcp_socket();
extern int addrParse (char *parse_str, char *host,char *port);
extern int bind_sock_local(int port, int type);
extern int bind_sock_str(int *sockd, char *addr_str, int type);
extern int bind_sock_str2(char *addr_str, int type);
extern int set_nonblock_sock(int sockd);
extern int listen_sock(int sockd, int type);
extern int accept_sock(int sockd_listen, struct sockaddr *addr, int *size);
extern void *addr_by_name(char *host, int port, int type);
extern int make_bc(int sockd);
extern int reuse_addr(int sock);
extern int reset_bt();
#endif
[-- Attachment #4: Makefile --]
[-- Type: application/octet-stream, Size: 307 bytes --]
CC=gcc
INCLUDE=-I/usr/include/bluetooth
LIBS=-lbluetooth -lm
CFLAGS=-g $(INCLUDE) $(LIBS)
run: hotdec_sock.o init_bt_v2.c
$(CC) -o run $(CFLAGS) hotdec_sock.o init_bt_v2.c
hotdec_sock.o: hotdec_sock.h hotdec_sock.c
$(CC) -o hotdec_sock.o -c $(INCLUDE) hotdec_sock.c
.PHONY: clean
clean:
-rm *o run
[-- Attachment #5: init_bt_v2.c --]
[-- Type: application/octet-stream, Size: 2727 bytes --]
#include "hotdec_sock.h"
#define CLIENT_MODE 1
#define SERVER_MODE 2
int main (int argc, char *argv[])
{
int sock1, sock2;
int s_local_bt;
int opt, len, mode;
int i;
int s_hci;
struct sockaddr_l2 *sa_bt,rem_addr;
char buf[256];
if(argc != 2)
{
printf("usage: ./run --server/--client\n");
exit(0);
}
if(strcmp(argv[1], "--client") == 0)
mode = CLIENT_MODE;
else if(strcmp(argv[1], "--server") == 0)
mode = SERVER_MODE;
s_hci = hci_socket();
//hci_reset(s_hci);
//hci_init(s_hci);
hci_scan_enable(s_hci);
//hci_read_page_timeout(s_hci);
//hci_set_page_timeout(s_hci, 63000);
//hci_read_page_timeout(s_hci);
//hci_read_connection_accept_timeout(s_hci);
//hci_set_connection_accept_timeout(s_hci, 6200);
//hci_read_connection_accept_timeout(s_hci);
close(s_hci);
if(mode == SERVER_MODE)
{
printf("tale:\n");
s_local_bt = bind_sock_local(0, TYPE_BT);
printf("local socket is no %d\n", s_local_bt);
len = listen_sock(s_local_bt, TYPE_BT);
printf("listen returns %d\n", len);
opt = sizeof(rem_addr);
/* i = getsockopt(s_local_bt, SOL_L2CAP, L2CAP_LM, &opt, &len);
printf("getsockopt = %d options are %d\n", i, opt);
opt |= L2CAP_LM_MASTER;
setsockopt(s_local_bt, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt));
printf("setsockopt = %d\n", i);
i = getsockopt(s_local_bt, SOL_L2CAP, L2CAP_LM, &opt, &len);
printf("getsockopt = %d options are %d\n", i, opt); */
sock1 = accept(s_local_bt, (struct sockaddr *)&rem_addr, &opt);
printf("1 in\n");
getsockopt(sock1, SOL_L2CAP, L2CAP_LM, &opt, &len);
opt |= L2CAP_LM_MASTER;
setsockopt(sock1, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt));
sock2 = accept(s_local_bt, (struct sockaddr *)&rem_addr, &opt);
printf("2 in\n");
getsockopt(sock2, SOL_L2CAP, L2CAP_LM, &opt, &len);
opt |= L2CAP_LM_MASTER;
setsockopt(sock2, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt));
printf("socket no's = %d, %d\n", sock1, sock2);
while(1) {
write(sock1, "Hello", sizeof("Hello"));
write(sock2, "Hello", sizeof("Hello"));
printf("len = %d\n", len);
usleep(10000);
}
}
else if(mode == CLIENT_MODE)
{
s_local_bt = bind_sock_local(0, TYPE_BT);
sa_bt = addr_by_name("00:40:05:C1:7A:20", 0, TYPE_BT);
printf("s_local_bt = %d, addr=%s\n",
s_local_bt, batostr(&(sa_bt->l2_bdaddr)));
i = connect(s_local_bt, (struct sockaddr *)sa_bt, sizeof(*sa_bt));
printf("connected sock = %d\n", i);
if (i < 0)
perror("bt connect");
while (i>=0) {
len = read(s_local_bt, buf, 256);
if (len > 0)
printf("Received \"%s\"\n", buf);
}
close(s_local_bt);
}
}
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [Bluez-devel] l2cap connection problems
@ 2004-07-15 16:16 becicka
0 siblings, 0 replies; 4+ messages in thread
From: becicka @ 2004-07-15 16:16 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: bluez-devel
I found an old post with source code using psm 0x1001. I
tried using this psm and all my connection problems have
disappeared. I apologize for cluttering the newsgroup.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2004-07-15 16:16 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-07-13 21:50 [Bluez-devel] l2cap connection problems becicka
2004-07-15 10:58 ` Marcel Holtmann
-- strict thread matches above, loose matches on Subject: below --
2004-07-15 15:50 becicka
2004-07-15 16:16 becicka
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox