Chinaunix首页 | 论坛 | 博客
  • 博客访问: 344920
  • 博文数量: 92
  • 博客积分: 2500
  • 博客等级: 少校
  • 技术积分: 960
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-21 19:38
文章分类

全部博文(92)

文章存档

2010年(71)

2009年(21)

我的朋友

分类: 嵌入式

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.

  
 
Command to see an example below: Connection Request:

 
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:


  
The server calls socket(), bind(), listen(), after the completion of initialization, call accept() blocking wait, listen port in the state, the client calls socket () initialized, the call connect() send SYN segment and blocks waiting for the server response, the server answer a SYN-ACK segment, the client of receipt from the connect() returns, while answering an ACK segment, the server receipt from the accept() returns.


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 \ n", argv [0]);
         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);
)

 

阅读(3299) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~