全部博文(92)
分类: 嵌入式
2009-09-16 18:34:20
1: L2CAP Protocol Description:
Logical Link Control and Adaptation Protocol (L2CAP) provides connection-oriented and connectionless data services for the upper protocol, and provides multi-protocol functionality and operation of division and reconstruction. L2CAP protocol and allows an upper application software to transmit and receive the maximum length of 64K of the L2CAP packets.
L2CAP is based on channel concept. Channel (Channel) is located in the baseband which is above the logical connection. Each channel binds in a way that many channels bind to one single protocol. Multiple channels can bind to a protocol, but a channel can not bind multiple protocols. Each of the channel receives L2CAP data packets and then being transmitted to the corresponding upper-layer protocols. Multiple channels can share the same baseband connection.
L2CAP in Bluetooth protocol stack are located at:
In other words, all the L2CAP data are transmitted through the HCI to the Remote Device. And the upper protocol data, mostly through L2CAP to transfer.
L2CAP can send Command. For example, connection, disconnection and so on.
PSM which require greater attention, L2CAP using the L2CAP connection request (Connection Request) in the PSM field in order to achieve an agreement reuse. L2CAP can be re-distributed to the upper protocol connection with the request, these upper-layer protocols include the Service Discovery Protocol SDP (PSM = 0x0001), RFCOMM (PSM = 0x0003) and phone control (PSM = 0x0005) and so on.
Protocol |
PSM |
Reference |
SDP |
0x0001 |
|
RFCOMM |
0x0003 |
|
TCS-BIN |
0x0005 |
|
TCS-BIN-CORDLESS |
0x0007 |
|
BNEP |
0x000F |
|
HID_Control |
0x0011 |
|
HID_Interrupt |
0x0013 |
|
UPnP |
0x0015 |
|
AVCTP |
0x0017 |
|
AVDTP |
0x0019 |
|
AVCTP_Browsing |
0x001B |
|
UDI_C-Plane |
0x001D |
|
2: TCP protocol flow of communication:
Data transfer process:
To establish a connection, TCP protocol provides full-duplex communications services, but the general client / server program procedure is to take the initiative launched by the client request, the server passively answers the request, a question and answer approach. Therefore, the server from the accept() returns immediately after calling read(), read the same socket as read channels, without waiting for the data arrive on the block, when a client calls write() to send the request to the server, the server use read() return the client's request for processing, during which the client calls read () to block and wait for the server's response, the server calls the write() to deal with the results sent back to the client, once again calling read () to block and wait for the next request for a , the client of receipt from the read () returns, send a request for the next, and so cycle continues.
If the client does not have more requests, and to call close() to close the connection, just like to write off the pipe end, as the server's read() returns 0, so the server knows that the client closed the connection, it calls close() to Close the connection. Note that any party calling close () after connecting the two transmission directions are closed, can not send data. If one side calls shutdown() and then connection is in a semi-closed state, and can receive the data sent by the other side.
Learning socket API should pay attention to application and TCP protocol layer how to interact: * when application calls a socket function and what actions TCP protocol layer has completed, such as call connect() will issue a SYN segment * How do you know TCP protocol applications layer state changes, such as from a blocked socket function returns the TCP protocol that has received some paragraphs, and then for example read() returns 0 to show receiving a FIN segment
3: L2CAP programming method:
L2CAP programming is very important, it is the Linux Bluetooth, and HCI basic programming foundation. Almost all protocols connections, disconnection, reading and writing are all to do with the L2CAP connection.
1. Create L2CAP Socket:
socket (PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP);
domain = PF_BLUETOOTH, type can be various types. protocol = BTPROTO_L2CAP.
2. Binding:
/ / Bind to local address
memset (& addr, 0, sizeof (addr));
addr.l2_family = AF_BLUETOOTH;
bacpy (& addr.l2_bdaddr, & bdaddr); / / bdaddr local Dongle BDAddr
if (bind (sk, (struct sockaddr *) & addr, sizeof (addr)) <0) (
perror ( "Can't bind socket");
goto error;
)
3. Connect
memset (& addr, 0, sizeof (addr));
addr.l2_family = AF_BLUETOOTH;
bacpy (addr.l2_bdaddr, src);
addr.l2_psm = xxx;
if (connect (sk, (struct sockaddr *) & addr, sizeof (addr)) <0) (
perror ( "Can't connect");
goto error;
)
Note:
struct sockaddr_l2 (
sa_family_t l2_family; / / must be AF_BLUETOOTH
unsigned short l2_psm; / / corresponds with previous PSM, this one is very important
bdaddr_t l2_bdaddr; / / Remote Device BDADDR
unsigned short l2_cid;
);
4. To send data to a Remote Device:
send () or write () all OK.
5. Receive Data:
revc () or read ()
The following examples:
Note: In Bluetooth, the initiative to end the connection as the host side. Passively wait for someone else to connect as Client-side.
l2cap-server.c
# include
# include
# include
# include
# include
int main (int argc, char ** argv)
(
struct sockaddr_l2 loc_addr = (0), rem_addr = (0);
char buf [1024] = (0);
int s, client, bytes_read;
socklen_t opt = sizeof (rem_addr);
/ / Allocate socket
s = socket (AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
/ / Bind socket to port 0x1001 of the first available
/ / Bluetooth adapter
loc_addr.l2_family = AF_BLUETOOTH;
loc_addr.l2_bdaddr = * BDADDR_ANY;
loc_addr.l2_psm = htobs (0x1001);
bind (s, (struct sockaddr *) & loc_addr, sizeof (loc_addr));
/ / Put socket into listening mode
listen (s, 1);
/ / Accept one connection
client = accept (s, (struct sockaddr *) & rem_addr, & opt);
ba2str (& rem_addr.l2_bdaddr, buf);
fprintf (stderr, "accepted connection from% s \ n", buf);
memset (buf, 0, sizeof (buf));
/ / Read data from the client
bytes_read = read (client, buf, sizeof (buf));
if (bytes_read> 0) (
printf ( "received [% s] \ n", buf);
)
/ / Close connection
close (client);
close (s);
)
l2cap-client.c
# include
# include
# include
# include
# include
int main (int argc, char ** argv)
(
struct sockaddr_l2 addr = (0);
int s, status;
char * message = "hello!";
char dest [18] = "01:23:45:67:89: AB";
if (argc <2)
(
fprintf (stderr, "usage:% s
exit (2);
)
strncpy (dest, argv [1], 18);
/ / Allocate a socket
s = socket (AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
/ / Set the connection parameters (who to connect to)
addr.l2_family = AF_BLUETOOTH;
addr.l2_psm = htobs (0x1001);
str2ba (dest, & addr.l2_bdaddr);
/ / Connect to server
status = connect (s, (struct sockaddr *) & addr, sizeof (addr));
/ / Send a message
if (status == 0) (
status = write (s, "hello!", 6);
)
if (status <0) perror ( "uh oh");
close (s);
)