You can get started from CE222046 - PSoC 6 BLE Throughput Measurement. This code example demonstrates a server sending notification packet of size 495 bytes continuously. Each notification packet (size 495 bytes) takes a processing time of 2.34 mS. Hence, in a connection interval of 75 mS, 32 notification packets are sent.
To add to Geona's response, you can send a max of 251 bytes of data per packet with data length extension supported in BLE 4.2 (and higher). This is easily achieved in PSoC 6 by setting the Tx or Rx LL payload size (BLE Component > Link Layer Settings > max Tx or Rx payload size field).
Next is the Attribute MTU size, which determines the maximum size of an ATT packet (these packets are disassembled/reassembled at the L2CAP layer). This determines the size of one packet that the L2CAP can handle. PSoC 6 supports MTU sizes of up to 512 bytes. This field is set in the BLE Component > GATT Settings > Attribute MTU Size field at the bottom left side of the config window.
It should be noted that even though PSoC 6 supports a max payload of 251 bytes and MTU sizes of up to 512 bytes, the peer device should also support similar payload/MTU sizes to benefit from this i.e. to achieve max throughput between the devices.
Irrespective of achieving max throughput, you still can easily send 244 bytes per connection event by creating a custom service (refer to this example pointed by Geona) either create a notification packet with 244 bytes of data or create a simple read/write characteristic with 244 bytes length. When you send notification (notification packet with peer/client enabling the notification) or peer does a read (simple read/write characteristic), the 244 bytes of data will be split into multiple packets (depending on your ATT MTU size negotiated and LL Tx/Rx payload size) and sent during the connection event. Say your LL payload size is 23 and negotiated MTU size is 185. Your notification of 244 bytes will be sent as 2 ATT packets (ceil(244/182) - 3 bytes overhead from ATT protocol) or 12 LL packets (ceil(185/23) + ceil (65/23) = 9+ 3 = 12 - first 185 ATT packet contains 182 bytes of notif data and the next 65 contains 62 bytes of notif data, 3 bytes ATT overhead in both packets) during a connection event. If you change the LL payload size to 251 and the negotiated MTU size is 512 bytes, then your 244 bytes notification is sent as one ATT packet or one LL packet, thus improving the throughput and reducing the power (as overhead is reduced).
Let me know if this helps.
Meenakshi Sundaram R
The field you are looking at defines the length of the characteristic and is above the ATT layer. Hence this size can be any value (limitation your memory or your requirement). Depending on the ATT MTU size, this characteristic will be split into multiple packets at the L2CAP layer and sent to the LL. The LL then uses the Tx payload size packets to transfer the data over-the-air.
Meenakshi Sundaram R
Why did they (the sig) make an ATT MTU and a L2CAP MTU?
If I were to sum up the whole message you typed.
1. All radio packets aka l2cap packets are divided up into a maximum of L2CAP MTU size (23-251)
2. All ATT messages are divided up into maximum ATT MTU bytes
3. The maximum ATT is 512 bytes
If the LL payload size is 23 and negotiated MTU size is 185。Can I understand that each air interface packet include 4 bytes basic L2CAP header ,only 2 packets contain 3 bytes notification ATT overhead (opcode：0x1B(one byte) and attribute handle(tow bytes)) and 20 bytes of user data and another 10 packets contain 23 bytes user data for each packet if I want to transmit 244 bytes user data.
I read the code CE222046 found that it achieve transmit 495 bytes user data by the follow operation：
/* Update Notification packet with the data. */
notificationPacket.connHandle = appConnHandle;
notificationPacket.handleValPair.attrHandle = CUSTOM_SERV0_CHAR0_HANDLE;
notificationPacket.handleValPair.value.val = buffer;
notificationPacket.handleValPair.value.len = NOTIFICATION_PKT_SIZE;
if(charNotificationEnabled == true)
/* Send notification data to the GATT Client*/
I have some questions to ask you：
１：Ａfter I call the Cy_BLE_GATTS_Notification() function ,the 1024 bytes user data be split into tow ATT packets automatic without any operation by the user code (The ATT MTU is 512) ,and then the Link Controller and the L2CAP component will be split into 5 LL packets.The user only need to play the correct number of the user data size? Is Correct?
2:I found that the parameter "notificationPacket.handleValPair.value.len" is a 16 bits variate,What determines this?The length fields of the Basic L2CAP header? if the connInterval is allowed，it can transmit more than 65535 bytes data in a Connection Event right?
As per my understanding from the BLE spec-
"ATT Maximum Transmission Unit (MTU) is the maximum length of an ATT packet. The ATT MTU is defined by the L2CAP and can be anywhere between 23 and infinity." ( However, the current PSoC Creator Version Supports up-to 512 only)
Note: The maximum length of an attribute value shall be 512 octets.
The below pictorial representation might help to understand the scenario better-
2) In Details with an Example of 50 bytes transmission.
Just one correction -
1. All ATT messages are divided into max ATT MTU size packets - these packets go to L2CAP layer
2. Ideally L2CAP splits them into L2CAP MTU size packets - however, in our component we do not have a L2CAP MTU size on the ATT channel. The L2CAP MTU size you notice is for user-implemented or application level L2CAP channels (through which user can exchange data at the L2CAP layer directly between devices). For ATT channel, I believe the L2CAP derives its MTU size from the ATT MTU directly as Gyan pointed out.
3. The L2CAP packets are then split into the LL payload size packets.
Note that ATT splitting happens at the L2CAP interface with the ATT layer and LL splitting happens at the L2CAP interface with LL layer i.e. all fragmentation and reassembly happens at the L2CAP layer.
Meenakshi Sundaram R
There is a correction to my statement on the post#2 - I was earlier under the impression from our component configuration that the Link layer payload size settings excludes the L2CAP 4 byte header i.e. the size dictates the data available to the ATT layer directly. But looks like it needs to include the L2CAP header of 4 bytes. As I explained in my previous response to Alan, our L2CAP PDU/MTU is derived from ATT MTU size. Hence, in your case there will be an additional 4 bytes addition to the 2 ATT packets that are split at the ATT level i.e. the PDU generated at the L2CAP layer will be 189 and 69 bytes of size instead of 185 and 65 bytes of size I mentioned earlier. Now these 189 and 69 bytes L2CAP packets are transmitted as 9+3 = 12 LL packets (23 byte max each if your LL Tx payload size is 23). So out of these 12 packets only 2 packets will have 3+4 = 7 bytes ATT and L2CAP overhead and the remaining 10 packets will contain 23 bytes of ATT data. Though BLE spec allows for configurable L2CAP and ATT MTU sizes, our component does not provide that option as giving that option to the user may not be efficient if the user does not know the details and deriving the L2CAP MTU from ATT MTU automatically is easier and efficient.
To your questions in the next post,
1. Yes, user does not have to worry about splitting of notification data at the ATT layer. It is taken care by the stack code.
2. The max value of length field is defined by the "length" parameter you were showing in Post#3. That said, the length of data for a given notification packet is up to you i.e. you can send any length of data (within the max limit configured by you in the component characteristic). There is no limitation on this length from the spec as any length data will be split into multiple ATT packets, which is capped by the ATT MTU size. So having a larger value only will split the notification packet across multiple ATT packets. And yes, if connection interval allows for transmission of 64 kB of data, then yes you can very well transmit that much data in your notification. But remember to take into account the overheads at the ATT, L2CAP and LL layer for the calculation.
Meenakshi Sundaram R
One correction to Gyan's figure - The Negotiated MTU in figure 2 is 53 bytes and not 23 bytes.
How many notification packets Can I sent in a connection event ?
The number of notifications packets you can send per connection interval depends on multiple factors. In short, you will be able to fill the connection interval with data. The factors that impact the number of packets are below –
- Connection interval: Larger the connection interval, you will have more time to queue up more packets and transmit them over the air per interval.
- LL payload size: Larger the LL payload size, you will need to transmit lesser number of packets (lesser header overhead), lesser the number of ACKs PSoC needs to receive (basically over-the-air BW wasted receiving ACKs when it can be used to send data) from the other device. For instance, a 502 bytes LL payload will be sent as two packets with 251 LL payload size or 19 packets with 27 bytes LL payload size. With the latter, we need to send 19x10bytes as additional LL/PHY header compared to 2x10 bytes in the former case. 10 bytes per LL packet consists of 1 byte preamble, 4 bytes Access Address, 2 bytes LL Header and 3 bytes CRC. In addition, we need to receive and process 19 ACKs from the other device reducing the over-the-air time available to send more packets. Again for having LL payload size higher than 27 bytes, both devices need to support DLE.
- ATT MTU size: Unlike LL Payload size, MTU size will dictate how many bytes you can pack into one notification packet. If you are concerned with number of bytes per packet as well (throughput), then you should keep this higher to reduce overheads from ATT (3 bytes) and L2CAP (4 bytes) per notification packet.
- BLE data rate: This is straight forward - with 2 Mbps PHY, you can send twice as many bits as possible in the same time. However, this requires both the devices to support BLE 5.0 2 Mbps feature.
For example, for the below case (CE222046):
>>ATT MTU size = 498 bytes
>>LL Payload size = 251 bytes
>>Connection interval = 75 ms
>>2 Mbps LE PHY
We can transmit up to 32 packets per connection interval.
Also, note that in addition to the above factors, CPU operating frequency and the rate at which you are pushing notification from the application will affect this number as well.