当前位置:网站首页>Bluetooth development (9) -- A2DP protocol in combination with code
Bluetooth development (9) -- A2DP protocol in combination with code
2022-06-11 00:08:00 【yuanyun_ elber】
The last chapter talked about avdtp Connection process , Let's take a look at this chapter btstack Example .
because a2dp Is an audio transmission framework protocol , The specific use has involved the application layer , For example, is our device a speaker device or a sound source device , We are currently a speaker device , So let's see a2dp_sink_deom.c.
First of all, call a2dp_and_avrcp_setup Function performs a series of initializations , From the name of this function, we know , The initialization includes a2dp The protocol and avrcp agreement ,a2dp We have already talked about the basic agreement avdtp,avrcp Is based on avctp Agreed , AVCTP The protocol describes Bluetooth devices Audio/Video The format and mechanism of control signal exchange , It's an overall agreement , The specific control information is specified by the protocol ( Such as AVRCP) Realization ,AVCTP Itself only specifies control command and response The overall format of , For example, how do we pause at the speaker end 、 Play 、 stop it 、 On a 、 Next operation , You have to rely on avrcp, Another example is the volume synchronization function , Is also dependent on avrcp.
1 l2cap_init();
2 // Initialize AVDTP Sink
3 a2dp_sink_init();
4 a2dp_sink_register_packet_handler(&a2dp_sink_packet_handler);
5 a2dp_sink_register_media_handler(&handle_l2cap_media_data_packet);
6
7 avdtp_stream_endpoint_t * local_stream_endpoint = a2dp_sink_create_stream_endpoint(AVDTP_AUDIO,
8 AVDTP_CODEC_SBC, media_sbc_codec_capabilities, sizeof(media_sbc_codec_capabilities),
9 media_sbc_codec_configuration, sizeof(media_sbc_codec_configuration));
10 if (!local_stream_endpoint){
11 printf("A2DP Sink: not enough memory to create local stream endpoint\n");
12 return 1;
13 }
14 a2dp_local_seid = avdtp_local_seid(local_stream_endpoint);
15
16 // Initialize AVRCP service.
17 avrcp_init();
18 avrcp_register_packet_handler(&avrcp_packet_handler);
……Basically, they are all initialization operations , The first line initializes l2cap, The second line initializes a2dp sink, Which is for l2cap The callback function is registered with the data of
l2cap_register_service(&avdtp_packet_handler, BLUETOOTH_PSM_AVDTP, 0xffff, gap_get_security_level());
We talked about that before ,l2cap Establish logical channel , The basis for distinguishing upper layer agreements is PSM, So here PSM Be sure to fill in BLUETOOTH_PSM_AVDTP.
After all avdtp dependent l2cap Data will enter this avdtp_packet_handler To deal with .
1 void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
2 bd_addr_t event_addr;
3 uint16_t psm;
4 uint16_t local_cid;
5 uint8_t status;
6 uint16_t l2cap_mtu;
7
8 bool accept_streaming_connection;
9 bool outoing_signaling_active;
10 bool decline_connection;
11
12 avdtp_stream_endpoint_t * stream_endpoint = NULL;
13 avdtp_connection_t * connection = NULL;
14
15 switch (packet_type) {
16 case L2CAP_DATA_PACKET:
17 connection = avdtp_get_connection_for_l2cap_signaling_cid(channel);
18 if (connection){
19 handle_l2cap_data_packet_for_signaling_connection(connection, packet, size);
20 break;
21 }
22
23 stream_endpoint = avdtp_get_stream_endpoint_for_l2cap_cid(channel);
24 if (!stream_endpoint){
25 if (!connection) break;
26 handle_l2cap_data_packet_for_signaling_connection(connection, packet, size);
27 break;
28 }
29
30 if (stream_endpoint->connection){
31 if (channel == stream_endpoint->connection->l2cap_signaling_cid){
32 handle_l2cap_data_packet_for_signaling_connection(stream_endpoint->connection, packet, size);
33 break;
34 }
35 }
36
37 if (channel == stream_endpoint->l2cap_media_cid){
38 btstack_assert(avdtp_sink_handle_media_data);
39 (*avdtp_sink_handle_media_data)(avdtp_local_seid(stream_endpoint), packet, size);
40 break;
41 }
42
43 if (channel == stream_endpoint->l2cap_reporting_cid){
44 log_info("L2CAP_DATA_PACKET for reporting: NOT IMPLEMENTED");
45 } else if (channel == stream_endpoint->l2cap_recovery_cid){
46 log_info("L2CAP_DATA_PACKET for recovery: NOT IMPLEMENTED");
47 } else {
48 log_error("avdtp packet handler L2CAP_DATA_PACKET: local cid 0x%02x not found", channel);
49 }
50 break;
51
52 case HCI_EVENT_PACKET:
53 switch (hci_event_packet_get_type(packet)) {
54
55 case L2CAP_EVENT_INCOMING_CONNECTION:
56 l2cap_event_incoming_connection_get_address(packet, event_addr);
57 local_cid = l2cap_event_incoming_connection_get_local_cid(packet);
58
59 outoing_signaling_active = false;
60 accept_streaming_connection = false;
61
62 connection = avdtp_get_connection_for_bd_addr(event_addr);
……With the previous chapter , It is easy to understand the classification of various data packets here ,handle_l2cap_data_packet_for_signaling_connection Is dealing with signal channel The data of , The first 39 Yes (*avdtp_sink_handle_media_data)(avdtp_local_seid(stream_endpoint), packet, size) Is dealing with stream channel The data of , The first 52 Yes HCI_EVENT_PACKET It's not really hci event, It is btstack A kind of virtual software internal hci event, Look at number 55 Just know , This kind of hci event root According to the event type To perform different operations ,l2cap Of signal channel To establish a logical channel connection , There is also a set of state machines , There are different states , This L2CAP_EVENT_INCOMING_CONNECTION Is the state of being ready to establish a connection .
Let's go back to a2dp_and_avrcp_setup,
The first 4 That's ok a2dp_sink_register_packet_handler(&a2dp_sink_packet_handler); Except for avdtp The agreement is internal to a2dp In addition to the processing of each sub state , And registered a2dp_sink_packet_handler This application layer callback function , Mainly in a2dp When connecting sub States , Yes codec Layer needs to do some processing , for instance sbc Encoder initialization , Specific processing of audio , These all depend on the implementation of the upper layer .
The first 5 That's ok a2dp_sink_register_media_handler(&handle_l2cap_media_data_packet);
This handle_l2cap_media_data_packet Is the application layer for stream The package's handler , Before avdtp_packet_handler function , Upon receipt of l2cap Layer of avdtp When the package , Will analyze is signal channel My bag or stream channel My bag , If so stream channel If you have a bag , to glance at 39 That's ok , The callback function registered here is executed . Generally speaking , The work that should be done here is to perform the decoding of the decoder , What are you going to do after decoding ? Send it to the player to play ? It depends on the application layer .
The first 7 That's ok
avdtp_stream_endpoint_t * local_stream_endpoint = a2dp_sink_create_stream_endpoint(AVDTP_AUDIO,
AVDTP_CODEC_SBC, media_sbc_codec_capabilities, sizeof(media_sbc_codec_capabilities),
media_sbc_codec_configuration, sizeof(media_sbc_codec_configuration));Create a sep, It can also be seen that a2dp in sep It is indeed a virtual concept , Software can be created if you want to .
Take a closer look at the code , Look at this sep Distribute seid When :
static uint16_t avdtp_get_next_local_seid(void){
if (stream_endpoints_id_counter == 0xffff) {
stream_endpoints_id_counter = 1;
} else {
stream_endpoints_id_counter++;
}
return stream_endpoints_id_counter;
}You can see seid It's just a plus 1 Dynamic allocation of actions .
The first 14 That's ok
a2dp_local_seid = avdtp_local_seid(local_stream_endpoint);
to a2dp_local_seid This important variable is assigned , because avdtp Is based on seid Of , Therefore, the connection process will be frequently used in the future , It is not too much to save with a global variable .
Next avrcp A series of initialization .
Whole a2dp_and_avrcp_setup After the function is executed , The upper level services are set up ,a2dp_sink_demo.c Support to input instructions from the upper computer to execute corresponding programs , for instance , Input ‘b’, Will call a2dp_sink_establish_stream perform a2dp Connection operation , Next , Input b Give it a try , Let the state machine run .
边栏推荐
- Serial port missing in Ni Max in LabVIEW
- LabVIEW prohibits other multi-core processing applications from executing on all cores
- In the month of safety production, Huangpu launched a publicity campaign for gas safety in shops
- 【颜值检测神器】来,请拿出你们的绝活(这颜值,对得起观众么?)
- MySQL command line import and export data
- Select sort
- CSDN daily practice - find the closest element and output the subscript
- [auto reply Script] happy new year. I typed every word myself, not forwarded it~
- 【Go语言学习】——并发编程
- 【自动回复小脚本】新年快乐,每一个字都是我亲自手打的,不是转发哦~
猜你喜欢

【Pygame小游戏】趣味益智游戏 :打地鼠,看一下能打多少只呢?(附源码)

CSDN daily practice -- half search of ordered table

In the month of safety production, Huangpu launched a publicity campaign for gas safety in shops
![[pyGame] when the](/img/7e/d2cd2eb2fff2c1fb2b41f579d4f70e.png)
[pyGame] when the "coolest snake in history" arrives, fun will play it (no money for fun)

vtk. VTP download in JS

【颜值检测神器】来,请拿出你们的绝活(这颜值,对得起观众么?)

A simple understanding of B tree
![[pyGame games] interesting puzzle game: how many hamsters can you play? (source code attached)](/img/88/733cddca32491c4ac45102aa703815.jpg)
[pyGame games] interesting puzzle game: how many hamsters can you play? (source code attached)
![[untitled]](/img/7e/aab9560ef5a1b93f737a82561ec114.png)
[untitled]

Leetcode-713 subarray with product less than k
随机推荐
[turtle confessions collection] "the moon at the bottom of the sea is the moon in the sky, and the person in front of us is the sweetheart." Be happy for the rest of your life, and be safe for ever ~
MySQL命令行导入导出数据
都说验证码是爬虫中的一道坎,看我只用五行代码就突破它。
[opencv practice] this seal "artifact" is awesome, saving time and improving efficiency. It is powerful ~ (complete source code attached)
What is the workflow of dry goods MapReduce?
LabVIEW performs a serial loopback test
Multipartfile rename upload
Quick sort
[pyGame] this "groundhog" game is going to be popular (come on, come on)
【Pygame小游戏】首月破亿下载 一款高度融合了「超休闲游戏特性」的佳作~
Four ways to add names to threads in the thread pool
【Pygame小游戏】这款“打地鼠”小游戏要火了(来来来)
Why many new websites are not included by search engines
Self made app connected to onenet --- realize data monitoring and distribution control (mqtt)
B 树的简单认识
Error report of curl import postman
【Pygame合集】回忆杀-“童年游戏”,看看你中几枪?(附五款源码自取)
OpenResty安装
Method of converting file to multipartfile
【Pygame合集】滴~穿越童年游戏指南 请查收:这里面有你玩过的游戏嘛?(附五款源码自取)