From: <becicka@uiuc.edu>
To: Marcel Holtmann <marcel@holtmann.org>
Cc: bluez-devel@lists.sourceforge.net
Subject: Re: [Bluez-devel] l2cap connection problems
Date: Thu, 15 Jul 2004 10:50:04 -0500 [thread overview]
Message-ID: <a21dc35a.605958d3.8520600@expms2.cites.uiuc.edu> (raw)
[-- 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);
}
}
next reply other threads:[~2004-07-15 15:50 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-07-15 15:50 becicka [this message]
-- strict thread matches above, loose matches on Subject: below --
2004-07-15 16:16 [Bluez-devel] l2cap connection problems becicka
2004-07-13 21:50 becicka
2004-07-15 10:58 ` Marcel Holtmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=a21dc35a.605958d3.8520600@expms2.cites.uiuc.edu \
--to=becicka@uiuc.edu \
--cc=bluez-devel@lists.sourceforge.net \
--cc=marcel@holtmann.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox