|
From: Mattias ?g. <mat...@us...> - 2001-02-26 16:27:25
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
rfcomm.c 1.86 1.87=20=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
* moved function valid_dlci to rfcomm.h
The diff of the modified file(s):
--- rfcomm.c 2001/02/15 16:27:33 1.86
+++ rfcomm.c 2001/02/26 16:28:30 1.87
@@ -372,7 +372,6 @@
static u32 crc_check(u8 *data, u32 length, u8 check_sum);
static u8 crc_calc(u8 *data, u32 length);
static void create_crctable(u8 table[]);
-static s32 valid_dlci(u8 dlci);
static rfcomm_con* get_new_rfcomm_con(void);
static rfcomm_con* get_rfcomm_con(u8 line);
static s32 get_connected_dlci(rfcomm_con *rfcomm);
@@ -983,6 +982,7 @@
=20
/* registers in bt driver */
bt_register_rfcomm(rfcomm, tmp_dlci);
+=20
/* wake up any blocking connect/waits */=20
bt_connect_cfm(CREATE_RFCOMM_ID(rfcomm->line, tmp_dlci), 0 /* status ok=
*/ );
=20
|
|
From: Mats F. <ma...@us...> - 2001-02-27 15:00:36
|
The following file was modified in linux/drivers/char/bluetooth: Name Old version New version Comment ---- ----------- ----------- ------- rfcomm.c 1.87 1.88=20=20=20=20=20=20=20=20=20=20=20=20 The accompanying log: Fixed multipoint problem when setting default values to rfcomm_con Added check for incorrect length fields in UIH packets |
|
From: Gordon M. <gm...@us...> - 2001-03-07 20:07:43
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
rfcomm.c 1.92 1.93=20=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
--Made big-endian changes to rfcomm.c.
The diff of the modified file(s):
--- rfcomm.c 2001/03/05 15:52:52 1.92
+++ rfcomm.c 2001/03/07 20:09:24 1.93
@@ -157,12 +157,43 @@
#define RTR 0x8
#define DV 0x80
=20
+/* endian-swapping macros for structs */
+#define swap_long_frame(x) ((x)->h.length.val =3D le16_to_cpu((x)->h.lengt=
h.val))
+#define swap_mcc_long_frame(x) (swap_long_frame(x))
+#define swap_pn_msg(x) ((x)->frame_size =3D le16_to_cpu((x)->frame_size))
+
+#ifdef BTD_USERSTACK
+
+# include <asm/byteorder.h>
+# ifdef __LITTLE_ENDIAN
+# define cpu_to_le16(x) (x)
+# define cpu_to_le32(x) (x)
+# define cpu_to_be16(x) htons((x))
+# define cpu_to_be32(x) htonl((x))
+# else
+# define cpu_to_be16(x) (x)
+# define cpu_to_be32(x) (x)
+ extern inline __u16 cpu_to_le16(__u16 x) { return (x<<8) | (x>>8);}
+ extern inline __u32 cpu_to_le32(__u32 x) { return((x>>24) |
+ ((x>>8)&0xff00) | ((x<<8)&0xff0000) | (x<<24));}
+# endif
+
+# define le16_to_cpu(x) cpu_to_le16(x)
+# define le32_to_cpu(x) cpu_to_le32(x)
+# define be16_to_cpu(x) cpu_to_be16(x)
+# define be32_to_cpu(x) cpu_to_be32(x)
+
+#endif
+
/****************** TYPE DEFINITION SECTION ******************************=
***/
=20
/* Typedefinitions of stuctures used for creating and parsing packets, for=
a
further description of the structures please se the bluetooth core
specification part F:1 and the ETSI TS 07.10 specification */
=20
+#include <asm/byteorder.h>
+#ifdef __LITTLE_ENDIAN_BITFIELD
+
typedef struct address_field{
u8 ea:1;
u8 cr:1;
@@ -361,6 +392,150 @@
u8 fcs;
} __attribute__ ((packed)) nsc_msg;
=20
+#elif defined(__BIG_ENDIAN_BITFIELD)
+
+typedef struct address_field{
+ u8 server_chn:5;
+ u8 d:1;
+ u8 cr:1;
+ u8 ea:1;
+} __attribute__ ((packed)) address_field;
+
+typedef struct short_length{
+ u8 len:7;
+ u8 ea:1;
+} __attribute__ ((packed)) short_length;
+
+typedef union long_length {
+ struct bits {
+ unsigned short len:15;
+ u8 ea:1;
+ } bits;
+ u16 val;
+} __attribute__ ((packed)) long_length;
+
+typedef struct short_frame_head{=20
+ address_field addr;
+ u8 control;
+ short_length length;
+} __attribute__ ((packed)) short_frame_head;
+
+typedef struct short_frame{
+ short_frame_head h;
+ u8 data[0];
+} __attribute__ ((packed)) short_frame;
+
+typedef struct long_frame_head{=20
+ address_field addr;
+ u8 control;
+ long_length length;
+ u8 data[0];
+} __attribute__ ((packed)) long_frame_head;
+
+typedef struct long_frame{=20
+ long_frame_head h;
+ u8 data[0];
+} __attribute__ ((packed)) long_frame;
+
+typedef struct mcc_type{=20
+ u8 type:6;
+ u8 cr:1;
+ u8 ea:1;
+} __attribute__ ((packed)) mcc_type;
+
+typedef struct mcc_short_frame_head{=20
+ mcc_type type;
+ short_length length;
+ u8 value[0];
+} __attribute__ ((packed)) mcc_short_frame_head;
+
+typedef struct mcc_short_frame{=20
+ mcc_short_frame_head h;
+ u8 value[0];
+} __attribute__ ((packed)) mcc_short_frame;
+
+typedef struct mcc_long_frame_head{=20
+ mcc_type type;
+ long_length length;
+ u8 value[0];
+} __attribute__ ((packed)) mcc_long_frame_head;
+
+typedef struct mcc_long_frame{=20
+ mcc_long_frame_head h;
+ u8 value[0];
+} __attribute__ ((packed)) mcc_long_frame;
+
+typedef struct v24_signals{=20
+ u8 dv:1;
+ u8 ic:1;
+ u8 reserved:2;
+ u8 rtr:1;
+ u8 rtc:1;
+ u8 fc:1;
+ u8 ea:1;
+} __attribute__ ((packed)) v24_sigs;
+
+typedef struct brk_sigs{=20
+ u8 len:4;
+ u8 b3:1;
+ u8 b2:1;
+ u8 b1:1;
+ u8 ea:1;
+} __attribute__ ((packed)) brk_sigs;
+
+typedef struct msc_msg{=20
+ short_frame_head s_head;
+ mcc_short_frame_head mcc_s_head;
+ address_field dlci;
+ u8 v24_sigs;
+ //brk_sigs break_signals;
+ u8 fcs;
+} __attribute__ ((packed)) msc_msg;
+
+typedef struct rpn_msg{=20
+ short_frame_head s_head;
+ mcc_short_frame_head mcc_s_head;
+ address_field dlci;
+ rpn_values rpn_val;
+ u8 fcs;
+} __attribute__ ((packed)) rpn_msg;
+
+typedef struct rls_msg{=20
+ short_frame_head s_head;
+ mcc_short_frame_head mcc_s_head;
+ address_field dlci;
+ u8 res:4;
+ u8 error:4;
+ u8 fcs;
+} __attribute__ ((packed)) rls_msg;
+
+typedef struct pn_msg{=20
+ short_frame_head s_head;
+ mcc_short_frame_head mcc_s_head;
+ u8 res1:2;
+ u8 dlci:6;
+ u8 credit_flow:4;
+ u8 frame_type:4;
+ u8 res2:2;
+ u8 prior:6;
+ u8 ack_timer;
+ u32 frame_size:16;
+ u8 max_nbrof_retrans;
+ u8 credits;
+ u8 fcs;
+} __attribute__ ((packed)) pn_msg;
+
+typedef struct nsc_msg{=20
+ short_frame_head s_head;
+ mcc_short_frame_head mcc_s_head;
+ mcc_type command_type;
+ u8 fcs;
+} __attribute__ ((packed)) nsc_msg;
+
+#else /* __XXX_ENDIAN */
+#error Processor endianness unknown!
+#endif /* __XXX_ENDIAN */
+
/****************** LOCAL FUNCTION DECLARATION SECTION *******************=
***/
=20
static void process_mcc(u8* data, u32 len, rfcomm_con *rfcomm, s32 long_pk=
t);
@@ -1061,6 +1236,7 @@
packet */=20
D_REC(FNC"Long UIH packet received\n");
long_pkt =3D (long_frame*) data;
+ swap_long_frame(long_pkt);
uih_len =3D long_pkt->h.length.bits.len;
uih_data_start =3D long_pkt->h.data;
D_REC(FNC"long packet length %d\n",
@@ -1256,6 +1432,7 @@
if ((mcc_short_pkt->h.length.ea) =3D=3D 0) {
mcc_long_frame *mcc_long_pkt;
mcc_long_pkt =3D (mcc_long_frame*) mcc_short_pkt;
+ swap_mcc_long_frame(mcc_long_pkt);
rfcomm_test_msg(rfcomm, mcc_long_pkt->value,
mcc_long_pkt->h.length.bits.len,
MCC_RSP);
@@ -1363,6 +1540,7 @@
case PN: /*DLC parameter negotiation*/
{
pn_msg *pn_pkt =3D (pn_msg*) data;
+ swap_pn_msg(pn_pkt);
D_CTRL(FNC"Received DLC parameter negotiation, PN\n");
if (longpkt) {
/* UNPLUGGED Ericsson using 2 bytes length field */
@@ -1648,6 +1826,7 @@
set_uih_hdr((void*) l_pkt, dlci, len, rfcomm->initiator);
memcpy(l_pkt->data, data, len);
l_pkt->data[len] =3D crc_calc((u8*) l_pkt, SHORT_CRC_CHECK);
+ swap_long_frame(l_pkt);
} else {
short_frame *s_pkt;
=20
@@ -1746,6 +1925,8 @@
mcc_pkt->h.type.type =3D TEST;
mcc_pkt->h.length.bits.ea =3D EA;
mcc_pkt->h.length.bits.len =3D len;
+ swap_long_frame(uih_pkt);
+ swap_mcc_long_frame(mcc_pkt);
memcpy(mcc_pkt->value,test_pattern,len);
} else if (len > (SHORT_PAYLOAD_SIZE-sizeof(mcc_short_frame))) {
long_frame *uih_pkt;
@@ -1777,6 +1958,7 @@
mcc_pkt->h.type.type =3D TEST;
mcc_pkt->h.length.ea =3D EA;
mcc_pkt->h. length.len =3D len;
+ swap_long_frame(uih_pkt);
memcpy(mcc_pkt->value,test_pattern,len);
} else {
short_frame *uih_pkt;
@@ -2033,6 +2215,8 @@
pn_pkt->credits =3D credits;
pn_pkt->max_nbrof_retrans =3D 0;
=20=20=20
+ swap_pn_msg(pn_pkt);
+
return l2cap_send_data(tx_buf,rfcomm->l2cap);
}
=20
|
|
From: Peter K. <pk...@us...> - 2001-03-08 15:21:00
|
The following file was modified in linux/drivers/char/bluetooth: Name Old version New version Comment ---- ----------- ----------- ------- rfcomm.c 1.93 1.94=20=20=20=20=20=20=20=20=20=20=20=20 The accompanying log: Needed to include sysdep-2.1.h to get le16_to_cpu() defined on 2.0.x The diff of the modified file(s): --- rfcomm.c 2001/03/07 20:09:24 1.93 +++ rfcomm.c 2001/03/08 15:22:45 1.94 @@ -45,6 +45,7 @@ #define __NO_VERSION__ /* don't define kernel_version in module.h */ =20 #ifdef __KERNEL__=20 +#include <linux/bluetooth/sysdep-2.1.h> #include <linux/malloc.h> #include <linux/types.h> #include <linux/string.h> |
|
From: Mattias A. <mat...@us...> - 2001-03-30 12:04:11
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
rfcomm.c 1.95 1.96=20=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
* fixed blocking connect / disconnect
* lots of minor changes & cleanup
The diff of the modified file(s):
--- rfcomm.c 2001/03/12 15:54:35 1.95
+++ rfcomm.c 2001/03/30 12:03:25 1.96
@@ -132,7 +132,6 @@
#define NBROFCREDITS 6
=20
#define DEF_RFCOMM_MTU 127
-//#define DEF_RFCOMM_MTU 330
=20
/* The values in the control field when sending ordinary rfcomm packets */
#define SABM 0x2f
@@ -545,11 +544,16 @@
/* One RFCOMM connection for each bt_tty 0 to 6 */
=20
#ifdef __KERNEL__
+
+static struct timer_list rfcomm_timer;
+#define RFCOMM_CON_TIMEOUT (5*HZ)
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
static struct wait_queue *rfcomm_disconnect_wq =3D NULL;
#else
static wait_queue_head_t rfcomm_disconnect_wq;
#endif /* LINUX_VERSION_CODE */
+
#endif /* __KERNEL__ */
=20
void send_send_data(unsigned long ptr);
@@ -715,8 +719,6 @@
=20=09
if (!(rfcomm->l2cap)) {
=20
- printk("we don't have l2cap ch yet for this rfcomm ch\n");
-
rfcomm->dlci[0].state =3D CONNECTING;=20=20=20=20
=20
/* we don't have a l2cap connection yet */
@@ -779,12 +781,19 @@
=20=09=09
send_disc(rfcomm, tmp);
=20
- /* fixme -- do this block from bluetooth.c x*/
-
#ifdef __KERNEL__
+ start_wq_timer(&rfcomm_timer, RFCOMM_CON_TIMEOUT,
+ &rfcomm_disconnect_wq);
+
+ /* FIXME -- check that we haven't already received=20
+ disconnect 'acknowledge' */
interruptible_sleep_on(&rfcomm_disconnect_wq);
+
+ /* Now rfcomm is disconnected, disconnect l2cap */
+
l2ca_disconnect_req(rfcomm->l2cap);
- bt_unregister_rfcomm(line);
+
+ /* Now l2cap ch for RFCOMM is disconnected */
#endif
}
else
@@ -822,8 +831,6 @@
void rfcomm_connect_pnd(l2cap_con *l2cap, s32 status)
{
printk("rfcomm_connect_pnd : reason %d\n", status);=09
- //PRINTPSM(l2cap);
-
}
=20
void=20
@@ -892,12 +899,14 @@
Check whether the received params are acceptable,=20
accept all for now
*/
+
D_CTRL("rfcomm_config_ind : remote cid %d\n", l2cap->remote_cid);
/* check if we have sent a pos response yet */
if (!l2ca_remote_conf_done(l2cap)){
/* still haven't sent a pos configure response*/
=20=09=09
- if (l2ca_config_rsp(l2cap, l2cap->remote_mtu,NULL,1)) {
+ if (l2ca_config_rsp(l2cap, l2cap->remote_mtu,=20
+ NULL, CONF_SUCCESS)) {
D_ERR(FNC"l2ca_config_rsp failed\n");
}
} else=20
@@ -970,7 +979,7 @@
}
=20
/* The lower protocol layer, L2CAP, indicates that the lower layer=20
- connection is disconnected. */
+ connection is about to disconnect */
=20
void=20
rfcomm_disconnect_ind(l2cap_con *l2cap)
@@ -982,23 +991,21 @@
=20
rfcomm =3D ((rfcomm_con*) l2cap->upper_con);
=20
+
+ /* FIXME -- disconnect all rfcomm cons on this l2cap con=20
+ if any */
+
if (l2ca_disconnect_rsp(l2cap)) {
D_ERR(FNC"l2ca_disconnect_rsp failed\n");
return;
}
=20
#ifdef __KERNEL__
-
- bt_unregister_rfcomm(rfcomm->line);
-
/* notify upper tty that this rfcomm connection is down */
bt_hangupline(rfcomm->line);
#else
bt_disconnect_ind(CREATE_RFCOMM_ID(rfcomm->line, 0));
#endif
-=09
- rfcomm_reset_con(rfcomm->line);
-=09
#undef FNC
}
=20
@@ -1013,7 +1020,16 @@
=20
rfcomm =3D (rfcomm_con*) l2cap->upper_con;
=20
+ /* fixme -- should we indicate to bt interface when rfcomm is=20
+ down or when l2cap for rfcomm is down ? */
bt_disconnect_ind(CREATE_RFCOMM_ID(rfcomm->line, 0));
+#ifdef __KERNEL__
+ bt_unregister_rfcomm(rfcomm->line);
+
+ /* wake up bt line */
+ bt_disconnect_cfm(CREATE_RFCOMM_ID(rfcomm->line, 0),=20
+ l2cap->c_result);
+#endif
=20=09
rfcomm_reset_con(rfcomm->line);
=20=09
@@ -1155,14 +1171,17 @@
} else if (rfcomm->dlci[tmp_dlci].state =3D=3D DISCONNECTING) {
if (tmp_dlci =3D=3D 0) {
#ifdef __KERNEL__=20=20
+ release_wq_timer(&rfcomm_timer);
+ /* this will take down l2cap aswell */
wake_up_interruptible(&rfcomm_disconnect_wq);
+
#else
+ /* usermode stack */
l2ca_disconnect_req(rfcomm->l2cap);
#endif
=20=20=20=20=20=20=20=20=20
} else {
s32 tmp;
-=09=09=09=09
rfcomm->dlci[tmp_dlci].state =3D DISCONNECTED;
tmp =3D get_connected_dlci(rfcomm);
rfcomm->dlci[tmp].state =3D DISCONNECTING;
@@ -1175,6 +1194,7 @@
}=20=20=20=20
break;
=20=20=20=20=20
+ /* Disconnect mode, 'NAK on SABM/DISC' */
case DM:
D_CTRL(FNC"DM packet received\n");
rfcomm =3D ((rfcomm_con*) l2cap->upper_con);
@@ -1195,12 +1215,14 @@
rfcomm->dlci[0].state =3D DISCONNECTED;
/* FIXME:
Tell the tty that the link is down */
+ printk("RFCOMM control ch disconnected\n");
send_ua(rfcomm, tmp_dlci);
- bt_disconnect_ind(CREATE_RFCOMM_ID(rfcomm->line, 0));
} else {
rfcomm->dlci[tmp_dlci].state =3D DISCONNECTED;
send_ua(rfcomm, tmp_dlci);
- bt_disconnect_ind(CREATE_RFCOMM_ID(rfcomm->line, tmp_dlci));
+ D_CTRL("dlci %d was disconnected\n", tmp_dlci);
+ bt_disconnect_ind(CREATE_RFCOMM_ID(rfcomm->line,=20
+ tmp_dlci));
}
D_CTRL(FNC"DISC, sending back UA\n");
=20=20=20=20=20
@@ -1236,7 +1258,8 @@
}
=20
if (GET_PF(short_pkt->h.control)) {
- printk(FNC" %d more credits on dlci:%d...\n", *uih_data_start, tmp_dlci=
);
+ printk(FNC" %d more credits on dlci:%d...\n",=20
+ *uih_data_start, tmp_dlci);
if (crc_check(data, SHORT_CRC_CHECK,=20
uih_data_start[1])) {
break;
@@ -1390,7 +1413,6 @@
}
=20
/* Parses a multiplexer control channel packet */
-
void=20
process_mcc(u8* data, u32 len, rfcomm_con *rfcomm, s32 longpkt)
{
|
|
From: Peter K. <pk...@us...> - 2001-04-10 10:50:41
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
rfcomm.c 1.96 1.97=20=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
Added the packed attribute to the bits structure in the
long_length union (thanks to Claus Tondering).
The diff of the modified file(s):
--- rfcomm.c 2001/03/30 12:03:25 1.96
+++ rfcomm.c 2001/04/10 10:50:39 1.97
@@ -185,11 +185,10 @@
} __attribute__ ((packed)) short_length;
=20
typedef union long_length{
-// David LIBAULT : THIS WAS NOT WORKING AT UPF4.5...
struct bits {
u8 ea:1;
unsigned short len:15;
- } bits ;
+ } __attribute__ ((packed)) bits ;
u16 val ;
} __attribute__ ((packed)) long_length;
=20
@@ -388,7 +387,7 @@
struct bits {
unsigned short len:15;
u8 ea:1;
- } bits;
+ } __attribute__ ((packed)) bits;
u16 val;
} __attribute__ ((packed)) long_length;
=20
|
|
From: Mattias A. <mat...@us...> - 2001-04-12 12:25:31
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
rfcomm.c 1.98 1.99=20=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
* fixed credit based flow control when received piggybacked credits in=20
uih frame (thanks to David Libault)
* reset rfcomm session and unregister rfcomm even if disconnect fails=20
* fixed setting of control ch state before waking up disc wait queue
* fixed termination of rfcomm when baseband timed out
* fixed race in rfcomm_disconnect_ind, sometimes bt_hangupline flushed=20
outbuffer (containing l2ca_disconnect_rsp) before the scheduled data=20=
=20
was sent.=20
* added more debug
* cleanup & minor changes
The diff of the modified file(s):
--- rfcomm.c 2001/04/10 12:27:10 1.98
+++ rfcomm.c 2001/04/12 12:25:29 1.99
@@ -92,9 +92,9 @@
#endif
=20
#if PRINT_DATA_ENABLE
-#define PRINTPKT(str, data, len) print_data(str, data, len)
+#define RF_DATA(str, data, len) print_data(str, data, len)
#else
-#define PRINTPKT(str, data, len)
+#define RF_DATA(str, data, len)
#endif
=20
=20
@@ -554,6 +554,8 @@
static wait_queue_head_t rfcomm_disconnect_wq;
#endif /* LINUX_VERSION_CODE */
=20
+#else
+static int rfcomm_disconnect_wq;
#endif /* __KERNEL__ */
=20
void send_send_data(unsigned long ptr);
@@ -785,16 +787,33 @@
start_wq_timer(&rfcomm_timer, RFCOMM_CON_TIMEOUT,
&rfcomm_disconnect_wq);
=20
+#endif
/* FIXME -- check that we haven't already received=20
disconnect 'acknowledge' */
+
interruptible_sleep_on(&rfcomm_disconnect_wq);
=20
+ /* Check that rfcomm session really disconnected */
+ /* FIXME -- add timer obj with status in rfcomm obj */
+
+ /* check control channel */
+ if (rfcomm->dlci[0].state !=3D DISCONNECTED)
+ {
+ printk("Rfcomm disconnect failed, reset session\n");
+#ifdef __KERNEL__
+ bt_unregister_rfcomm(rfcomm->line);
+ bt_disconnect_cfm(CREATE_RFCOMM_ID(rfcomm->line, 0),=20
+ rfcomm->l2cap->c_result);
+#endif
+ rfcomm_reset_con(rfcomm->line);
+ }
+
/* Now rfcomm is disconnected, disconnect l2cap */
=20
l2ca_disconnect_req(rfcomm->l2cap);
=20
/* Now l2cap ch for RFCOMM is disconnected */
-#endif
+
}
else
D_WARN("rfcomm_disconnect_req : line not connected !\n");
@@ -967,7 +986,8 @@
{
=20=09=09=09
s32 j;
- DSYS(FNC"Setting RFCOMM frame size to %d\n", l2cap->remote_mtu-5);
+ DSYS(FNC"Setting RFCOMM frame size to %d\n",=20
+ l2cap->remote_mtu-5);
=20=09=09=09
for (j =3D 0; j < 62; j++) {
rfcomm->dlci[j].mtu =3D (l2cap->remote_mtu-5);
@@ -980,35 +1000,36 @@
=20
/* The lower protocol layer, L2CAP, indicates that the lower layer=20
connection is about to disconnect */
-
void=20
rfcomm_disconnect_ind(l2cap_con *l2cap)
{
-#define FNC "rfcomm_disconnect_ind: "
rfcomm_con *rfcomm;
=20
- D_CTRL(FNC"remote cid %d\n", l2cap->remote_cid);
+ D_CTRL(__FUNCTION__" remote cid %d\n", l2cap->remote_cid);
=20
rfcomm =3D ((rfcomm_con*) l2cap->upper_con);
=20
+ /* This l2cap connection is going down, remove all rfcomm cons=20
+ and notify upper tty */
=20
- /* FIXME -- disconnect all rfcomm cons on this l2cap con=20
- if any */
+ if (!l2cap->link_up)
+ {
+ DSYS("Baseband is down, reset this RFCOMM session\n");
+#ifdef __KERNEL__
+ bt_unregister_rfcomm(rfcomm->line);
+#endif
+ bt_disconnect_ind(CREATE_RFCOMM_ID(rfcomm->line, 0));
+ rfcomm_reset_con(rfcomm->line);
+ }
=20
+ /* always try to send back rsp (if link is down con is deleted) */
if (l2ca_disconnect_rsp(l2cap)) {
- D_ERR(FNC"l2ca_disconnect_rsp failed\n");
+ D_ERR(__FUNCTION__" l2ca_disconnect_rsp failed\n");
return;
}
-
-#ifdef __KERNEL__
- /* notify upper tty that this rfcomm connection is down */
- bt_hangupline(rfcomm->line);
-#else
- bt_disconnect_ind(CREATE_RFCOMM_ID(rfcomm->line, 0));
-#endif
-#undef FNC
}
=20
+
void=20
rfcomm_disconnect_cfm(l2cap_con *l2cap)
{
@@ -1023,6 +1044,8 @@
/* fixme -- should we indicate to bt interface when rfcomm is=20
down or when l2cap for rfcomm is down ? */
bt_disconnect_ind(CREATE_RFCOMM_ID(rfcomm->line, 0));
+
+ /* fixme -- add these glue layer functions in userstack */
#ifdef __KERNEL__
bt_unregister_rfcomm(rfcomm->line);
=20
@@ -1030,7 +1053,6 @@
bt_disconnect_cfm(CREATE_RFCOMM_ID(rfcomm->line, 0),=20
l2cap->c_result);
#endif
-=09
rfcomm_reset_con(rfcomm->line);
=20=09
#undef FNC
@@ -1051,7 +1073,7 @@
u32 uih_len;
u8 tmp_dlci;
=20
- PRINTPKT("rfcomm_receive_data:",data,len);
+ RF_DATA("rfcomm_receive_data:",data,len);
=20=09
D_REC(FNC"%d bytes, our cid is %d\n",len,=20
l2cap->remote_cid);
@@ -1172,14 +1194,13 @@
if (tmp_dlci =3D=3D 0) {
#ifdef __KERNEL__=09=09=09
release_wq_timer(&rfcomm_timer);
+#endif
+ printk("RFCOMM disconnected ctrl ch (local)\n");
+ rfcomm->dlci[0].state =3D DISCONNECTED;
+=09=09=09=09
/* this will take down l2cap aswell */
wake_up_interruptible(&rfcomm_disconnect_wq);
=20
-#else
- /* usermode stack */
- l2ca_disconnect_req(rfcomm->l2cap);
-#endif
-=20=20=20=20=20=20=20=20
} else {
s32 tmp;
rfcomm->dlci[tmp_dlci].state =3D DISCONNECTED;
@@ -1215,7 +1236,7 @@
rfcomm->dlci[0].state =3D DISCONNECTED;
/* FIXME:
Tell the tty that the link is down */
- printk("RFCOMM control ch disconnected\n");
+ printk("RFCOMM control ch disconnected (remotely)\n");
send_ua(rfcomm, tmp_dlci);
} else {
rfcomm->dlci[tmp_dlci].state =3D DISCONNECTED;
@@ -1258,14 +1279,15 @@
}
=20
if (GET_PF(short_pkt->h.control)) {
- printk(FNC" %d more credits on dlci:%d...\n",=20
+ D_REC(FNC" %d more credits on dlci:%d...\n",=20
*uih_data_start, tmp_dlci);
- if (crc_check(data, SHORT_CRC_CHECK,=20
- uih_data_start[1])) {
- break;
- }
- rfcomm->dlci[tmp_dlci].local_credits +=3D uih_data_start[0];
- break;
+
+ rfcomm->dlci[tmp_dlci].local_credits +=3D=20
+ uih_data_start[0];
+ uih_data_start++;
+
+ /* feed uih data to tty if any */
+
}
=20
if (crc_check(data, SHORT_CRC_CHECK,
@@ -1283,8 +1305,14 @@
if (rfcomm->credit_flow) {
rfcomm->dlci[tmp_dlci].remote_credits -=3D 1;
if (rfcomm->dlci[tmp_dlci].remote_credits <=3D 1) {
- rfcomm_send_credits(rfcomm, tmp_dlci, NBROFCREDITS -1);
- rfcomm->dlci[tmp_dlci].remote_credits +=3D NBROFCREDITS - 1;=20
+ /* FIXME -- possible race ? */
+=09=09=09=09=09
+ /* FIXME -- send credits piggybacked */
+
+ rfcomm_send_credits(rfcomm, tmp_dlci,=20
+ NBROFCREDITS -1);
+ rfcomm->dlci[tmp_dlci].remote_credits+=3D
+ NBROFCREDITS - 1;=20
}
}=09=09=09
bt_receive_top(con_id, uih_data_start, uih_len);
@@ -1318,10 +1346,11 @@
=20=09
if (dlci =3D=3D 0) {
D_ERR(FNC" Not allowed to send data on DLCI 0\n");
+ return -1;
}
=20=09
rfcomm =3D &rfcomm_con_list[line];
- PRINTPKT(FNC, data, count);
+ RF_DATA(FNC, data, count);
=20
if (rfcomm =3D=3D NULL) {
D_ERR(FNC" ERROR rfcomm_con =3D=3D NULL\n");
@@ -1331,11 +1360,11 @@
return -1;
} else if(rfcomm->dlci[0].state =3D=3D FLOW_STOPPED) {
DSYS(FNC"Flow stopped on all channels, returning zero\n");
- /* FIXME: We need to buffer the incomming data here... */
+ /* FIXME: We need to buffer the incoming data here... */
return 0;
} else if (rfcomm->dlci[dlci].state =3D=3D FLOW_STOPPED) {
DSYS(FNC"Flow stopped, returning zero\n");
- /* FIXME: We need to buffer the incomming data here... */
+ /* FIXME: We need to buffer the incoming data here... */
return 0;
}
/* Check whether there are any data channels connected */
@@ -1419,6 +1448,8 @@
#define FNC "process_mcc: "
mcc_short_frame *mcc_short_pkt;
=20=20=20=20=20
+ D_CTRL("process_mcc\n");
+
if (longpkt) {
mcc_short_pkt =3D (mcc_short_frame*)(((long_frame*)data)->data);
} else {
@@ -1480,7 +1511,7 @@
rfcomm->dlci[dlci].state =3D FLOW_STOPPED;
} else {
rfcomm->dlci[dlci].state =3D CONNECTED;
- D_CTRL(FNC"Flow on on dlci %d\n", dlci);
+ D_CTRL(FNC"Flow ON, dlci %d\n", dlci);
}
=20
rfcomm_msc_msg(rfcomm, v24_sigs, MCC_RSP, dlci);
@@ -1520,10 +1551,9 @@
memset(&rpn_val.pm, 0, 2);
}
}
-=20=20=20=20
-=09=09
break;
}
+
case RLS: /*Remote line status*/
{
u8 tmp_dlci;
@@ -1866,6 +1896,8 @@
short_frame *uih_pkt;
u32 rfcomm_frame_size;
=20=20=20
+ D_CTRL(__FUNCTION__" give %d credits to dlci %d\n", credits, dlci);
+
rfcomm_frame_size =3D (sizeof(short_frame) + 1 + FCS_SIZE);
tx_buf =3D subscribe_bt_buf(sizeof(rfcomm_tx_buf) + rfcomm_frame_size);
=20
@@ -2298,7 +2330,6 @@
return l2cap_send_data(tx_buf, rfcomm->l2cap);
}
=20
-
void
set_uih_hdr(short_frame *uih_pkt, u8 dlci, u32 len, u8 cr)
{
@@ -2327,7 +2358,7 @@
&& (rfcomm_con_list[i].dlci[0].state !=3D DISCONNECTED)) {
i++;
}
- D_CTRL("get_new_rfcomm_con: rfcomm_con -> tty%d\n",i);
+ D_CTRL("get_new_rfcomm_con: rfcomm_con -> ttyBT%d\n",i);
if (rfcomm_con_list[i].dlci[0].state !=3D DISCONNECTED) {
return NULL;
} else {
@@ -2378,7 +2409,7 @@
{
u8 fcs =3D 0xff;
=20
- PRINTPKT("crc_check:",data,length);
+ RF_DATA("crc_check:",data,length);
while (length--) {
fcs =3D crctable[fcs^*data++];
}
|
|
From: Peter K. <pk...@us...> - 2001-04-12 16:25:59
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
rfcomm.c 1.99 1.100=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
If rfcomm session was reset in rfcomm_disconnect_req(), we
called l2ca_disconnect_req() with a NULL pointer instead of
the l2cap_con object.
The diff of the modified file(s):
--- rfcomm.c 2001/04/12 12:25:29 1.99
+++ rfcomm.c 2001/04/12 16:25:58 1.100
@@ -779,6 +779,8 @@
tmp =3D get_connected_dlci(rfcomm);
=20
if (tmp > 0) {
+ l2cap_con *l2cap =3D rfcomm->l2cap;
+
rfcomm->dlci[tmp].state =3D DISCONNECTING;
=20=09=09
send_disc(rfcomm, tmp);
@@ -786,8 +788,8 @@
#ifdef __KERNEL__
start_wq_timer(&rfcomm_timer, RFCOMM_CON_TIMEOUT,
&rfcomm_disconnect_wq);
-
#endif
+
/* FIXME -- check that we haven't already received=20
disconnect 'acknowledge' */
=20
@@ -810,10 +812,9 @@
=20
/* Now rfcomm is disconnected, disconnect l2cap */
=20
- l2ca_disconnect_req(rfcomm->l2cap);
+ l2ca_disconnect_req(l2cap);
=20
/* Now l2cap ch for RFCOMM is disconnected */
-
}
else
D_WARN("rfcomm_disconnect_req : line not connected !\n");
|
|
From: Peter K. <pk...@us...> - 2001-04-17 16:57:48
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
rfcomm.c 1.101 1.102=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
Unregister rfcomm when disconnecting control channel remotely.
The diff of the modified file(s):
--- rfcomm.c 2001/04/17 10:00:26 1.101
+++ rfcomm.c 2001/04/17 16:57:47 1.102
@@ -1245,7 +1245,8 @@
/* FIXME:
Tell the tty that the link is down */
printk("RFCOMM control ch disconnected (remotely)\n");
- send_ua(rfcomm, tmp_dlci);
+ send_ua(rfcomm, 0);
+ bt_unregister_rfcomm(rfcomm->line);
} else {
rfcomm->dlci[tmp_dlci].state =3D DISCONNECTED;
send_ua(rfcomm, tmp_dlci);
|
|
From: Peter K. <pk...@us...> - 2001-04-18 11:49:42
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
rfcomm.c 1.102 1.103=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
Made it compile for user stack.
The diff of the modified file(s):
--- rfcomm.c 2001/04/17 16:57:47 1.102
+++ rfcomm.c 2001/04/18 11:49:42 1.103
@@ -1246,7 +1246,9 @@
Tell the tty that the link is down */
printk("RFCOMM control ch disconnected (remotely)\n");
send_ua(rfcomm, 0);
+#ifdef __KERNEL__
bt_unregister_rfcomm(rfcomm->line);
+#endif
} else {
rfcomm->dlci[tmp_dlci].state =3D DISCONNECTED;
send_ua(rfcomm, tmp_dlci);
|
|
From: Peter K. <pk...@us...> - 2001-04-18 15:24:23
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
rfcomm.c 1.103 1.104=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
Return negative value in crc_check() to indicate failure.
The diff of the modified file(s):
--- rfcomm.c 2001/04/18 11:49:42 1.103
+++ rfcomm.c 2001/04/18 15:24:23 1.104
@@ -1095,7 +1095,7 @@
D_CTRL(FNC"SABM-packet received\n");
=20=20=20=20=20
if (crc_check((u8*) short_pkt, LONG_CRC_CHECK,=20
- short_pkt->data[0])) {
+ short_pkt->data[0]) < 0) {
break;
}
=20
@@ -1232,7 +1232,7 @@
=20=20=20=20=20
case DISC:
D_CTRL(FNC"DISC packet received\n");
- if (crc_check(data, LONG_CRC_CHECK, short_pkt->data[0])) {
+ if (crc_check(data, LONG_CRC_CHECK, short_pkt->data[0]) < 0) {
break;
}
rfcomm =3D ((rfcomm_con*) l2cap->upper_con);
@@ -1302,7 +1302,7 @@
}
=20
if (crc_check(data, SHORT_CRC_CHECK,
- *(uih_data_start + uih_len))) {
+ *(uih_data_start + uih_len)) < 0) {
break;
}
=20=20=20=20=20
@@ -2431,7 +2431,7 @@
return 0;
} else {
D_ERR("crc_check: CRC check failed\n");
- return 1;
+ return -1;
}
}
=20
|
|
From: Mattias A. <mat...@us...> - 2001-04-25 17:01:23
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
rfcomm.c 1.105 1.106=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
* added return codes in rfcomm_connect_req / rfcomm_disconnect_req
The diff of the modified file(s):
--- rfcomm.c 2001/04/18 15:47:13 1.105
+++ rfcomm.c 2001/04/25 17:01:22 1.106
@@ -703,7 +703,7 @@
=20
/* This function creates an rfcomm connection over the control channel DCL=
I 0 */
=20=20=20
-u32=20
+s32=20
rfcomm_connect_req(u8* bd_addr, u8 server_chn, u8 line)
{
#define FNC "rfcomm_connect_req: "
@@ -733,7 +733,7 @@
/* we don't have a l2cap connection yet */
if (l2ca_connect_req(bd_addr, RFCOMM_LAYER)) {
D_ERR(FNC"l2ca_connect_req failed\n");
- return 0;
+ return -1;
}
} else if (!((rfcomm->l2cap)->current_state =3D=3D OPEN)) {
=20
@@ -771,7 +771,7 @@
#undef FNC
}
=20
-void=20
+s32
rfcomm_disconnect_req(u8 line)
{
rfcomm_con *rfcomm;
@@ -801,7 +801,6 @@
disconnect 'acknowledge' */
=20
interruptible_sleep_on(&rfcomm_disconnect_wq);
-
/* Check that rfcomm session really disconnected */
/* FIXME -- add timer obj with status in rfcomm obj */
=20
@@ -809,8 +808,7 @@
if (rfcomm->dlci[0].state !=3D DISCONNECTED)
{
printk("Rfcomm disconnect failed, reset session\n");
-#ifdef __KERNEL__
- bt_unregister_rfcomm(rfcomm->line);
+#ifdef __KERNEL__ bt_unregister_rfcomm(rfcomm->line);
bt_disconnect_cfm(CREATE_RFCOMM_ID(rfcomm->line, 0),=20
rfcomm->l2cap->c_result);
#endif
@@ -818,13 +816,12 @@
}
=20
/* Now rfcomm is disconnected, disconnect l2cap */
-
- l2ca_disconnect_req(l2cap);
-
- /* Now l2cap ch for RFCOMM is disconnected */
+ return l2ca_disconnect_req(l2cap);
}
else
D_WARN("rfcomm_disconnect_req : line not connected !\n");
+
+ return 0;
}
=20=09
=20
|
|
From: Mattias A. <mat...@us...> - 2001-04-25 17:08:54
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
rfcomm.c 1.106 1.107=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
fixed typo...
The diff of the modified file(s):
--- rfcomm.c 2001/04/25 17:01:22 1.106
+++ rfcomm.c 2001/04/25 17:08:53 1.107
@@ -808,7 +808,8 @@
if (rfcomm->dlci[0].state !=3D DISCONNECTED)
{
printk("Rfcomm disconnect failed, reset session\n");
-#ifdef __KERNEL__ bt_unregister_rfcomm(rfcomm->line);
+#ifdef __KERNEL__=09=09=09
+ bt_unregister_rfcomm(rfcomm->line);
bt_disconnect_cfm(CREATE_RFCOMM_ID(rfcomm->line, 0),=20
rfcomm->l2cap->c_result);
#endif
|
|
From: Mattias A. <mat...@us...> - 2001-05-02 15:43:29
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
rfcomm.c 1.107 1.108=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
* replaced hardcoded values with define
* index test should go first in while loop (get_connected_dlci)
* fixed bug when all rfcomm cons where busy (get_new_rfcomm_con)
The diff of the modified file(s):
--- rfcomm.c 2001/04/25 17:08:53 1.107
+++ rfcomm.c 2001/05/02 15:43:29 1.108
@@ -540,8 +540,8 @@
static u8 crctable[256];
/* The crctable for the FEC field */
=20
-rfcomm_con rfcomm_con_list[7];
-/* One RFCOMM connection for each bt_tty 0 to 6 */
+rfcomm_con rfcomm_con_list[BT_NBR_DATAPORTS];
+/* One RFCOMM connection for each bt_tty 0 to BT_NBR_DATAPORTS */
=20
#ifdef __KERNEL__
static struct timer_list rfcomm_timer;
@@ -873,7 +873,7 @@
con objs) to see which rfcomm that was trying to connect */
=20
/* Find the connecting rfcomm_con */
- while ((i < 7) && (!stop)) {
+ while ((i < BT_NBR_DATAPORTS) && (!stop)) {
if ((rfcomm_con_list[i].dlci[0].state =3D=3D CONNECTING) &&=20
(rfcomm_con_list[i].initiator =3D=3D TRUE)) {
rfcomm =3D &rfcomm_con_list[i];
@@ -2363,19 +2363,18 @@
{
s32 i =3D 0;
=20
- while ((i<BT_NBR_DATAPORTS)
- && (rfcomm_con_list[i].dlci[0].state !=3D DISCONNECTED)) {
- i++;
- }
D_CTRL("get_new_rfcomm_con: rfcomm_con -> ttyBT%d\n",i);
- if (rfcomm_con_list[i].dlci[0].state !=3D DISCONNECTED) {
- return NULL;
- } else {
- /* Reset these parameters just incase... */
+
+ for (i =3D 0 ; i < BT_NBR_DATAPORTS ; i ++)
+ {
+ if (rfcomm_con_list[i].dlci[0].state =3D=3D DISCONNECTED)
+ {
rfcomm_con_list[i].l2cap =3D NULL;
return &rfcomm_con_list[i];
}
}
+ return NULL;
+}
=20
rfcomm_con*=20
get_rfcomm_con(u8 line)
@@ -2398,7 +2397,7 @@
s32 tmp;
=20
tmp =3D 61;
- while ((rfcomm->dlci[tmp].state =3D=3D DISCONNECTED) && (tmp > 0)) {
+ while ((tmp > 0) && (rfcomm->dlci[tmp].state =3D=3D DISCONNECTED)) {
tmp--;
}
=20
|
|
From: Mattias A. <mat...@us...> - 2001-05-02 15:50:50
|
The following file was modified in linux/drivers/char/bluetooth: Name Old version New version Comment ---- ----------- ----------- ------- rfcomm.c 1.108 1.109=20=20=20=20=20=20=20=20=20=20=20 The accompanying log: * minor change The diff of the modified file(s): --- rfcomm.c 2001/05/02 15:43:29 1.108 +++ rfcomm.c 2001/05/02 15:50:50 1.109 @@ -537,11 +537,11 @@ =20 /****************** LOCAL VARIABLE DECLARATION SECTION *******************= ***/ =20 -static u8 crctable[256]; /* The crctable for the FEC field */ +static u8 crctable[256]; =20 +/* One RFCOMM connection for each ttyBTx */ rfcomm_con rfcomm_con_list[BT_NBR_DATAPORTS]; -/* One RFCOMM connection for each bt_tty 0 to BT_NBR_DATAPORTS */ =20 #ifdef __KERNEL__ static struct timer_list rfcomm_timer; |
|
From: Peter K. <pk...@us...> - 2001-05-23 15:09:19
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
rfcomm.c 1.109 1.110=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
Return errorvalue in rfcomm_disconnect_req() if connection is found.
The diff of the modified file(s):
--- rfcomm.c 2001/05/02 15:50:50 1.109
+++ rfcomm.c 2001/05/23 15:09:18 1.110
@@ -776,11 +776,12 @@
{
rfcomm_con *rfcomm;
s32 tmp;
+
D_CTRL("rfcomm_disconnect_req %d\n", line);
if (!(rfcomm =3D &rfcomm_con_list[line]))
{
D_ERR("rfcomm_disconnect_req : no rfcomm con\n");
- return;
+ return -EINVAL;
}
=20
tmp =3D get_connected_dlci(rfcomm);
|
|
From: Peter K. <pk...@us...> - 2001-05-23 15:17:56
|
The following file was modified in linux/drivers/char/bluetooth: Name Old version New version Comment ---- ----------- ----------- ------- rfcomm.c 1.110 1.111=20=20=20=20=20=20=20=20=20=20=20 The accompanying log: Made it compile for user mode too. The diff of the modified file(s): --- rfcomm.c 2001/05/23 15:09:18 1.110 +++ rfcomm.c 2001/05/23 15:17:55 1.111 @@ -61,6 +61,7 @@ #else #include <stdlib.h> #include <string.h> +#include <errno.h> #include "include/rfcomm.h" #include "include/rfcomm_sec.h" #include "include/btmem.h" |
|
From: Mattias A. <mat...@us...> - 2001-05-29 13:14:11
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
rfcomm.c 1.111 1.112=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
* always reset rfcomm con when receiving a disconnect ind.
* added debug message & minor cleanup
The diff of the modified file(s):
--- rfcomm.c 2001/05/23 15:17:55 1.111
+++ rfcomm.c 2001/05/29 13:14:11 1.112
@@ -577,6 +577,8 @@
return;
}
=20
+ D_CTRL(__FUNCTION__" line %d\n", line);
+
rfcomm_con_list[line].magic =3D RFCOMM_MAGIC;
rfcomm_con_list[line].line =3D line;
rfcomm_con_list[line].credit_flow =3D 0;
@@ -1027,9 +1029,10 @@
bt_unregister_rfcomm(rfcomm->line);
#endif
bt_disconnect_ind(CREATE_RFCOMM_ID(rfcomm->line, 0));
- rfcomm_reset_con(rfcomm->line);
}
=20=09
+ rfcomm_reset_con(rfcomm->line);
+
/* always try to send back rsp (if link is down con is deleted) */
if (l2ca_disconnect_rsp(l2cap)) {
D_ERR(__FUNCTION__" l2ca_disconnect_rsp failed\n");
@@ -2309,6 +2312,8 @@
msc_msg *msc_pkt;
u32 rfcomm_frame_size;
=20=20=20
+ D_CTRL(__FUNCTION__" val:%d, cr:%d, dlci:%d\n", value, cr, dlci);
+
rfcomm_frame_size =3D sizeof(msc_msg);
tx_buf =3D subscribe_bt_buf(sizeof(rfcomm_tx_buf) + rfcomm_frame_size);
=20
|
|
From: Mats F. <ma...@us...> - 2001-06-14 10:45:25
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
rfcomm.c 1.112 1.113=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
Improved the flow control, especially the credit based
The diff of the modified file(s):
--- rfcomm.c 2001/05/29 13:14:11 1.112
+++ rfcomm.c 2001/06/14 10:45:24 1.113
@@ -98,6 +98,7 @@
#define RF_DATA(str, data, len)
#endif
=20
+#define FNC __FUNCTION__": "
=20
/****************** CONSTANT AND MACRO SECTION ***************************=
***/
=20
@@ -131,7 +132,8 @@
=20
#define RFCOMM_MAX_HDR_SIZE 5
=20
-#define NBROFCREDITS 6
+#define MAX_CREDITS 6
+#define MIN_CREDITS 3
=20
#define DEF_RFCOMM_MTU 127
=20
@@ -573,11 +575,11 @@
/* check if valid line number */
if (line >=3D BT_NBR_DATAPORTS)
{
- D_ERR("rfcomm_reset_con : invalid line!\n");
+ D_ERR(FNC"invalid line!\n");
return;
}
=20
- D_CTRL(__FUNCTION__" line %d\n", line);
+ D_CTRL(FNC"line %d\n", line);
=20
rfcomm_con_list[line].magic =3D RFCOMM_MAGIC;
rfcomm_con_list[line].line =3D line;
@@ -652,7 +654,7 @@
s32
rfcomm_set_mtu(rfcomm_con *rfcomm, u8 dlci, u32 new_mtu)
{
- DSYS("rfcomm_set_mtu %d\n", new_mtu);
+ DSYS(FNC"MTU set to:%d\n", new_mtu);
if (rfcomm->dlci[dlci].state =3D=3D DISCONNECTED) {
rfcomm->dlci[dlci].mtu =3D new_mtu;
return 0;
@@ -692,7 +694,7 @@
for (i =3D 0; i < BT_NBR_DATAPORTS; i++) {
rfcomm_con *rfcomm =3D get_rfcomm_con(i);
if (get_connected_dlci(rfcomm) !=3D -1) {
- DSYS("Now disconnecting rfcomm line %d\n", i);
+ DSYS(FNC"Now disconnecting rfcomm line %d\n", i);
rfcomm_disconnect_req(i);
}=09=09
}
@@ -709,7 +711,6 @@
s32=20
rfcomm_connect_req(u8* bd_addr, u8 server_chn, u8 line)
{
-#define FNC "rfcomm_connect_req: "
rfcomm_con *rfcomm;
u8 tmp_dlci;
=20=20=20
@@ -717,7 +718,7 @@
server_chn, line);
=20
if (!(rfcomm =3D get_rfcomm_con(line))) {
- D_ERR(FNC"ERROR: %d is an invalid line\n", line);
+ D_ERR(FNC"%d is an invalid line\n", line);
return 0;
}
=20
@@ -745,7 +746,7 @@
} else if (rfcomm->dlci[0].state !=3D CONNECTED) {
=20
/* we have an l2cap channel (server ch) */
- D_CTRL("we already have an l2cap channel)\n");
+ D_CTRL(FNC"we already have an l2cap channel)\n");
=20=09=09
if (rfcomm->dlci[0].state !=3D DISCONNECTED) {
D_ERR(FNC"DLCI:0 neither CONNECTED nor DISCONNECTED\n");
@@ -757,10 +758,10 @@
}
} else if (rfcomm->dlci[tmp_dlci].state !=3D DISCONNECTED) {
=20
- D_ERR(FNC"ERROR trying to connect a non DISCONNECTED server channel (%d)=
\n",server_chn);
+ D_ERR(FNC"trying to connect a non DISCONNECTED server channel (%d)\n",se=
rver_chn);
return 0;
} else {
- D_CTRL("We are negotiating rfcomm (pn msg)\n");
+ D_CTRL(FNC"We are negotiating rfcomm (pn msg)\n");
rfcomm->dlci[tmp_dlci].state =3D NEGOTIATING;
/* must fit i l2cap mtu */
D_CTRL(FNC"negotiate mtu : %d bytes\n",
@@ -771,7 +772,7 @@
=20
/* ? never used ? */
return line;
-#undef FNC
+
}
=20
s32
@@ -865,7 +866,6 @@
void=20
rfcomm_connect_cfm(l2cap_con *l2cap, s32 status)
{
-#define FNC "rfcomm_connect_cfm: "
s32 i =3D 0;
s32 stop =3D FALSE;
=20
@@ -909,7 +909,7 @@
} else {
D_ERR(FNC"couldn't find the correct rfcomm_con object\n");
}
-#undef FNC
+
}
=20
=20
@@ -921,7 +921,6 @@
void=20
rfcomm_config_ind(l2cap_con* l2cap)
{
-#define FNC "rfcomm_config_ind: "
=20
/*=20
FIXME
@@ -962,7 +961,7 @@
DSYS(FNC"already ready with config req\n");
=20
}=20
-#undef FNC
+
}
=20
/* The lower protocol layer, L2CAP, indicates that the configuration
@@ -971,7 +970,6 @@
void=20
rfcomm_config_cfm(l2cap_con *l2cap, s32 status)
{
-#define FNC "rfcomm_config_cfm: "
rfcomm_con *rfcomm;
rfcomm =3D (rfcomm_con *) l2cap->upper_con;
=20
@@ -1005,7 +1003,7 @@
}
}
=20=20=20=20=20=20=20=20=20
-#undef FNC
+
}
=20
/* The lower protocol layer, L2CAP, indicates that the lower layer=20
@@ -1015,7 +1013,7 @@
{
rfcomm_con *rfcomm;
=20
- D_CTRL(__FUNCTION__" remote cid %d\n", l2cap->remote_cid);
+ DSYS(FNC"remote cid %d\n", l2cap->remote_cid);
=20
rfcomm =3D ((rfcomm_con*) l2cap->upper_con);
=20
@@ -1024,7 +1022,7 @@
=20
if (!l2cap->link_up)
{
- DSYS("Baseband is down, reset this RFCOMM session\n");
+ DSYS(FNC"Baseband is down, reset this RFCOMM session\n");
#ifdef __KERNEL__
bt_unregister_rfcomm(rfcomm->line);
#endif
@@ -1035,7 +1033,7 @@
=20
/* always try to send back rsp (if link is down con is deleted) */
if (l2ca_disconnect_rsp(l2cap)) {
- D_ERR(__FUNCTION__" l2ca_disconnect_rsp failed\n");
+ D_ERR(FNC" l2ca_disconnect_rsp failed\n");
return;
}
}
@@ -1044,7 +1042,6 @@
void=20
rfcomm_disconnect_cfm(l2cap_con *l2cap)
{
-#define FNC "rfcomm_disconnect_cfm: "
=20
rfcomm_con *rfcomm;
=20=20=20
@@ -1066,7 +1063,7 @@
#endif=09
rfcomm_reset_con(rfcomm->line);
=20=09
-#undef FNC
+
}
=20
/* This function should be called from the L2CAP layer data should pos32 at
@@ -1076,7 +1073,6 @@
void=20
rfcomm_receive_data(l2cap_con *l2cap, u8 *data, u32 len)
{
-#define FNC "rfcomm_receive_data: "
rfcomm_con *rfcomm;
short_frame *short_pkt;=20
long_frame *long_pkt;
@@ -1084,7 +1080,7 @@
u32 uih_len;
u8 tmp_dlci;
=20
- RF_DATA("rfcomm_receive_data:",data,len);
+ RF_DATA(FNC"rfcomm_receive_data:",data,len);
=20=09
D_REC(FNC"%d bytes, our cid is %d\n",len,=20
l2cap->remote_cid);
@@ -1140,15 +1136,6 @@
/* wake up any blocking connect/waits */=20
bt_connect_cfm(CREATE_RFCOMM_ID(rfcomm->line, tmp_dlci), 0 /* status ok=
*/ );
=20
-#if 0
- /* fixme --=A0should we negotiate frame size as server ? */=09=09
- printk("rfcomm (S) trying to negotiate mtu (%d)...=
\n",
- l2cap->remote_mtu-5);
- send_pn_msg(rfcomm, 7, (l2cap->remote_mtu-5), 0, 0,
- tmp_dlci, TRUE);
- rfcon->dlci[tmp_dlci].state =3D NEGOTIATING;
-#endif
-
D_CTRL(FNC"sending back UA - other channel\n");
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20
send_ua(rfcomm, tmp_dlci);
@@ -1206,7 +1193,7 @@
#ifdef __KERNEL__=09=09=09
release_wq_timer(&rfcomm_timer);
#endif
- printk("RFCOMM disconnected ctrl ch (local)\n");
+ printk(FNC"RFCOMM disconnected ctrl ch (local)\n");
rfcomm->dlci[0].state =3D DISCONNECTED;
=20=09=09=09=09
/* this will take down l2cap aswell */
@@ -1222,7 +1209,7 @@
} else if (rfcomm->dlci[tmp_dlci].state =3D=3D DISCONNECTED) {
rfcomm->dlci[tmp_dlci].state =3D CONNECTED;
} else {
- D_ERR(FNC" Something wrong receiving UA packet\n");
+ D_WARN(FNC" Something wrong receiving UA packet\n");
}=20=20=20=20
break;
=20=20=20=20=20
@@ -1278,7 +1265,7 @@
D_REC(FNC"long packet length %d\n",
uih_len);
if (uih_len > (len - 5)) {
- D_ERR(__FUNCTION__", Long packet length doesn't match, setting length =
to l2cap len - 5\n");
+ D_WARN(FNC", Long packet length doesn't match, setting length to l2cap=
len - 5\n");
uih_len =3D len - 5;
}
=20=09=09=09
@@ -1287,7 +1274,7 @@
uih_len =3D short_pkt->h.length.len;
uih_data_start =3D short_pkt->data;
if (uih_len > (len - 4)) {
- D_ERR(__FUNCTION__", Long packet length doesn't match, setting length =
to l2cap len - 4\n");
+ D_WARN(FNC", Short packet length doesn't match, setting length to l2ca=
p len - 4\n");
uih_len =3D len - 4;
}
}
@@ -1296,9 +1283,15 @@
D_REC(FNC" %d more credits on dlci:%d...\n",=20
*uih_data_start, tmp_dlci);
=20
- rfcomm->dlci[tmp_dlci].local_credits +=3D=20
- uih_data_start[0];
+ rfcomm->dlci[tmp_dlci].local_credits +=3D uih_data_start[0];
+#ifdef __KERNEL__
+ bt_feedstack();
+#endif
+ D_REC(FNC"Local_credits:%d\n", rfcomm->dlci[tmp_dlci].local_credits);=
=20
uih_data_start++;
+ if (short_pkt->h.length.len =3D=3D 0) {
+ break;
+ }
=20
/* feed uih data to tty if any */
=20
@@ -1318,15 +1311,14 @@
=20
if (rfcomm->credit_flow) {
rfcomm->dlci[tmp_dlci].remote_credits--;
- if (rfcomm->dlci[tmp_dlci].remote_credits <=3D 1) {
+ D_CTRL(FNC": Remote credits: %d\n",rfcomm->dlci[tmp_dlci].remote_credi=
ts);
+ if (rfcomm->dlci[tmp_dlci].remote_credits < MIN_CREDITS) {
/* FIXME -- possible race ? */
=20=09=09=09=09=09
- /* FIXME -- send credits piggybacked */
+ rfcomm_send_credits(rfcomm, tmp_dlci, MAX_CREDITS - rfcomm->dlci[tmp_=
dlci].remote_credits);
+ rfcomm->dlci[tmp_dlci].remote_credits =3D MAX_CREDITS;
+ D_SND(FNC"Remote credits: %d\n",rfcomm->dlci[tmp_dlci].remote_credits=
);
=20
- rfcomm_send_credits(rfcomm, tmp_dlci,=20
- NBROFCREDITS -1);
- rfcomm->dlci[tmp_dlci].remote_credits+=3D
- NBROFCREDITS - 1;=20
}
}=09=09=09
bt_receive_top(con_id, uih_data_start, uih_len);
@@ -1337,7 +1329,7 @@
D_REC(FNC"illegal packet\n");
break;
}
-#undef FNC
+
}
=20
=20
@@ -1348,7 +1340,6 @@
s32=20
rfcomm_send_data(u32 con_id, u8 *data, u32 count)
{
-#define FNC "rfcomm_send_data: "
u32 c;
u32 total =3D 0;
u8 line;
@@ -1373,23 +1364,21 @@
D_ERR(FNC"ERROR magic test failed\n");
return -1;
} else if(rfcomm->dlci[0].state =3D=3D FLOW_STOPPED) {
- DSYS(FNC"Flow stopped on all channels, returning zero\n");
+ D_SND(FNC"Flow stopped on all channels, returning zero\n");
/* FIXME: We need to buffer the incoming data here... */
return 0;
} else if (rfcomm->dlci[dlci].state =3D=3D FLOW_STOPPED) {
- DSYS(FNC"Flow stopped, returning zero\n");
+ D_SND(FNC"Flow stopped, returning zero\n");
/* FIXME: We need to buffer the incoming data here... */
return 0;
}
/* Check whether there are any data channels connected */
- else if (rfcomm->dlci[dlci].state =3D=3D CONNECTED)
- {
- D_SND(FNC"trying to send %d bytes\n", count);
- while (count)
+ else if (rfcomm->dlci[dlci].state =3D=3D CONNECTED) {
=20
- {=09
+ D_SND(FNC"trying to send %d bytes\n", count);
+ while (count) {=09
if (rfcomm->credit_flow &&(rfcomm->dlci[dlci].local_credits <=3D 0)) {
- DSYS(FNC"Flow stopped, no credits returning zero\n");
+ D_SND(FNC"Flow stopped, no credits returning %d\n", total);
return total;
}
=20=09=09=09
@@ -1412,7 +1401,7 @@
} else {
if (rfcomm->credit_flow) {
rfcomm->dlci[dlci].local_credits--;
- D_CTRL(FNC"%d credits left\n", rfcomm->dlci[dlci].local_credits);
+ D_SND(FNC"Local credits:%d\n", rfcomm->dlci[dlci].local_credits);
}
=20
total +=3D c;
@@ -1422,9 +1411,7 @@
}
D_SND(FNC"sent %d bytes\n", total);
return total;
- }
- else
- {
+ } else {
D_ERR(FNC"DLCI %d not connected\n", dlci);
#ifdef __KERNEL__
/* FIXME - should we return an _error_ if rfcomm isn't up=20
@@ -1435,8 +1422,22 @@
return -1;
#endif
}
-#undef FNC
+
+}
+
+s32
+rfcomm_flow_stop(u8 line, u8 dlci)
+{
+ if (rfcomm_con_list[line].credit_flow &&(rfcomm_con_list[line].dlci[dlci]=
.local_credits <=3D 0)) {
+ return TRUE;
+ } else if (rfcomm_con_list[line].dlci[dlci].state =3D=3D FLOW_STOPPED) {
+ return TRUE;
+ } else if (rfcomm_con_list[line].dlci[0].state =3D=3D FLOW_STOPPED) {
+ return TRUE;
+ } else {
+ return FALSE;
}
+}
=20
void=20
rfcomm_send_testdata(u32 count, u8 line)
@@ -1459,7 +1460,6 @@
void=20
process_mcc(u8* data, u32 len, rfcomm_con *rfcomm, s32 longpkt)
{
-#define FNC "process_mcc: "
mcc_short_frame *mcc_short_pkt;
=20=20=20=20=20
D_CTRL("process_mcc\n");
@@ -1588,7 +1588,8 @@
swap_pn_msg(pn_pkt);
D_CTRL(FNC"Received DLC parameter negotiation, PN\n");
if (longpkt) {
- /* UNPLUGGED Ericsson using 2 bytes length field */
+ /* If a long length field is used, then move the
+ payload pointer one byte ahead */
data++;
pn_pkt =3D (pn_msg*) data;
}=20=20
@@ -1607,12 +1608,14 @@
credit =3D pn_pkt->credit_flow;
nbrof_credits =3D pn_pkt->credits;=09=09=09
if (credit) {
- printk(FNC"Using credit flow control, initiating credits are %d on dlc=
i %d\n", nbrof_credits, tmp_dlci);
- rfcomm->credit_flow =3D 1;
+ D_CTRL(FNC"Using credit flow control, initiating credits are %d on dlc=
i %d\n", nbrof_credits, tmp_dlci);
+ rfcomm->credit_flow =3D TRUE;
rfcomm->dlci[tmp_dlci].local_credits =3D nbrof_credits;
- rfcomm->dlci[tmp_dlci].remote_credits =3D NBROFCREDITS;
+ D_CTRL(FNC"Local credits:%d\n", rfcomm->dlci[tmp_dlci].local_credits);=
=20
+ rfcomm->dlci[tmp_dlci].remote_credits =3D MAX_CREDITS;
+ D_CTRL(FNC"Remote credits: %d\n",rfcomm->dlci[tmp_dlci].remote_credits=
);
send_pn_msg(rfcomm, pn_pkt->prior, frame_size
- , credit ^ 1, NBROFCREDITS,=20
+ , credit ^ 1, MAX_CREDITS,=20
tmp_dlci, MCC_RSP);
} else {
send_pn_msg(rfcomm, pn_pkt->prior, frame_size
@@ -1625,9 +1628,9 @@
u8 tmp_dlci;
tmp_dlci =3D pn_pkt->dlci;
D_CTRL(FNC"received PN response with:\n");
- D_CTRL("Frame size:%d\n",pn_pkt->frame_size);
- D_CTRL("credit_flow:%d\n", pn_pkt->credit_flow);
- D_CTRL("credits:%d\n", pn_pkt->credits);
+ D_CTRL(FNC"Frame size:%d\n",pn_pkt->frame_size);
+ D_CTRL(FNC"credit_flow:%d\n", pn_pkt->credit_flow);
+ D_CTRL(FNC"credits:%d\n", pn_pkt->credits);
=20=09=09=09
rfcomm->dlci[tmp_dlci].mtu =3D pn_pkt->frame_size;
=20=09=09=09
@@ -1635,6 +1638,7 @@
printk(FNC" Credit flow control used\n");
rfcomm->credit_flow =3D TRUE;
rfcomm->dlci[tmp_dlci].local_credits =3D pn_pkt->credits;
+ D_CTRL(FNC"Local credits:%d\n", rfcomm->dlci[tmp_dlci].local_credits);=
=20
}
=20
D_CTRL(FNC"process_mcc : mtu set on dlci:%d to %d\n",=20
@@ -1659,7 +1663,7 @@
=20=20=20=20=20
break;
}
-#undef FNC
+
}
=20
=20
@@ -1833,12 +1837,13 @@
{
bt_tx_buf *tx_buf;
u32 rfcomm_frame_size;
+ u8 send_credit =3D 0;
=20=09=09
- D_CTRL("send_uih: Creating UIH packet with %d bytes data to DLCI %d\n",
+ D_CTRL(FNC"Creating UIH packet with %d bytes data to DLCI %d\n",
len, dlci);
=20
if (!rfcomm->l2cap->link_up) {
- D_ERR("[RFCOMM]send_uih : could not send data, baseband down\n");
+ D_ERR(FNC"could not send data, baseband down\n");
#ifdef __KERNEL__
return 0;
#else
@@ -1846,11 +1851,15 @@
#endif
}
=20=09
+ if (rfcomm->credit_flow &&(rfcomm->dlci[dlci].remote_credits < MAX_CREDIT=
S)) {
+ D_SND(FNC"Sending more credits to remote port\n");
+ send_credit =3D 1;
+ }
=20=09=09
if (len > SHORT_PAYLOAD_SIZE) {
long_frame *l_pkt;
=20=20=20=20=20
- rfcomm_frame_size =3D sizeof(long_frame) + len + FCS_SIZE;
+ rfcomm_frame_size =3D sizeof(long_frame) + len + FCS_SIZE + send_credit;
=20
/* Check for space in buffer, don't forget the size of the
L2CAP and HCI headers */
@@ -1862,20 +1871,29 @@
tx_buf =3D subscribe_bt_buf(sizeof(rfcomm_tx_buf)
+ rfcomm_frame_size);=20=20=20=20
if (!tx_buf) {
- D_ERR("send_uih: didn't get a valid tx_buf\n");
+ D_ERR(FNC"didn't get a valid tx_buf\n");
return -1;
}
tx_buf->cur_len =3D rfcomm_frame_size;
=20=20=20=20=20
l_pkt =3D (long_frame*) (tx_buf->data + sizeof(rfcomm_tx_buf));
set_uih_hdr((void*) l_pkt, dlci, len, rfcomm->initiator);
+ if (send_credit) {
+ l_pkt->h.control =3D SET_PF(UIH);
+ l_pkt->data[0] =3D (MAX_CREDITS -
+ rfcomm->dlci[dlci].remote_credits);
+ rfcomm->dlci[dlci].remote_credits =3D MAX_CREDITS;
+ D_SND(FNC": Remote credits: %d\n",rfcomm->dlci[dlci].remote_credits);
+ memcpy(l_pkt->data + 1, data, len);
+ } else {
memcpy(l_pkt->data, data, len);
- l_pkt->data[len] =3D crc_calc((u8*) l_pkt, SHORT_CRC_CHECK);
+ }
+ l_pkt->data[len + send_credit] =3D crc_calc((u8*) l_pkt, SHORT_CRC_CHECK=
);
swap_long_frame(l_pkt);
} else {
short_frame *s_pkt;
=20
- rfcomm_frame_size =3D sizeof(short_frame) + len + FCS_SIZE;
+ rfcomm_frame_size =3D sizeof(short_frame) + len + FCS_SIZE + send_credit;
/* Check for space in buffer, don't forget the size of the
L2CAP and HCI headers */
if (buf_write_room() < (rfcomm_frame_size
@@ -1885,7 +1903,7 @@
tx_buf =3D subscribe_bt_buf(sizeof(rfcomm_tx_buf)
+ rfcomm_frame_size);
if (!tx_buf) {
- D_ERR("send_uih: didn't get a valid tx_buf\n");
+ D_ERR(FNC"didn't get a valid tx_buf\n");
return -1;
}
tx_buf->cur_len =3D rfcomm_frame_size;
@@ -1893,8 +1911,17 @@
s_pkt =3D (short_frame*) (tx_buf->data + sizeof(rfcomm_tx_buf));
/* Always one */
set_uih_hdr((void*) s_pkt, dlci, len, rfcomm->initiator);
+ if (send_credit) {
+ s_pkt->h.control =3D SET_PF(UIH);
+ s_pkt->data[0] =3D (MAX_CREDITS -
+ rfcomm->dlci[dlci].remote_credits);
+ rfcomm->dlci[dlci].remote_credits =3D MAX_CREDITS;
+ D_SND(FNC": Remote credits: %d\n",rfcomm->dlci[dlci].remote_credits);
+ memcpy(s_pkt->data + 1, data, len);
+ } else {
memcpy(s_pkt->data, data, len);
- s_pkt->data[len] =3D crc_calc((u8*) s_pkt, SHORT_CRC_CHECK);
+ }
+ s_pkt->data[len + send_credit] =3D crc_calc((u8*) s_pkt, SHORT_CRC_CHECK=
);
}
=20
/* FIXME - How should we propagate result up to higher layers ?
@@ -1910,7 +1937,7 @@
short_frame *uih_pkt;
u32 rfcomm_frame_size;
=20=20=20
- D_CTRL(__FUNCTION__" give %d credits to dlci %d\n", credits, dlci);
+ D_CTRL(FNC"give %d credits to dlci %d\n", credits, dlci);
=20
rfcomm_frame_size =3D (sizeof(short_frame) + 1 + FCS_SIZE);
tx_buf =3D subscribe_bt_buf(sizeof(rfcomm_tx_buf) + rfcomm_frame_size);
@@ -2312,13 +2339,13 @@
msc_msg *msc_pkt;
u32 rfcomm_frame_size;
=20=20=20
- D_CTRL(__FUNCTION__" val:%d, cr:%d, dlci:%d\n", value, cr, dlci);
+ D_CTRL(FNC"val:%d, cr:%d, dlci:%d\n", value, cr, dlci);
=20
rfcomm_frame_size =3D sizeof(msc_msg);
tx_buf =3D subscribe_bt_buf(sizeof(rfcomm_tx_buf) + rfcomm_frame_size);
=20
if (!tx_buf) {
- D_ERR("rfcomm_msc_msg : didn't get a valid tx_buf\n");
+ D_ERR(FNC"didn't get a valid tx_buf\n");
return -1;
}
=20
@@ -2370,7 +2397,7 @@
{
s32 i =3D 0;
=20
- D_CTRL("get_new_rfcomm_con: rfcomm_con -> ttyBT%d\n",i);
+ D_CTRL(FNC"rfcomm_con -> ttyBT%d\n",i);
=20
for (i =3D 0 ; i < BT_NBR_DATAPORTS ; i ++)
{
@@ -2424,17 +2451,17 @@
{
u8 fcs =3D 0xff;
=20
- RF_DATA("crc_check:", data, length);
+ RF_DATA(FNC, data, length);
while (length--) {
fcs =3D crctable[fcs ^ *data++];
}
fcs =3D crctable[fcs ^ check_sum];
- D_REC("fcs : %d\n", fcs);
+ D_REC(FNC"fcs : %d\n", fcs);
if (fcs =3D=3D (uint) 0xcf) /* CRC_VALID) */ {
- D_REC("crc_check: CRC check OK\n");
+ D_REC(FNC"CRC check OK\n");
return 0;
} else {
- D_ERR("crc_check: CRC check failed\n");
+ D_WARN(FNC"CRC check failed, data will be discarded\n");
return -1;
}
}
@@ -2454,7 +2481,7 @@
return 0xff-fcs;
}
=20
-/* Calulates a reversed CRC table for the FCS check */
+/* Calculates a reversed CRC table for the FCS check */
=20
void
create_crctable(u8 table[])
@@ -2537,7 +2564,7 @@
tx_buf =3D subscribe_bt_buf(sizeof(rfcomm_tx_buf) + rfcomm_frame_size);
=20
if (!tx_buf) {
- D_ERR("rfcomm_test_415: didn't get a valid tx_buf\n");
+ D_ERR(FNC"didn't get a valid tx_buf\n");
return -1;
}
=20
@@ -2566,7 +2593,7 @@
rfcomm_pn_msg(rfcomm_con *rfcomm, u8 dlci, u8 credits, u32 frame_size)
{
if (credits) {
- printk("rfcomm_pn_msg: using %d credits\n", credits);
+ printk(FNC"using %d credits\n", credits);
return send_pn_msg(rfcomm, 0, frame_size, 0xf, credits, dlci,
TRUE);
} else {
|
|
From: Mats F. <ma...@us...> - 2001-07-06 06:46:56
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
rfcomm.c 1.114 1.115=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
Increased the amount of credits
The diff of the modified file(s):
--- rfcomm.c 2001/06/19 06:13:01 1.114
+++ rfcomm.c 2001/07/06 06:46:54 1.115
@@ -132,7 +132,8 @@
=20
#define RFCOMM_MAX_HDR_SIZE 5
=20
-#define MAX_CREDITS 6
+#define MAX_CREDITS 20
+#define START_CREDITS 7
#define MIN_CREDITS 3
=20
#define DEF_RFCOMM_MTU 127
@@ -1608,11 +1609,11 @@
credit =3D pn_pkt->credit_flow;
nbrof_credits =3D pn_pkt->credits;=09=09=09
if (credit) {
- D_CTRL(FNC"Using credit flow control, initiating credits are %d on dlc=
i %d\n", nbrof_credits, tmp_dlci);
+ DSYS(FNC"Using credit flow control, initiating credits are %d on dlci =
%d\n", nbrof_credits, tmp_dlci);
rfcomm->credit_flow =3D TRUE;
rfcomm->dlci[tmp_dlci].local_credits =3D nbrof_credits;
D_CTRL(FNC"Local credits:%d\n", rfcomm->dlci[tmp_dlci].local_credits);=
=20
- rfcomm->dlci[tmp_dlci].remote_credits =3D MAX_CREDITS;
+ rfcomm->dlci[tmp_dlci].remote_credits =3D START_CREDITS;
D_CTRL(FNC"Remote credits: %d\n",rfcomm->dlci[tmp_dlci].remote_credits=
);
send_pn_msg(rfcomm, pn_pkt->prior, frame_size
, credit ^ 1, MAX_CREDITS,=20
|
|
From: Mats F. <ma...@us...> - 2001-07-09 09:48:38
|
The following file was modified in linux/drivers/char/bluetooth: Name Old version New version Comment ---- ----------- ----------- ------- rfcomm.c 1.115 1.116=20=20=20=20=20=20=20=20=20=20=20 The accompanying log: Increased the number of credits The diff of the modified file(s): --- rfcomm.c 2001/07/06 06:46:54 1.115 +++ rfcomm.c 2001/07/09 09:48:37 1.116 @@ -132,9 +132,9 @@ =20 #define RFCOMM_MAX_HDR_SIZE 5 =20 -#define MAX_CREDITS 20 +#define MAX_CREDITS 30 #define START_CREDITS 7 -#define MIN_CREDITS 3 +#define MIN_CREDITS 15 =20 #define DEF_RFCOMM_MTU 127 =20 |
|
From: Mattias A. <mat...@us...> - 2001-08-02 15:45:36
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
rfcomm.c 1.116 1.117=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
* fixed auto shutdown of all rfcomm connections if stack is taken=20
down during active sessions.
* fixed bug in get_connected_dlci, now returns -1 if no connected=20
dlci was found.
* added some fixme:s ...
* cleanup
The diff of the modified file(s):
--- rfcomm.c 2001/07/09 09:48:37 1.116
+++ rfcomm.c 2001/08/02 15:45:15 1.117
@@ -690,16 +690,19 @@
=20=20=20
DSYS("Shutting down RFCOMM\n");
=20
-#if 0
/* First try disconnecting */
for (i =3D 0; i < BT_NBR_DATAPORTS; i++) {
rfcomm_con *rfcomm =3D get_rfcomm_con(i);
- if (get_connected_dlci(rfcomm) !=3D -1) {
+
+ /* fixme -- handle the case where only the control=20
+ channel is left on a rfcomm session */
+
+ if (get_connected_dlci(rfcomm) > 0) {
DSYS(FNC"Now disconnecting rfcomm line %d\n", i);
rfcomm_disconnect_req(i);
}=09=09
}
-#endif
+
/* If still connections left, terminate them */
for (i =3D 0; i < BT_NBR_DATAPORTS; i++) {
rfcomm_reset_con(i);
@@ -749,9 +752,10 @@
/* we have an l2cap channel (server ch) */
D_CTRL(FNC"we already have an l2cap channel)\n");
=20
+ /* fixme -- strange case ... */
if (rfcomm->dlci[0].state !=3D DISCONNECTED) {
D_ERR(FNC"DLCI:0 neither CONNECTED nor DISCONNECTED\n");
- return 0;
+ return -1;
} else {
rfcomm->dlci[0].state =3D CONNECTING;
/* Establish the control channel */
@@ -771,11 +775,12 @@
tmp_dlci, TRUE);
}
=20
- /* ? never used ? */
- return line;
-
+ return 0;
}
=20
+
+/* fixme -- this should be on dlci/rfcomm con basis not line ... */
+
s32
rfcomm_disconnect_req(u8 line)
{
@@ -805,8 +810,8 @@
=20
/* FIXME -- check that we haven't already received=20
disconnect 'acknowledge' */
-
interruptible_sleep_on(&rfcomm_disconnect_wq);
+
/* Check that rfcomm session really disconnected */
/* FIXME -- add timer obj with status in rfcomm obj */
=20
@@ -844,6 +849,9 @@
D_CTRL("rfcomm_connect_ind\n");=20=20
if (!(rfcomm =3D get_new_rfcomm_con())) {
D_ERR("rfcomm_connect_ind: error: couldn't find free tty\n");
+=09=09
+ /* fixme -- respond neg ! */
+
return;
} else {
=20=20=20=20=20=20=20=20=20=20=20
@@ -1127,6 +1135,9 @@
#ifdef CONFIG_BLUETOOTH_USE_SECURITY_MANAGER
rfcomm_check_allowed_security(rfcomm->l2cap->remot=
e_bd,
tmp_dlci, rfcomm);
+
+ /* fixme -- check result and send neg response if not allowed */
+=09=09=09
#else
bt_connect_ind(CREATE_RFCOMM_ID(rfcomm->line, tmp_dlci));
rfcomm->dlci[tmp_dlci].state =3D CONNECTED;
@@ -1152,12 +1163,15 @@
break;
=20=20=20=20=20
case UA:
- D_CTRL(FNC"UA packet received\n");=20
rfcomm =3D ((rfcomm_con*) l2cap->upper_con);
+
if (rfcomm->magic !=3D RFCOMM_MAGIC) {
D_ERR(FNC"Invalid magic number\n");
break;
}
+=09=09
+ D_CTRL(FNC"UA packet received on line %d\n", rfcomm->line);
+
if (rfcomm->dlci[0].state =3D=3D CONNECTING) {
/* Now we are the initiating side and we have got a
respons to our SABM command. We then send a PN
@@ -1190,22 +1204,31 @@
rfcomm->dlci[tmp_dlci].initiator =3D TRUE;
=20
} else if (rfcomm->dlci[tmp_dlci].state =3D=3D DISCONNECTING) {
+=09=09=20=20
if (tmp_dlci =3D=3D 0) {
+ /* Control channel */
#ifdef __KERNEL__=09=09=09
release_wq_timer(&rfcomm_timer);
#endif
- printk(FNC"RFCOMM disconnected ctrl ch (local)\n");
+ DSYS(FNC"RFCOMM disconnected ctrl ch (local) on line [%d]\n", rfcomm->=
line);
rfcomm->dlci[0].state =3D DISCONNECTED;
=20=09=09=09=09
/* this will take down l2cap aswell */
wake_up_interruptible(&rfcomm_disconnect_wq);
=20=09=09=09=09
} else {
+ /* Data channel */
s32 tmp;
rfcomm->dlci[tmp_dlci].state =3D DISCONNECTED;
tmp =3D get_connected_dlci(rfcomm);
+
+ if (tmp >=3D 0) {
rfcomm->dlci[tmp].state =3D DISCONNECTING;
send_disc(rfcomm, tmp);
+ } else {
+ D_ERR("Could not find connected DLCI\n");
+ }
+=09=09=09=09
}
} else if (rfcomm->dlci[tmp_dlci].state =3D=3D DISCONNECTED) {
rfcomm->dlci[tmp_dlci].state =3D CONNECTED;
@@ -1219,6 +1242,10 @@
D_CTRL(FNC"DM packet received\n");
rfcomm =3D ((rfcomm_con*) l2cap->upper_con);
rfcomm->dlci[tmp_dlci].state =3D DISCONNECTED;
+
+ /* Notify upper tty */
+ /* bt_disconnect_ind() ? */
+
break;
=20=20=20=20=20
case DISC:
@@ -1233,8 +1260,7 @@
send_dm(rfcomm, tmp_dlci);
} else if ((short_pkt->h.addr.server_chn) =3D=3D 0) {
rfcomm->dlci[0].state =3D DISCONNECTED;
- /* FIXME:
- Tell the tty that the link is down */
+
printk("RFCOMM control ch disconnected (remotely)\n");
send_ua(rfcomm, 0);
#ifdef __KERNEL__
@@ -1247,8 +1273,6 @@
bt_disconnect_ind(CREATE_RFCOMM_ID(rfcomm->line,=20
tmp_dlci));
}
- D_CTRL(FNC"DISC, sending back UA\n");
-=20=20=20=20
break;
=20=20=20=20=20
case UIH:
@@ -1610,6 +1634,7 @@
nbrof_credits =3D pn_pkt->credits;=09=09=09
if (credit) {
DSYS(FNC"Using credit flow control, initiating credits are %d on dlci =
%d\n", nbrof_credits, tmp_dlci);
+
rfcomm->credit_flow =3D TRUE;
rfcomm->dlci[tmp_dlci].local_credits =3D nbrof_credits;
D_CTRL(FNC"Local credits:%d\n", rfcomm->dlci[tmp_dlci].local_credits);=
=20
@@ -2394,6 +2419,7 @@
=20
}
=20
+
rfcomm_con*=20
get_new_rfcomm_con(void)
{
@@ -2428,15 +2454,18 @@
}
}
=20
+/* fetches the 'last' non DISCONNECTED dlci number in this session,=20
+ returns -1 if no connected dlci was found */
+
s32 get_connected_dlci(rfcomm_con *rfcomm)
{
s32 tmp;
=20
tmp =3D 61;
- while ((tmp > 0) && (rfcomm->dlci[tmp].state =3D=3D DISCONNECTED)) {
+ while ((tmp >=3D 0) && (rfcomm !=3D NULL) &&=20
+ (rfcomm->dlci[tmp].state =3D=3D DISCONNECTED)) {
tmp--;
}
-
return tmp;
}
=20
|
|
From: Mattias A. <mat...@us...> - 2001-08-02 16:03:59
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
rfcomm.c 1.117 1.118=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
* call bt_unregister_rfcomm when a data channel is disconnected
* changed some debug
The diff of the modified file(s):
--- rfcomm.c 2001/08/02 15:45:15 1.117
+++ rfcomm.c 2001/08/02 16:03:28 1.118
@@ -818,7 +818,7 @@
/* check control channel */
if (rfcomm->dlci[0].state !=3D DISCONNECTED)
{
- printk("Rfcomm disconnect failed, reset session\n");
+ D_ERR("Rfcomm disconnect failed, reset session\n");
#ifdef __KERNEL__=09=09=09
bt_unregister_rfcomm(rfcomm->line);
bt_disconnect_cfm(CREATE_RFCOMM_ID(rfcomm->line, 0),=20
@@ -1261,17 +1261,18 @@
} else if ((short_pkt->h.addr.server_chn) =3D=3D 0) {
rfcomm->dlci[0].state =3D DISCONNECTED;
=20
- printk("RFCOMM control ch disconnected (remotely)\n");
+ DSYS("RFCOMM control ch disconnected (remotely) [line:%d]\n",=20
+ rfcomm->line);
send_ua(rfcomm, 0);
-#ifdef __KERNEL__
- bt_unregister_rfcomm(rfcomm->line);
-#endif
} else {
rfcomm->dlci[tmp_dlci].state =3D DISCONNECTED;
send_ua(rfcomm, tmp_dlci);
D_CTRL("dlci %d was disconnected\n", tmp_dlci);
bt_disconnect_ind(CREATE_RFCOMM_ID(rfcomm->line,=20
tmp_dlci));
+#ifdef __KERNEL__
+ bt_unregister_rfcomm(rfcomm->line);
+#endif
}
break;
=20=20=20=20=20
@@ -1661,7 +1662,7 @@
rfcomm->dlci[tmp_dlci].mtu =3D pn_pkt->frame_size;
=20=09=09=09
if (pn_pkt->credit_flow =3D=3D 0xe) {
- printk(FNC"Credit flow control used\n");
+ DSYS(FNC"Credit flow control used\n");
rfcomm->credit_flow =3D TRUE;
rfcomm->dlci[tmp_dlci].local_credits =3D pn_pkt->credits;
D_CTRL(FNC"Local credits:%d\n", rfcomm->dlci[tmp_dlci].local_credits);=
=20
@@ -2624,7 +2625,7 @@
rfcomm_pn_msg(rfcomm_con *rfcomm, u8 dlci, u8 credits, u32 frame_size)
{
if (credits) {
- printk(FNC"using %d credits\n", credits);
+ DSYS(FNC"using %d credits\n", credits);
return send_pn_msg(rfcomm, 0, frame_size, 0xf, credits, dlci,
TRUE);
} else {
|
|
From: Peter K. <pk...@us...> - 2001-09-18 12:59:49
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
rfcomm.c 1.118 1.119=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
Removed some unused code, and cleaned-up a little.
The diff of the modified file(s):
--- rfcomm.c 2001/08/02 16:03:28 1.118
+++ rfcomm.c 2001/09/18 12:59:47 1.119
@@ -102,11 +102,6 @@
=20
/****************** CONSTANT AND MACRO SECTION ***************************=
***/
=20
-#define GET_BIT(pos,bitfield) ((bitfield[(pos)/32]) & (1 << ((pos) % 32)))
-#define SET_BIT(pos,bitfield) ((bitfield[(pos)/32]) |=3D (1 << ((pos) % 32=
)))=20
-#define CLR_BIT(pos,bitfield) ((bitfield[(pos)/32]) &=3D ((1 << ((pos) % 3=
2)) \
- ^ (~0)))
-
#define SET_PF(ctr) ((ctr) | (1 << 4))=20
/* Sets the P/F-bit in the control field */
#define CLR_PF(ctr) ((ctr) & 0xef)
@@ -168,6 +163,8 @@
#define swap_mcc_long_frame(x) (swap_long_frame(x))
#define swap_pn_msg(x) ((x)->frame_size =3D le16_to_cpu((x)->frame_size))
=20
+#define RFCOMM_CON_TIMEOUT (5*HZ)
+
/****************** TYPE DEFINITION SECTION ******************************=
***/
=20
/* Typedefinitions of stuctures used for creating and parsing packets, for=
a
@@ -249,7 +246,7 @@
u8 value[0];
} __attribute__ ((packed)) mcc_long_frame;
=20
-/* MSC-command */
+/* MSC command */
typedef struct v24_signals {
u8 ea:1;
u8 fc:1;
@@ -277,59 +274,7 @@
u8 fcs;
} __attribute__ ((packed)) msc_msg;
=20
-#if 0
/* RPN command */
-#define B2400 0
-#define B4800 1
-#define B7200 2
-#define B9600 3
-#define B19200 4
-#define B38400 5
-#define B57600 6
-#define B115200 7
-#define D230400 8
-
-#endif
-
-#if 0 /* Temporary moved to rfcomm.h during the UnPlugFest */
-typedef struct parameter_mask {
- u8 bit_rate:1;
- u8 data_bits:1;
- u8 stop_bit:1;
- u8 parity:1;
- u8 parity_type:1;
- u8 xon_u8:1;
- u8 xoff_u8:1;
- u8 res1:1;
- u8 xon_input:1;
- u8 xon_output:1;
- u8 rtr_input:1;
- u8 rtr_output:1;
- u8 rtc_input:1;
- u8 rtc_output:1;
- u8 res2:2;
-} parameter_mask;
-
-typedef struct rpn_values {
- u8 bit_rate;
- u8 data_bits:2;
- u8 stop_bit:1;
- u8 parity:1;
- u8 parity_type:2;
- u8 res1:2;
- u8 xon_input:1;
- u8 xon_output:1;
- u8 rtr_input:1;
- u8 rtr_output:1;
- u8 rtc_input:1;
- u8 rtc_output:1;
- u8 res2:2;
- u8 xon_u8;
- u8 xoff_u8;
- parameter_mask pm;
-} rpn_values;
-#endif
-
typedef struct rpn_msg {
short_frame_head s_head;
mcc_short_frame_head mcc_s_head;
@@ -338,7 +283,7 @@
u8 fcs;
} __attribute__ ((packed)) rpn_msg;
=20
-/* RLS-command */=20=20
+/* RLS command */=20=20
typedef struct rls_msg {
short_frame_head s_head;
mcc_short_frame_head mcc_s_head;
@@ -348,7 +293,7 @@
u8 fcs;
} __attribute__ ((packed)) rls_msg;
=20
-/* PN-command */
+/* PN command */
typedef struct pn_msg {
short_frame_head s_head;
mcc_short_frame_head mcc_s_head;
@@ -360,7 +305,7 @@
u8 prior:6;
u8 res2:2;
u8 ack_timer;
- u32 frame_size:16;
+ u16 frame_size;
u8 max_nbrof_retrans;
u8 credits;
u8 fcs;
@@ -419,6 +364,7 @@
u8 data[0];
} __attribute__ ((packed)) long_frame;
=20
+/* Typedefinitions for structures used for the multiplexer commands */
typedef struct mcc_type {=20
u8 type:6;
u8 cr:1;
@@ -447,6 +393,7 @@
u8 value[0];
} __attribute__ ((packed)) mcc_long_frame;
=20
+/* MSC command */
typedef struct v24_signals {=20
u8 dv:1;
u8 ic:1;
@@ -474,6 +421,7 @@
u8 fcs;
} __attribute__ ((packed)) msc_msg;
=20
+/* RPN command */
typedef struct rpn_msg {=20
short_frame_head s_head;
mcc_short_frame_head mcc_s_head;
@@ -482,6 +430,7 @@
u8 fcs;
} __attribute__ ((packed)) rpn_msg;
=20
+/* RLS command */=20=20
typedef struct rls_msg {=20
short_frame_head s_head;
mcc_short_frame_head mcc_s_head;
@@ -491,9 +440,11 @@
u8 fcs;
} __attribute__ ((packed)) rls_msg;
=20
+/* PN command */
typedef struct pn_msg {=20
short_frame_head s_head;
mcc_short_frame_head mcc_s_head;
+/* The res1, res2 and res3 values have to be set to 0 by the sender */
u8 res1:2;
u8 dlci:6;
u8 credit_flow:4;
@@ -501,12 +452,13 @@
u8 res2:2;
u8 prior:6;
u8 ack_timer;
- u32 frame_size:16;
+ u16 frame_size;
u8 max_nbrof_retrans;
u8 credits;
u8 fcs;
} __attribute__ ((packed)) pn_msg;
=20
+/* NSC-command */
typedef struct nsc_msg {=20
short_frame_head s_head;
mcc_short_frame_head mcc_s_head;
@@ -550,7 +502,6 @@
#ifdef __KERNEL__
static struct timer_list rfcomm_timer;
#endif
-#define RFCOMM_CON_TIMEOUT (5*HZ)
=20
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
static struct wait_queue *rfcomm_disconnect_wq =3D NULL;
@@ -558,9 +509,6 @@
static wait_queue_head_t rfcomm_disconnect_wq;
#endif /* LINUX_VERSION_CODE */
=20
-
-void send_send_data(unsigned long ptr);
-
rpn_values rpn_val;
=20
/****************** FUNCTION DEFINITION SECTION **************************=
***/
@@ -1641,12 +1589,12 @@
D_CTRL(FNC"Local credits:%d\n", rfcomm->dlci[tmp_dlci].local_credits);=
=20
rfcomm->dlci[tmp_dlci].remote_credits =3D START_CREDITS;
D_CTRL(FNC"Remote credits: %d\n",rfcomm->dlci[tmp_dlci].remote_credits=
);
- send_pn_msg(rfcomm, pn_pkt->prior, frame_size
- , credit ^ 1, MAX_CREDITS,=20
+ send_pn_msg(rfcomm, pn_pkt->prior, frame_size,
+ credit ^ 1, MAX_CREDITS,=20
tmp_dlci, MCC_RSP);
} else {
- send_pn_msg(rfcomm, pn_pkt->prior, frame_size
- , 0, 0, tmp_dlci, MCC_RSP);
+ send_pn_msg(rfcomm, pn_pkt->prior, frame_size,
+ 0, 0, tmp_dlci, MCC_RSP);
}
rfcomm->dlci[tmp_dlci].mtu =3D frame_size;
D_CTRL(FNC"process_mcc : mtu set to %d\n",=20
@@ -1759,6 +1707,7 @@
tx_buf->cur_len =3D rfcomm_frame_size;
=20=20=20
dm_pkt =3D (short_frame*) (tx_buf->data + sizeof(rfcomm_tx_buf));
+
/* Always one in the address field */
dm_pkt->h.addr.ea =3D 1;
/* If we are the responder the cr bit should be set in a response */
@@ -2045,6 +1994,7 @@
}
=20=09=09
tx_buf->cur_len =3D rfcomm_frame_size;
+
uih_pkt =3D (long_frame*) (tx_buf->data + sizeof(rfcomm_tx_buf));
=20=20=20=20=20
set_uih_hdr((short_frame*) uih_pkt, CTRL_CHAN, len +
|
|
From: Anders J. <and...@us...> - 2001-09-28 14:54:16
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
rfcomm.c 1.119 1.120=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
* Corrected initial credits sent.
* Improved creditcalculation.
The diff of the modified file(s):
--- rfcomm.c 2001/09/18 12:59:47 1.119
+++ rfcomm.c 2001/09/28 14:54:15 1.120
@@ -1284,13 +1284,13 @@
u32 con_id =3D CREATE_RFCOMM_ID(rfcomm->line, tmp_dlci);
=20
if (rfcomm->credit_flow) {
- rfcomm->dlci[tmp_dlci].remote_credits--;
+ --rfcomm->dlci[tmp_dlci].remote_credits;
D_CTRL(FNC": Remote credits: %d\n",rfcomm->dlci[tmp_dlci].remote_credi=
ts);
if (rfcomm->dlci[tmp_dlci].remote_credits < MIN_CREDITS) {
- /* FIXME -- possible race ? */
+ u8 newcredits =3D MAX_CREDITS - rfcomm->dlci[tmp_dlci].remote_credits;
+ rfcomm_send_credits(rfcomm, tmp_dlci, newcredits);
+ rfcomm->dlci[tmp_dlci].remote_credits +=3D newcredits;
=20=09=09=09=09=09
- rfcomm_send_credits(rfcomm, tmp_dlci, MAX_CREDITS - rfcomm->dlci[tmp_=
dlci].remote_credits);
- rfcomm->dlci[tmp_dlci].remote_credits =3D MAX_CREDITS;
D_SND(FNC"Remote credits: %d\n",rfcomm->dlci[tmp_dlci].remote_credits=
);
=20=09=09=09=09=09
}
@@ -1374,7 +1374,7 @@
return total;
} else {
if (rfcomm->credit_flow) {
- rfcomm->dlci[dlci].local_credits--;
+ --rfcomm->dlci[dlci].local_credits;
D_SND(FNC"Local credits:%d\n", rfcomm->dlci[dlci].local_credits);
}
=20
@@ -1590,7 +1590,7 @@
rfcomm->dlci[tmp_dlci].remote_credits =3D START_CREDITS;
D_CTRL(FNC"Remote credits: %d\n",rfcomm->dlci[tmp_dlci].remote_credits=
);
send_pn_msg(rfcomm, pn_pkt->prior, frame_size,
- credit ^ 1, MAX_CREDITS,=20
+ credit ^ 1, START_CREDITS,=20
tmp_dlci, MCC_RSP);
} else {
send_pn_msg(rfcomm, pn_pkt->prior, frame_size,
@@ -1827,7 +1827,7 @@
#endif
}
=20
- if (rfcomm->credit_flow &&(rfcomm->dlci[dlci].remote_credits < MAX_CREDIT=
S)) {
+ if (rfcomm->credit_flow &&(rfcomm->dlci[dlci].remote_credits < MIN_CREDIT=
S)) {
D_SND(FNC"Sending more credits to remote port\n");
send_credit =3D 1;
}
@@ -1855,10 +1855,10 @@
l_pkt =3D (long_frame*) (tx_buf->data + sizeof(rfcomm_tx_buf));
set_uih_hdr((void*) l_pkt, dlci, len, rfcomm->initiator);
if (send_credit) {
+ u8 newcredits =3D MAX_CREDITS - rfcomm->dlci[dlci].remote_credits;
l_pkt->h.control =3D SET_PF(UIH);
- l_pkt->data[0] =3D (MAX_CREDITS -
- rfcomm->dlci[dlci].remote_credits);
- rfcomm->dlci[dlci].remote_credits =3D MAX_CREDITS;
+ l_pkt->data[0] =3D (newcredits);
+ rfcomm->dlci[dlci].remote_credits +=3D newcredits;
D_SND(FNC": Remote credits: %d\n",rfcomm->dlci[dlci].remote_credits);
memcpy(l_pkt->data + 1, data, len);
} else {
@@ -1888,10 +1888,11 @@
/* Always one */
set_uih_hdr((void*) s_pkt, dlci, len, rfcomm->initiator);
if (send_credit) {
+ u8 newcredits =3D MAX_CREDITS - rfcomm->dlci[dlci].remote_credits;
+=09=09=09
s_pkt->h.control =3D SET_PF(UIH);
- s_pkt->data[0] =3D (MAX_CREDITS -
- rfcomm->dlci[dlci].remote_credits);
- rfcomm->dlci[dlci].remote_credits =3D MAX_CREDITS;
+ s_pkt->data[0] =3D (newcredits);
+ rfcomm->dlci[dlci].remote_credits +=3D newcredits;
D_SND(FNC": Remote credits: %d\n",rfcomm->dlci[dlci].remote_credits);
memcpy(s_pkt->data + 1, data, len);
} else {
|