After the above socke is created, we will naturally think of the following work, that is, bind.
5.6 bind Analysis of l2cap
According to international practice, after the socket is built, bind is bound, haha ~~
if (l2cap_bind(sock, &opts->src, server ? opts->psm : 0, opts->cid, err) < 0)
This function is as follows:
Static int l2cap_bind (int sock, const bdaddr_t * src, uint16_t psm, uint16_t cid, GError ** err) {struct sockaddr_l2 addr; memset (& addr, 0, sizeof (addr); addr. l2_family = AF_BLUETOOTH; bacpy (& addr. l2_bdaddr, src); // The cid is 0, and the SM is 0? If (cid) addr. l2_cid = htobs (cid); else addr. l2_psm = htobs (psm); // bind, which will still be called to the kernel. For details, see the analysis of if (bind (sock, (struct sockaddr *) & addr, sizeof (addr) <0) {ERROR_FAILED (err, "l2cap_bind", errno); return-1;} return 0 ;}
5.6.1 bind Analysis in kernel
Static int l2cap_sock_bind (struct socket * sock, struct sockaddr * addr, int alen) {// obtain the corresponding sock and chan struct sock * sk = sock-> sk; struct l2cap_chan * chan = l2cap_pi (sk)-> chan; struct sockaddr_l2 la; int len, err = 0; BT_DBG ("sk % p", sk ); // check the input parameter if (! Addr | addr-> sa_family! = AF_BLUETOOTH) return-EINVAL; memset (& la, 0, sizeof (la); len = min_t (unsigned int, sizeof (la), alen ); // copy the input content to memcpy (& la, addr, len) in la; // neither of them can have a value. Both of us are 0 if (la. l2_cid & la. l2_psm) return-EINVAL; lock_sock (sk); // This is open at the beginning. Here it is just a double check if (sk-> sk_state! = BT_OPEN) {err =-EBADFD; goto done;} // if you have input. l2_psm) {_ b2psm = _ le16_to_cpu (la. l2_psm); // The psm must be an odd number and a high value of 0. This is specified by spec. For details, see 5.6.2/* PSM must be odd and lsb of upper byte must be 0 */if (psm & 0x0101 )! = 0x0001) {err =-EINVAL; goto done ;} /* Restrict usage of well-known PSMs * // check the range of MSPs and check the permissions if (MSPS <0x1001 &&! Capable (CAP_NET_BIND_SERVICE) {err =-EACCES; goto done ;}// if there is a cid, add the cid; otherwise, add the SMS. about the concept of the cid, in 5.6.3, we analyze if (la. l2_cid) err = l2cap_add_scid (chan, la. l2_cid); else // It can be generated no matter whether there are any MSPs. Here is the assignment of MSPs. For detailed analysis, see 5.6.4 err = l2cap_add_sm (chan, & la. l2_bdaddr, la. l2_psm); if (err <0) goto done; // This is a special psm value, sdp if (_ le16_to_cpu (la. l2_psm) = 0x0001 | _ le16_to_cpu (la. l2_psm) = 0x0003) chan-> sec_level = BT_SECURITY_SDP; // The Source bacpy (& bt_sk (sk)-> src, & la. l2_bdaddr); // The chan state is set to bound, that is, the chan-> state = BT_BOUND; sk-> sk_state = BT_BOUND; done: release_sock (sk); return err ;}
5.6.2 rules in spec
All the MNS are called Protocol/ServiceMultiplexer. In spec, it is described as follows:
The PSM fieldis at least two octets in length. the structure of the PSM field is based onthe ISO 3309 extension mechanic for address fields. all PSM values shall beODD, that is, the least significant bit of the least significant octet must be '1 '. also, all PSM values shall have the least significant bit of the mostsignificant octet equal to '0 '. this allows the PSM field to be extended beyond16 bits. PSM values are separated into two ranges. valid values in the firstrange are assigned by the Bluetooth SIG and indicate protocols. the secondrange of values are dynamically allocated and used in conjunction with theService Discovery Protocol (SDP ). the dynamically assigned values may be usedto support multiple implementations of a particle protocol.
In this section, we mean that the minimum length of the SMS is 2 bytes, and its value should be an odd number, that is, the minimum bytes must be 1. in addition, the maximum bytes of the psm should be 0. it can be longer than 2 bytes. the MNS consists of two range segments. The first range segment is SIG used to indicate the corresponding protocol, and the second range segment is dynamically applied and used in combination with SDP. This value is used to support different implementations of a specific protocol. The two range fields are set as follows:
Therefore, when we apply for MnS, we start from 0x1001. The reason is 0x0001 ~ 0x0eff is reserved by SIG. Which protocol does each of these reserved values correspond? See the following table for details: <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4KPHA + PHN0cm9uZz48YnI + cda-vc3ryb25np1_vcd4kphrhymxligjvcmrlcj0 = "1" cellspacing = "0" cellpadding = "0">
Protocol
PSM
SDP
Zero X 0001
RFCOMM
Zero X 0003
TCS-BIN
Zero X 0005
TCS-BIN-CORDLESS
Zero X 0007
BNEP
0X000F
HID_Control
Zero x 0011
HID_Interrupt
Zero x 0013
UPnP
Zero x 0015
AVCTP
Zero X 0017
AVDTP
Zero X 0019
AVCTP_Browsing
0x001B
UDI_C-Plane
0x001D
ATT
0X001F
3DSP
Zero X 0021
Cid rules in 5.6.3 spec
CID is called ChannelIdentifer. It is used to indicate different L2CAP channels. Each L2CAP channel must have a different CID. The main description of CID in spec is as follows:
A channel identifier (CID) is the local name representing a logical channel endpoint on the device. the null identifier (0x0000) shall never be used as a destination endpoint. identifiers from 0x0001 to 0x003F are reserved for specific L2CAP functions. these channels are referred to as Fixed Channels. at a minimum, the L2CAPSignaling channel (Fixed Channel 0x0001) or the L2CAP LE Signaling channel (Fixed Channel 0x0005) shall be supported. if Fixed Channel 0x0005 issupported, then Fixed Channels 0x0004 and 0x0006 shall be supported (seeTable 2.1 ). otherfixed channels may be supported. the Information Request/Response Mechanic (described in Section 4.10 andSection 4.11) shall be used to determine which fixed channels aremote device supports over the ACL-U logical link.
In this section, we can find that 0x0000 cannot be used, 0x0001 ~ 0x003F is requisitioned. They are called FixedChannels, which is a special seat for the elderly, the sick, and the pregnant women. Generally, do not sit here (not appropriate. In our country, everyone will still sit here, haha ~~). Here, L2CAP Signaling channel (0x0001) and LESignaling channel (0x0005) should be supported. If 0x0005 (LE device) is supported, 0x004 and 0x006 are also supported. Others are supported. What exactly are the Fix channels? For details, see the following table:
In general, to create an L2CAP channel, a corresponding cid value is required. This is probably the meaning.
5.6.4 Implementation of the assignment of MnS in bluez
In 5.6.2, we have a detailed description of how the MNS are defined in spec. Next we will continue to look at how the MNS are implemented in bluez code.
Int l2cap_add_psm (struct l2cap_chan * chan, bdaddr_t * src, _ le16 psm) {int err; write_lock_bh (& chan_list_lock); // if there is a psm, then, the chan corresponding to this SM is found, and the in use error if (psm & _ l2cap_global_chan_by_addr (psm, src) {err =-EADDRINUSE; goto done;} if (psm) {// if there is a psm, it is to set the SM and sport values of chan to chan-> psm = psm; chan-> sport = psm; err = 0;} else {2010p; err =-EINVAL; for (p = 0x1001; p <0x1100; p + = 2) // If no, is from Low to high, find the MNS that are not used. With the spec explanation, the reason for this is clear from 1001. if (! _ L2cap_global_chan_by_addr (cpu_to_le16 (p), src) {chan-> psm = cpu_to_le16 (p); chan-> sport = cpu_to_le16 (p); err = 0; break ;}} done: write_unlock_bh (& chan_list_lock); return err ;}
Now, the bind analysis is complete. In fact, it is to associate the corresponding SMS and cid with the protocol and L2cap applied below. If not, apply for the corresponding SMS or cid value.
Zookeeper