forked from espressif/esp-idf
Compare commits
843 Commits
fixes
...
audio/stac
Author | SHA1 | Date | |
---|---|---|---|
606dd2b629 | |||
b1a4b24963 | |||
3dc41ff14c | |||
86e451fac0 | |||
b867ce46e9 | |||
4fb9c97d73 | |||
63c5a2b2ca | |||
7d4829bc37 | |||
d91f8b8a8b | |||
890c3422d6 | |||
eba2fdde27 | |||
70dc06b051 | |||
ff9a29503a | |||
c3bfc45c59 | |||
77c96eb7d9 | |||
5db7ecb629 | |||
4e9cfb9936 | |||
c0e2f9395e | |||
d872bcd926 | |||
2d85f00244 | |||
1cf1580619 | |||
614c43016e | |||
a91c9d6c41 | |||
d2f3e14ee6 | |||
4ee9619322 | |||
b3659a8f3c | |||
125c5fda62 | |||
59b1f8bc89 | |||
04b68f2002 | |||
51b16be912 | |||
386f39d012 | |||
95d0505456 | |||
03d0c7c62e | |||
0def2cfd1b | |||
fd31b9f56c | |||
aea40896a3 | |||
50abb981d2 | |||
60cb043e13 | |||
bfa79648cd | |||
25d1bb54f9 | |||
c440c26449 | |||
0f0e48facb | |||
4c383886dd | |||
0ff8001297 | |||
2777d636d4 | |||
1e90e1482d | |||
be8a2e850c | |||
2769dbcf1d | |||
1d4f0ad1b2 | |||
5259ec1c77 | |||
8839d0c0b3 | |||
99c0cac942 | |||
e148f41d79 | |||
c4406771fc | |||
ce3b9171dd | |||
b20d8cb16c | |||
d2ddfa5183 | |||
69fd702b1d | |||
f0206427b0 | |||
1a78389a91 | |||
1f152b5146 | |||
73153d9bf6 | |||
6903865b9c | |||
1f286c2ba9 | |||
a0226f1793 | |||
7f6c5585e2 | |||
b04afa39fe | |||
f1412a2799 | |||
1cc7856e5d | |||
c4352192a4 | |||
bea8c46ba6 | |||
7669600253 | |||
b94eec73fa | |||
0c1859a5a5 | |||
f745642042 | |||
f00a598153 | |||
03affa7058 | |||
2612854838 | |||
50ea32b86d | |||
bc881cc32d | |||
239bd70ea1 | |||
8e5bf0d500 | |||
37272e79b4 | |||
97aeb75955 | |||
2e32cdb3b2 | |||
fbfad8838e | |||
a749488f9f | |||
dcf351888e | |||
b6f67aebb3 | |||
6c18e85816 | |||
b23e569e3a | |||
a6e06d7711 | |||
a7840de9d8 | |||
1e25c373c1 | |||
1c382e94db | |||
293e02f32a | |||
9b28e15688 | |||
afde3607da | |||
34d2e45ab2 | |||
c534295225 | |||
2aa718367a | |||
b059157b74 | |||
07ad7b9845 | |||
da66192023 | |||
b8ca37175d | |||
aaf6c1a0d0 | |||
f51a055736 | |||
d3fb83421c | |||
7552f9cad9 | |||
5a522a8029 | |||
69aa2121cc | |||
8a074d7b40 | |||
9d0d5a1b24 | |||
ac8f85c3dd | |||
5b031bbf01 | |||
3b3467b884 | |||
c85876ab51 | |||
f2082ad2ea | |||
3198b4861d | |||
eb0ca8317a | |||
7e8e30c77e | |||
ef64f1d56b | |||
d3c1530745 | |||
07dbcee626 | |||
a3188d7fd9 | |||
c69c066641 | |||
7b20091c1e | |||
44985f00d3 | |||
5e6824e3ea | |||
437c66920c | |||
2e14f68dec | |||
712fe9d047 | |||
84ce40ef47 | |||
74a04aa4d7 | |||
02ddbfe989 | |||
63dfbd3f94 | |||
f7abfac202 | |||
dac1a2f363 | |||
18e2b52d6d | |||
cfb6bb7566 | |||
bc6bd5155d | |||
2f911d84db | |||
9958b41cab | |||
95ab1be706 | |||
ac533361b1 | |||
8e15c53631 | |||
a77867d302 | |||
c27b399a49 | |||
d1027a0514 | |||
9d97e30874 | |||
3263dd0705 | |||
2e5ea3a51b | |||
79db8df354 | |||
176c02a9fe | |||
552524e43a | |||
030281444c | |||
a4a15aa179 | |||
964245dcd1 | |||
d5f02c8302 | |||
61b646aa8a | |||
76717f72d6 | |||
19fd28aad8 | |||
c0ca9cd531 | |||
4610f058e8 | |||
fa0348b512 | |||
c2dac74cc5 | |||
00d6b12671 | |||
b48bdefe54 | |||
de662d5e11 | |||
a80cf2dc69 | |||
ca51072461 | |||
1fb82085b9 | |||
1167a5c2f9 | |||
49cb9972de | |||
cef73cd232 | |||
f8fbb2be5c | |||
c1374ff769 | |||
d396624a60 | |||
4ede6c8c15 | |||
0c5d5c9dd6 | |||
1a89bfaef3 | |||
be3be59feb | |||
679b55da62 | |||
e9b87fda73 | |||
20f1838563 | |||
f3e107ada9 | |||
fb33c67532 | |||
99c6aad0a6 | |||
1ff2d61ddf | |||
bb2c0475eb | |||
b5ab64b4d9 | |||
5c2e8930f9 | |||
f34f7bade6 | |||
4790b63e2b | |||
407b9b0a68 | |||
bad97eb1f9 | |||
b6bcdad3db | |||
b6cb812499 | |||
f41b9d6d64 | |||
576dcffec1 | |||
8a7c8b2d60 | |||
a58c272b8c | |||
dfbdddecc1 | |||
46a23d9f8a | |||
36918e179c | |||
3d49e49210 | |||
5f04a02bb1 | |||
3b935e3fad | |||
c4b21e9d47 | |||
cb2cb8fea7 | |||
787ee04a5d | |||
db3fa3a100 | |||
3222dfef0e | |||
d33caa02c8 | |||
5ef656af35 | |||
5a9a5bed56 | |||
f1c222f254 | |||
11739fd459 | |||
a172605af4 | |||
f490b4ddfe | |||
712df748da | |||
918472f641 | |||
473db9c14b | |||
a7a20f2e17 | |||
7941e591d3 | |||
09c895f0f9 | |||
48e6aa916a | |||
67f1cedbed | |||
0b76a8547f | |||
dfd5e9da02 | |||
cb51f8c827 | |||
5a09cf600e | |||
92e111eb56 | |||
7cc89bf83a | |||
6d67dc7e7c | |||
a0d85de8af | |||
285f9672ae | |||
e1a33408c4 | |||
1921a327c5 | |||
50b57516e8 | |||
1b3f7d4dfe | |||
1102d2b1d2 | |||
5a86c5b3a7 | |||
a94ec95d6b | |||
5eee07f944 | |||
e75cf5d44e | |||
b81de503cd | |||
c38d6a1dc5 | |||
22b196c4bd | |||
3d59dd404a | |||
e479b79462 | |||
1ea761ecee | |||
8e6a52008c | |||
1413b84a8a | |||
afb96542dd | |||
125e21c3e0 | |||
3cbd8ce32e | |||
1a82857251 | |||
818ea3e3ce | |||
be10cc6251 | |||
8114c51da0 | |||
1a0d6699be | |||
0b74249a01 | |||
c5d6efa59d | |||
d9a91b835a | |||
0d31937a7d | |||
04e4f6fbf1 | |||
ea6033f0dc | |||
98e618f75e | |||
8188138c35 | |||
1739654de4 | |||
c8e5433da3 | |||
896ba3df56 | |||
f5d74b1106 | |||
99951fbcf8 | |||
3b704d2f3a | |||
143d26aa49 | |||
e1eabe6f6a | |||
0407ab426e | |||
bcbc4a9599 | |||
50737018cc | |||
19913cec43 | |||
bf80d8211e | |||
7d26cf16cc | |||
86c4d8737e | |||
8ffe0ff357 | |||
faf96bd108 | |||
8225cc75df | |||
0d6cae963b | |||
3a94beeb5b | |||
29f6537faf | |||
160f435e4d | |||
51d2d9041c | |||
5a6ac7f32f | |||
0f3f7d984a | |||
efdddbb253 | |||
ce9c7e4f79 | |||
66c0699411 | |||
646c851824 | |||
51a49a861a | |||
9b34085053 | |||
0f7dc2ec02 | |||
2e341f003a | |||
92c8fd24bb | |||
2aa255c875 | |||
5a3af62f44 | |||
bc1d87a846 | |||
71d0d08c4e | |||
0caa96584c | |||
5d4cd1269b | |||
6e1eb21bae | |||
0d1c490a7c | |||
dbd2cd2f7a | |||
34b14ddf5b | |||
9592346090 | |||
696d6867b4 | |||
f52b877199 | |||
a179125fd3 | |||
1dd8411e04 | |||
e6a71fe29c | |||
efe8490623 | |||
a29f30b5d3 | |||
c570e253fe | |||
7b7f597cb4 | |||
3a5249aea9 | |||
28c19e623f | |||
cabe66195c | |||
f0855c85ad | |||
569334267f | |||
9911823658 | |||
b90f32bffb | |||
20db198401 | |||
bf877941c4 | |||
f9a51fc784 | |||
aa09462685 | |||
365c336a98 | |||
95c768165f | |||
12f2ae47c6 | |||
fc6b44f500 | |||
0042aaafa1 | |||
adcf95dc9f | |||
e5ee10e89f | |||
c9f1cb2f4c | |||
a0c8de077b | |||
9e62340897 | |||
f451efd1d0 | |||
f490eda68c | |||
f2dfb0cf70 | |||
03aef3c087 | |||
9a6526554d | |||
8d4e1c0616 | |||
4e27cbb89f | |||
b51f89d827 | |||
e30c7a9b27 | |||
622842a983 | |||
2bcb02795e | |||
fd22441494 | |||
8f048ffddc | |||
3e3ce3da81 | |||
0a0f2caa1d | |||
2441858835 | |||
3545b58986 | |||
9f10f684d3 | |||
5d750fb8ce | |||
6f8f39a2e5 | |||
6c60d3ef29 | |||
ecaf8a7a61 | |||
7ef60d2c2b | |||
e524b4b1fd | |||
40cce58a52 | |||
c50d44e66e | |||
07a3eca372 | |||
626684578a | |||
5ba3b8c587 | |||
c286416762 | |||
fd1c127d34 | |||
b5aa65c136 | |||
61486620c7 | |||
396f477972 | |||
2165154c04 | |||
46e918cfa1 | |||
051d2fbdd5 | |||
41f91d3ef6 | |||
ffce53449b | |||
7314f44b13 | |||
4936110591 | |||
af9472bb7a | |||
d190c53ec8 | |||
26c6583bab | |||
b3720f80c7 | |||
8147d48ec8 | |||
8466b8d6d3 | |||
6e47143dc5 | |||
10c882764e | |||
4559434d5a | |||
25f837a148 | |||
53e295a616 | |||
156ffa412e | |||
7726102bfb | |||
8c74a4a989 | |||
48bd2152d0 | |||
7db01c954e | |||
d90868b42e | |||
7d60a78b31 | |||
23a8cbb247 | |||
f3fd849da1 | |||
7a2bd81870 | |||
2b6f7697b9 | |||
610b5579a7 | |||
15a9d4f4d3 | |||
65e9af5114 | |||
579cbd8229 | |||
2b84f3e6c4 | |||
10732770d3 | |||
f2c10cb443 | |||
c67b02db52 | |||
dc4c16f475 | |||
3f2bf11751 | |||
b1f264be69 | |||
d14f2c5fca | |||
35898c704f | |||
3564d6728c | |||
c5b1b57b09 | |||
fbd38ad19a | |||
2d5ee438fa | |||
46b12a560a | |||
f19bc120f1 | |||
9c87165bc8 | |||
6514820311 | |||
0af56e2815 | |||
a06b88d7f6 | |||
5e292d50ad | |||
321ecc94d3 | |||
f0f30f9d0c | |||
9ea662a4ba | |||
285925a43b | |||
9e51598ee7 | |||
5e321badd5 | |||
e943181f72 | |||
2dc98f3be8 | |||
3badf6ebd9 | |||
9a1b11c813 | |||
b933d851bf | |||
204b58a34c | |||
88c9506469 | |||
202664bac0 | |||
0500fa2344 | |||
fefc65f885 | |||
d7e257d8ba | |||
ca3df7de7f | |||
8849d6acfa | |||
e8e5410cef | |||
cc68a512d2 | |||
3a291da164 | |||
1173b4f51a | |||
f6d0a913de | |||
149171f119 | |||
94091761c4 | |||
262f3774e8 | |||
30f93365b5 | |||
e0748cdaf2 | |||
6cd6423092 | |||
38b1c93764 | |||
9f3f7009c0 | |||
69d8fab619 | |||
cc50d88a89 | |||
4aea2dce15 | |||
54c7379060 | |||
b12c2646fa | |||
39ac9cb44b | |||
64fbce50c2 | |||
d1e8b4473d | |||
38e2d3bec6 | |||
2192de7111 | |||
c7f4fb56d8 | |||
3201333f06 | |||
85a89db863 | |||
21a8a9a170 | |||
0ce9d2662d | |||
d4e13c011e | |||
f380d72825 | |||
6ccb4cf5b7 | |||
f8e24754d1 | |||
86975b7e8f | |||
c2bb7d7cd6 | |||
3451f3526f | |||
cc3ba7186f | |||
7d28c02fd5 | |||
1aa2f36dec | |||
3becdd7850 | |||
cfd7a5b84e | |||
cf2062f1d7 | |||
a742bad8f3 | |||
ef11260310 | |||
7b39d5e5c5 | |||
d5b0b36758 | |||
0a609be968 | |||
8fa409a0b5 | |||
2e9904556f | |||
8e32eb78a4 | |||
a3adc6c202 | |||
148a269808 | |||
7b3bedbc10 | |||
5b11428f00 | |||
4cd7fd89f5 | |||
ceb56a7a72 | |||
ebfa74310c | |||
b482ba117d | |||
07735424a2 | |||
f2f5a237c0 | |||
3be1c70d46 | |||
beb34b5390 | |||
3991084777 | |||
088439c634 | |||
dbd05d8986 | |||
02068cf328 | |||
7c5dd19c83 | |||
a6fb161309 | |||
0929dbbc9b | |||
4c27f9ced8 | |||
b800dfe6f1 | |||
caa1ef0cb6 | |||
97e7c14f4e | |||
c157c696e7 | |||
d900cb5a35 | |||
e8a4e70c42 | |||
4cb729283d | |||
6a3e160aaf | |||
70ecb7ec94 | |||
21e2c417e8 | |||
3ca82d5923 | |||
7af04d857f | |||
e070e1886f | |||
6da2bec1e8 | |||
73345bae44 | |||
b9f2531e8c | |||
b6e6a4f4b2 | |||
9420c5398f | |||
31c8be0738 | |||
cbc438c807 | |||
2d26163019 | |||
ff2624f09c | |||
11d141e87d | |||
91f29bef17 | |||
8ed62223cd | |||
de7a50dca0 | |||
a9eac4a124 | |||
3e27184c38 | |||
5758b739f1 | |||
2d7124e319 | |||
232408981d | |||
9821e533db | |||
6d8990f39b | |||
83a9a4dc70 | |||
630ffde6bb | |||
6af30250a8 | |||
30d2f13358 | |||
d7569b5862 | |||
db9979701a | |||
dca5ed2263 | |||
0ef3af367d | |||
9afe47425b | |||
f5d33fa889 | |||
29cef5a9cc | |||
40171d7307 | |||
e64bae3a0c | |||
a71fad46d4 | |||
2c9acce0ff | |||
8e58b31a69 | |||
bf152907a4 | |||
47ca5d53df | |||
c1fe8ceb83 | |||
db38c37cf7 | |||
71ce87c79e | |||
611c300a92 | |||
b7eb82d191 | |||
933674301f | |||
3b2e231ae3 | |||
881cd4310c | |||
13e6e9f592 | |||
cfc73a6de7 | |||
62e359a4e1 | |||
ab4024c84e | |||
f4ee20165e | |||
e443467f37 | |||
a6f990ffb9 | |||
43561a40d2 | |||
55f5c2e08d | |||
e4418f4f92 | |||
968728bf95 | |||
2073a6e738 | |||
95b72a96f8 | |||
2617dee69f | |||
f94db7bba7 | |||
f7f02c9a43 | |||
52f0b86965 | |||
12bbe0f39b | |||
536b2d8a65 | |||
f5ab51c9b7 | |||
8a5c712730 | |||
2287c28b41 | |||
129ac11c31 | |||
166918e802 | |||
4b028cca86 | |||
a9d266b921 | |||
dc9c2f3b60 | |||
ae1389afd9 | |||
92f1d7ae39 | |||
f73c972280 | |||
378a5b159a | |||
2ef218059b | |||
28a8349fb8 | |||
4acc941c3d | |||
4ae01f0c9d | |||
2c4e0cf878 | |||
4b739249c2 | |||
b3f4755ac2 | |||
0e022b7db9 | |||
9185c370dc | |||
b62182d75a | |||
890a341db4 | |||
04815c2d27 | |||
0af6d8ffe3 | |||
43b2563f5a | |||
16586524e9 | |||
f60acb2196 | |||
1d2a9efa55 | |||
5ab4a9da51 | |||
b63be2e08e | |||
6cf4e14671 | |||
39f7d1ad0b | |||
d3a29c2d08 | |||
31a8a488f0 | |||
b908d4325b | |||
54c148d289 | |||
60b937b5ca | |||
b816edac3c | |||
2ee0f98d05 | |||
f83296e448 | |||
09515bdfde | |||
081b623a34 | |||
871e95087e | |||
a3b3f9ae2d | |||
fb6f343ce5 | |||
e1069de9aa | |||
a219e9f819 | |||
8f8113f5cd | |||
cf3647fe40 | |||
06651c0951 | |||
d54fadef41 | |||
3b4353da5d | |||
261c5bf6a8 | |||
6132d7bce3 | |||
1db04ae574 | |||
6d4adb46f3 | |||
e681f449bc | |||
f3725a7821 | |||
34f6773471 | |||
d0e7fd4369 | |||
13a3edee8a | |||
56866567ae | |||
bc83d470e3 | |||
a298d32d65 | |||
172a216edb | |||
d5923f0e2e | |||
cd9249970f | |||
676a27c7cf | |||
33121c3311 | |||
38509b2b95 | |||
e821c22a8c | |||
8c363321db | |||
ce279988c3 | |||
7200b8bf77 | |||
7e5cd986a9 | |||
fa1e983028 | |||
71e344da20 | |||
620bba3a66 | |||
8f7f32c0a5 | |||
3cbbc3bbac | |||
5c42c831f5 | |||
8c57aa0242 | |||
0d5609ba92 | |||
e209307297 | |||
4ac347b295 | |||
fc3aa765cf | |||
31c94b25c5 | |||
5b8d1c9da3 | |||
7f784c84d2 | |||
532c8847c7 | |||
6dc31101ce | |||
c763b8089c | |||
7d9330d1af | |||
618aa6a3a4 | |||
762bf705bb | |||
5988e77a3a | |||
26e7f3fde6 | |||
ba2ff1876f | |||
0757e019f4 | |||
c68390f922 | |||
8e3a1876cb | |||
cc8652d8d2 | |||
3cd8538f53 | |||
0033b31442 | |||
56afb3bd1c | |||
e622ee0f41 | |||
2d50291b05 | |||
c9b1e1df60 | |||
9a72c11e6e | |||
39dbe7daa8 | |||
554a28e8a1 | |||
7a2885885c | |||
d154723a84 | |||
16918e400e | |||
510f726935 | |||
3295ed0995 | |||
924895f832 | |||
403268a13a | |||
6b3da6b188 | |||
93b4c71595 | |||
d6badc53eb | |||
cb7aaae35e | |||
18533e132a | |||
7a7128c7a3 | |||
208d87742c | |||
dd76df7aee | |||
deba35d2e5 | |||
9fdc36ed57 | |||
184f2f0fd6 | |||
b36f4aa813 | |||
4b6ac69c04 | |||
c7d73901d0 | |||
76cc8c1c0c | |||
38a2be75a9 | |||
c85fc16282 | |||
ab888394c3 | |||
b8a2b77f70 | |||
ef8341b5bc | |||
c31217d193 | |||
16a56e2e7a | |||
1b3c6fb1a1 | |||
f7177095cf | |||
0e89436769 | |||
40067fb50f | |||
167c21b987 | |||
a2f00b0adf | |||
feecafeb0e | |||
7bbbf2d4b3 | |||
21fb5085bd | |||
82a80005b9 | |||
b354c11db7 | |||
e5672e5d7f | |||
3e972a3ffe | |||
8bd09fb0a5 | |||
e90c90d1f6 | |||
2f72645320 | |||
4be28a798f | |||
eed94b87e2 | |||
a218d4b925 | |||
015f523939 | |||
7196573605 | |||
4a698ffb75 | |||
3368783bf0 | |||
7e0e514127 | |||
541c267af3 | |||
bbfe9f4efa | |||
9bd172356e | |||
1b8dd9f173 | |||
dd33cec716 | |||
1cb29ac446 | |||
7b368fc211 | |||
d6ceb4a31a | |||
d5f9eb65e9 | |||
ce3d20dcd2 | |||
1dc461ba80 | |||
f03382b0ff | |||
2ecd007974 | |||
c6e32c1a61 | |||
2f26bb2e65 | |||
3be2b430d1 | |||
ff01bcfd88 | |||
8442255ccc | |||
c92e677da4 | |||
6d2faf4172 | |||
826146e985 | |||
2faf3c9c34 | |||
3fedc3eb28 | |||
4148beca50 | |||
c71b38c467 | |||
8e2b189252 | |||
dca83700f2 | |||
37e131f76b | |||
c76f00373f | |||
24a713b3c4 | |||
88fe438524 | |||
7f1fd0b8d3 | |||
2c91bc7a50 | |||
3cec8d0122 | |||
6381817006 | |||
14a6b33d5e | |||
6505f82a80 | |||
c05a0ae6c3 | |||
2a9555f5dd | |||
f72df315f7 | |||
e7a263938b | |||
3ed0f8e113 | |||
7e1ccb56a7 | |||
50a0b00afa | |||
be8f34065d | |||
d0eab0f3ee | |||
7a530be302 | |||
b692bda09b | |||
e4a83f856e | |||
e25152a031 | |||
885aec7aba | |||
0c2419d798 | |||
a3a58546bc | |||
2f2f0fbcbd | |||
ec4c75b692 | |||
90ddbaac16 | |||
0176f912b6 | |||
615376d14a | |||
fe516fb7c2 | |||
f5c805160b | |||
00e3f7f6b6 | |||
d6b316c375 | |||
bc04b1f53b | |||
50ceb45e6f | |||
646c7a7515 | |||
cc7e91e1a3 | |||
725f0a7545 | |||
bd0984226e | |||
f330bb50b2 | |||
4f1e27fa76 | |||
16755a2c51 | |||
936b99d756 | |||
c88cc4950e | |||
54e5e440b1 | |||
e8bcda3512 | |||
35a30072f4 | |||
edb0374b9d | |||
78539acdd1 | |||
a1546e0714 | |||
8ff6afd29f |
2
.flake8
2
.flake8
@ -156,10 +156,10 @@ exclude =
|
||||
components/protocomm/python/sec0_pb2.py,
|
||||
components/protocomm/python/sec1_pb2.py,
|
||||
components/protocomm/python/session_pb2.py,
|
||||
components/wifi_provisioning/python/wifi_scan_pb2.py,
|
||||
components/wifi_provisioning/python/wifi_config_pb2.py,
|
||||
components/wifi_provisioning/python/wifi_constants_pb2.py,
|
||||
examples/provisioning/custom_config/components/custom_provisioning/python/custom_config_pb2.py,
|
||||
# temporary list (should be empty)
|
||||
components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py,
|
||||
tools/esp_app_trace/pylibelf,
|
||||
tools/mass_mfg/mfg_gen.py,
|
||||
|
1136
.gitlab-ci.yml
1136
.gitlab-ci.yml
File diff suppressed because it is too large
Load Diff
4
.gitmodules
vendored
4
.gitmodules
vendored
@ -69,3 +69,7 @@
|
||||
[submodule "examples/build_system/cmake/import_lib/main/lib/tinyxml2"]
|
||||
path = examples/build_system/cmake/import_lib/main/lib/tinyxml2
|
||||
url = https://github.com/leethomason/tinyxml2
|
||||
|
||||
[submodule "components/nimble/nimble"]
|
||||
path = components/nimble/nimble
|
||||
url = https://github.com/espressif/esp-nimble.git
|
||||
|
21
.readthedocs.yml
Normal file
21
.readthedocs.yml
Normal file
@ -0,0 +1,21 @@
|
||||
# .readthedocs.yml
|
||||
# Read the Docs configuration file
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
# Required
|
||||
version: 2
|
||||
|
||||
# Optionally build your docs in additional formats such as PDF and ePub
|
||||
formats:
|
||||
- pdf
|
||||
|
||||
# Optionally set the version of Python and requirements required to build your docs
|
||||
python:
|
||||
version: 2.7
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
||||
|
||||
# We need to list all the submodules included in documentation build by Doxygen
|
||||
submodules:
|
||||
include:
|
||||
- components/mqtt/esp-mqtt
|
118
CMakeLists.txt
118
CMakeLists.txt
@ -1,108 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(esp-idf C CXX ASM)
|
||||
|
||||
if(NOT IDF_PATH)
|
||||
set(IDF_PATH ${CMAKE_CURRENT_LIST_DIR})
|
||||
endif()
|
||||
|
||||
include(tools/cmake/idf_functions.cmake)
|
||||
|
||||
#
|
||||
# Set variables that control the build configuration and the build itself
|
||||
#
|
||||
idf_set_variables()
|
||||
|
||||
kconfig_set_variables()
|
||||
|
||||
#
|
||||
# Generate a component dependencies file, enumerating components to be included in the build
|
||||
# as well as their dependencies.
|
||||
#
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}"
|
||||
-D "COMPONENTS=${IDF_COMPONENTS}"
|
||||
-D "COMPONENT_REQUIRES_COMMON=${IDF_COMPONENT_REQUIRES_COMMON}"
|
||||
-D "EXCLUDE_COMPONENTS=${IDF_EXCLUDE_COMPONENTS}"
|
||||
-D "TEST_COMPONENTS=${IDF_TEST_COMPONENTS}"
|
||||
-D "TEST_EXCLUDE_COMPONENTS=${IDF_TEST_EXCLUDE_COMPONENTS}"
|
||||
-D "BUILD_TESTS=${IDF_BUILD_TESTS}"
|
||||
-D "DEPENDENCIES_FILE=${CMAKE_BINARY_DIR}/component_depends.cmake"
|
||||
-D "COMPONENT_DIRS=${IDF_COMPONENT_DIRS}"
|
||||
-D "BOOTLOADER_BUILD=${BOOTLOADER_BUILD}"
|
||||
-D "IDF_TARGET=${IDF_TARGET}"
|
||||
-D "IDF_PATH=${IDF_PATH}"
|
||||
-D "DEBUG=${DEBUG}"
|
||||
-P "${IDF_PATH}/tools/cmake/scripts/expand_requirements.cmake"
|
||||
WORKING_DIRECTORY "${PROJECT_PATH}"
|
||||
RESULT_VARIABLE expand_requirements_result)
|
||||
|
||||
if(expand_requirements_result)
|
||||
message(FATAL_ERROR "Failed to expand component requirements")
|
||||
endif()
|
||||
|
||||
include("${CMAKE_BINARY_DIR}/component_depends.cmake")
|
||||
|
||||
#
|
||||
# We now have the following component-related variables:
|
||||
#
|
||||
# IDF_COMPONENTS is the list of initial components set by the user
|
||||
# (or empty to include all components in the build).
|
||||
# BUILD_COMPONENTS is the list of components to include in the build.
|
||||
# BUILD_COMPONENT_PATHS is the paths to all of these components, obtained from the component dependencies file.
|
||||
#
|
||||
# Print the list of found components and test components
|
||||
#
|
||||
string(REPLACE ";" " " BUILD_COMPONENTS_SPACES "${BUILD_COMPONENTS}")
|
||||
message(STATUS "Component names: ${BUILD_COMPONENTS_SPACES}")
|
||||
unset(BUILD_COMPONENTS_SPACES)
|
||||
message(STATUS "Component paths: ${BUILD_COMPONENT_PATHS}")
|
||||
|
||||
# Print list of test components
|
||||
if(TESTS_ALL EQUAL 1 OR TEST_COMPONENTS)
|
||||
string(REPLACE ";" " " BUILD_TEST_COMPONENTS_SPACES "${BUILD_TEST_COMPONENTS}")
|
||||
message(STATUS "Test component names: ${BUILD_TEST_COMPONENTS_SPACES}")
|
||||
unset(BUILD_TEST_COMPONENTS_SPACES)
|
||||
message(STATUS "Test component paths: ${BUILD_TEST_COMPONENT_PATHS}")
|
||||
endif()
|
||||
|
||||
# Generate project configuration
|
||||
kconfig_process_config()
|
||||
|
||||
# Include sdkconfig.cmake so rest of the build knows the configuration
|
||||
include(${SDKCONFIG_CMAKE})
|
||||
|
||||
# Verify the environment is configured correctly
|
||||
idf_verify_environment()
|
||||
|
||||
# Check git revision (may trigger reruns of cmake)
|
||||
## sets IDF_VER to IDF git revision
|
||||
idf_get_git_revision()
|
||||
|
||||
# Check that the targets set in cache, sdkconfig, and in environment all match
|
||||
idf_check_config_target()
|
||||
|
||||
## get PROJECT_VER
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
app_get_revision("${CMAKE_SOURCE_DIR}")
|
||||
endif()
|
||||
|
||||
# Add some idf-wide definitions
|
||||
idf_set_global_compile_options()
|
||||
|
||||
# generate compile_commands.json (needs to come after project)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
|
||||
|
||||
#
|
||||
# Setup variables for linker script generation
|
||||
#
|
||||
ldgen_set_variables()
|
||||
|
||||
# Include any top-level project_include.cmake files from components
|
||||
foreach(component ${BUILD_COMPONENT_PATHS})
|
||||
set(COMPONENT_PATH "${component}")
|
||||
include_if_exists("${component}/project_include.cmake")
|
||||
unset(COMPONENT_PATH)
|
||||
endforeach()
|
||||
|
||||
#
|
||||
# Add each component to the build as a library
|
||||
#
|
||||
@ -144,18 +42,4 @@ foreach(component ${BUILD_COMPONENTS})
|
||||
add_component_dependencies(${component_target} ${dep_target} PRIVATE)
|
||||
endforeach()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(IDF_BUILD_ARTIFACTS)
|
||||
# Write project description JSON file
|
||||
make_json_list("${BUILD_COMPONENTS}" build_components_json)
|
||||
make_json_list("${BUILD_COMPONENT_PATHS}" build_component_paths_json)
|
||||
configure_file("${IDF_PATH}/tools/cmake/project_description.json.in"
|
||||
"${IDF_BUILD_ARTIFACTS_DIR}/project_description.json")
|
||||
unset(build_components_json)
|
||||
unset(build_component_paths_json)
|
||||
endif()
|
||||
|
||||
set(BUILD_COMPONENTS ${BUILD_COMPONENTS} PARENT_SCOPE)
|
||||
|
||||
ldgen_add_dependencies()
|
||||
endforeach()
|
4
Kconfig
4
Kconfig
@ -23,6 +23,10 @@ mainmenu "Espressif IoT Development Framework Configuration"
|
||||
default "IDF_TARGET_NOT_SET" if IDF_TARGET_ENV=""
|
||||
default IDF_TARGET_ENV
|
||||
|
||||
config IDF_FIRMWARE_CHIP_ID
|
||||
hex
|
||||
default 0x0000 if IDF_TARGET="esp32"
|
||||
default 0xFFFF
|
||||
|
||||
menu "SDK tool configuration"
|
||||
config TOOLPREFIX
|
||||
|
66
SUPPORT_POLICY.md
Normal file
66
SUPPORT_POLICY.md
Normal file
@ -0,0 +1,66 @@
|
||||
The latest support policy for ESP-IDF can be found at [https://github.com/espressif/esp-idf/blob/master/SUPPORT_POLICY.md](https://github.com/espressif/esp-idf/blob/master/SUPPORT_POLICY.md)
|
||||
|
||||
Support Period Policy
|
||||
=====================
|
||||
|
||||
Each ESP-IDF major and minor release (V4.0, V4.1, etc) is supported for
|
||||
18 months after the initial stable release date.
|
||||
|
||||
Supported means that the ESP-IDF team will continue to apply bug fixes,
|
||||
security fixes, etc to the release branch on GitHub, and periodically
|
||||
make new bugfix releases as needed.
|
||||
|
||||
Users are encouraged to upgrade to a newer ESP-IDF release before the
|
||||
support period finishes and the release becomes End of Life (EOL). It is
|
||||
our policy to not continue fixing bugs in End of Life releases.
|
||||
|
||||
Pre-release versions (betas, previews, `-rc` and `-dev` versions, etc)
|
||||
are not covered by any support period. Sometimes a particular feature is
|
||||
marked as \"Preview\" in a release, which means it is also not covered
|
||||
by the support period.
|
||||
|
||||
The ESP-IDF Programming Guide has information about the
|
||||
[different versions of ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/latest/versions.html)
|
||||
(major, minor, bugfix, etc).
|
||||
|
||||
Long Term Support releases
|
||||
--------------------------
|
||||
|
||||
Some releases (starting with ESP-IDF V3.3) are designated Long Term
|
||||
Support (LTS). LTS releases are supported for 30 months (2.5 years)
|
||||
after the initial stable release date.
|
||||
|
||||
A new LTS release will be made at least every 18 months. This means
|
||||
there will always be a period of at least 12 months to upgrade from the
|
||||
previous LTS release to the following LTS release.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
ESP-IDF V3.3 was released in September 2019 and is a Long Term Support
|
||||
(LTS) release, meaning it will be supported for 30 months until February
|
||||
2022.
|
||||
|
||||
- The first V3.3 release was `v3.3` in September 2019.
|
||||
- The ESP-IDF team continues to backport bug fixes, security fixes,
|
||||
etc to the release branch `release/v3.3`.
|
||||
- Periodically stable bugfix releases are created from the release
|
||||
branch. For example `v3.3.1`, `v3.3.2`, etc. Users are encouraged to
|
||||
always update to the latest bugfix release.
|
||||
- V3.3 bugfix releases continue until February 2022, when all V3.3.x
|
||||
releases become End of Life.
|
||||
|
||||
Existing Releases
|
||||
-----------------
|
||||
|
||||
ESP-IDF release V3.3 and all newer releases will follow this support
|
||||
period policy. The support period for each release will be announced
|
||||
when the release is made.
|
||||
|
||||
For releases made before the support period policy was announced,
|
||||
the following support periods apply:
|
||||
|
||||
- ESP-IDF V3.1.x and V3.2.x will both be supported until October 2020.
|
||||
- ESP-IDF V3.0.9 (planned for October 2019) will be the last V3.0
|
||||
bugfix release. ESP-IDF V3.0.x is End of Life from October 2019.
|
||||
- ESP-IDF versions before V3.0 are already End of Life.
|
@ -8,9 +8,16 @@ PARTTOOL_PY := $(PYTHON) $(IDF_PATH)/components/partition_table/parttool.py
|
||||
# Generate blank partition file
|
||||
BLANK_OTA_DATA_FILE = $(BUILD_DIR_BASE)/ota_data_initial.bin
|
||||
|
||||
$(BLANK_OTA_DATA_FILE): partition_table_get_info $(PARTITION_TABLE_BIN) | check_python_dependencies
|
||||
# Copy PARTITION_TABLE_CSV_PATH definition here from $IDF_PATH/components/partition_table/Makefile.projbuild
|
||||
# to avoid undefined variables warning for PARTITION_TABLE_CSV_PATH
|
||||
ifndef PARTITION_TABLE_CSV_PATH
|
||||
PARTITION_TABLE_ROOT := $(call dequote,$(if $(CONFIG_PARTITION_TABLE_CUSTOM),$(PROJECT_PATH),$(IDF_PATH)/components/partition_table))
|
||||
PARTITION_TABLE_CSV_PATH := $(call dequote,$(abspath $(PARTITION_TABLE_ROOT)/$(call dequote,$(CONFIG_PARTITION_TABLE_FILENAME))))
|
||||
endif
|
||||
|
||||
$(BLANK_OTA_DATA_FILE): partition_table_get_info $(PARTITION_TABLE_CSV_PATH) | check_python_dependencies
|
||||
$(shell if [ "$(OTA_DATA_OFFSET)" != "" ] && [ "$(OTA_DATA_SIZE)" != "" ]; then \
|
||||
$(PARTTOOL_PY) --partition-type data --partition-subtype ota --partition-table-file $(PARTITION_TABLE_BIN) \
|
||||
$(PARTTOOL_PY) --partition-type data --partition-subtype ota --partition-table-file $(PARTITION_TABLE_CSV_PATH) \
|
||||
-q generate_blank_partition_file --output $(BLANK_OTA_DATA_FILE); \
|
||||
fi; )
|
||||
$(eval BLANK_OTA_DATA_FILE = $(shell if [ "$(OTA_DATA_OFFSET)" != "" ] && [ "$(OTA_DATA_SIZE)" != "" ]; then \
|
||||
@ -22,11 +29,11 @@ blank_ota_data: $(BLANK_OTA_DATA_FILE)
|
||||
# expand to empty values.
|
||||
ESPTOOL_ALL_FLASH_ARGS += $(OTA_DATA_OFFSET) $(BLANK_OTA_DATA_FILE)
|
||||
|
||||
erase_otadata: $(PARTITION_TABLE_BIN) partition_table_get_info | check_python_dependencies
|
||||
$(OTATOOL_PY) --partition-table-file $(PARTITION_TABLE_BIN) erase_otadata
|
||||
erase_otadata: $(PARTITION_TABLE_CSV_PATH) partition_table_get_info | check_python_dependencies
|
||||
$(OTATOOL_PY) --partition-table-file $(PARTITION_TABLE_CSV_PATH) erase_otadata
|
||||
|
||||
read_otadata: $(PARTITION_TABLE_BIN) partition_table_get_info | check_python_dependencies
|
||||
$(OTATOOL_PY) --partition-table-file $(PARTITION_TABLE_BIN) read_otadata
|
||||
read_otadata: $(PARTITION_TABLE_CSV_PATH) partition_table_get_info | check_python_dependencies
|
||||
$(OTATOOL_PY) --partition-table-file $(PARTITION_TABLE_CSV_PATH) read_otadata
|
||||
|
||||
erase_ota: erase_otadata
|
||||
@echo "WARNING: erase_ota is deprecated. Use erase_otadata instead."
|
||||
|
@ -43,7 +43,7 @@
|
||||
#include "esp_efuse.h"
|
||||
|
||||
|
||||
#define SUB_TYPE_ID(i) (i & 0x0F)
|
||||
#define SUB_TYPE_ID(i) (i & 0x0F)
|
||||
|
||||
typedef struct ota_ops_entry_ {
|
||||
uint32_t handle;
|
||||
@ -208,7 +208,7 @@ esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size)
|
||||
// must erase the partition before writing to it
|
||||
assert(it->erased_size > 0 && "must erase the partition before writing to it");
|
||||
if (it->wrote_size == 0 && it->partial_bytes == 0 && size > 0 && data_bytes[0] != ESP_IMAGE_HEADER_MAGIC) {
|
||||
ESP_LOGE(TAG, "OTA image has invalid magic byte (expected 0xE9, saw 0x%02x", data_bytes[0]);
|
||||
ESP_LOGE(TAG, "OTA image has invalid magic byte (expected 0xE9, saw 0x%02x)", data_bytes[0]);
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
}
|
||||
|
||||
|
@ -295,7 +295,7 @@ static void test_flow1(void)
|
||||
// 3 Stage: run OTA0 -> check it -> copy OTA0 to OTA1 -> reboot --//--
|
||||
// 4 Stage: run OTA1 -> check it -> copy OTA1 to OTA0 -> reboot --//--
|
||||
// 5 Stage: run OTA0 -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, OTA1, OTA0", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow1, test_flow1, test_flow1, test_flow1);
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, OTA1, OTA0", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow1, test_flow1, test_flow1, test_flow1);
|
||||
|
||||
static void test_flow2(void)
|
||||
{
|
||||
@ -332,7 +332,7 @@ static void test_flow2(void)
|
||||
// 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
|
||||
// 3 Stage: run OTA0 -> check it -> corrupt ota data -> reboot --//--
|
||||
// 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, corrupt ota_sec1, factory", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow2, test_flow2, test_flow2);
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, corrupt ota_sec1, factory", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow2, test_flow2, test_flow2);
|
||||
|
||||
static void test_flow3(void)
|
||||
{
|
||||
@ -376,7 +376,7 @@ static void test_flow3(void)
|
||||
// 3 Stage: run OTA0 -> check it -> copy OTA0 to OTA1 -> reboot --//--
|
||||
// 3 Stage: run OTA1 -> check it -> corrupt ota sector2 -> reboot --//--
|
||||
// 4 Stage: run OTA0 -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, OTA1, currupt ota_sec2, OTA0", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow3, test_flow3, test_flow3, test_flow3);
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, OTA1, currupt ota_sec2, OTA0", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow3, test_flow3, test_flow3, test_flow3);
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_FACTORY_RESET
|
||||
#define STORAGE_NAMESPACE "update_ota"
|
||||
@ -443,7 +443,7 @@ static void test_flow4(void)
|
||||
// 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
|
||||
// 3 Stage: run OTA0 -> check it -> set_pin_factory_reset -> reboot --//--
|
||||
// 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, sets pin_factory_reset, factory", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow4, test_flow4, test_flow4);
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, sets pin_factory_reset, factory", "[app_update][timeout=90][ignore][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow4, test_flow4, test_flow4);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_APP_TEST
|
||||
@ -486,7 +486,7 @@ static void test_flow5(void)
|
||||
// 2 Stage: run factory -> check it -> copy factory to Test and set pin_test_app -> reboot --//--
|
||||
// 3 Stage: run test -> check it -> reset pin_test_app -> reboot --//--
|
||||
// 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, test, factory", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow5, test_flow5, test_flow5);
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, test, factory", "[app_update][timeout=90][ignore][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow5, test_flow5, test_flow5);
|
||||
#endif
|
||||
|
||||
static const esp_partition_t* app_update(void)
|
||||
@ -580,7 +580,7 @@ static void test_rollback1_1(void)
|
||||
// 3 Stage: run OTA0 -> check it -> esp_ota_mark_app_valid_cancel_rollback() -> reboot --//--
|
||||
// 4 Stage: run OTA0 -> check it -> esp_ota_mark_app_invalid_rollback_and_reboot() -> reboot
|
||||
// 5 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Test rollback. factory, OTA0, OTA0, rollback -> factory", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_rollback1, test_rollback1, test_rollback1, test_rollback1_1);
|
||||
TEST_CASE_MULTIPLE_STAGES("Test rollback. factory, OTA0, OTA0, rollback -> factory", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_rollback1, test_rollback1, test_rollback1, test_rollback1_1);
|
||||
|
||||
static void test_rollback2(void)
|
||||
{
|
||||
@ -678,7 +678,7 @@ static void test_rollback2_1(void)
|
||||
// 3 Stage: run OTA0 -> check it -> esp_ota_mark_app_valid_cancel_rollback(), copy to next app slot -> reboot --//--
|
||||
// 4 Stage: run OTA1 -> check it -> PENDING_VERIFY/esp_ota_mark_app_invalid_rollback_and_reboot() -> reboot
|
||||
// 5 Stage: run OTA0(rollback) -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Test rollback. factory, OTA0, OTA1, rollback -> OTA0", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_rollback2, test_rollback2, test_rollback2, test_rollback2_1);
|
||||
TEST_CASE_MULTIPLE_STAGES("Test rollback. factory, OTA0, OTA1, rollback -> OTA0", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_rollback2, test_rollback2, test_rollback2, test_rollback2_1);
|
||||
|
||||
static void test_erase_last_app_flow(void)
|
||||
{
|
||||
@ -729,4 +729,4 @@ static void test_erase_last_app_rollback(void)
|
||||
// 3 Stage: run OTA0 -> check it -> copy factory to OTA1 -> reboot --//--
|
||||
// 4 Stage: run OTA1 -> check it -> erase OTA0 and rollback -> reboot
|
||||
// 5 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Test erase_last_boot_app_partition. factory, OTA1, OTA0, factory", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_erase_last_app_flow, test_erase_last_app_flow, test_erase_last_app_flow, test_erase_last_app_rollback);
|
||||
TEST_CASE_MULTIPLE_STAGES("Test erase_last_boot_app_partition. factory, OTA1, OTA0, factory", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_erase_last_app_flow, test_erase_last_app_flow, test_erase_last_app_flow, test_erase_last_app_rollback);
|
||||
|
@ -504,16 +504,23 @@ menu "Security features"
|
||||
|
||||
Only set this option in testing environments.
|
||||
|
||||
config SECURE_BOOT_TEST_MODE
|
||||
bool "Secure boot test mode: don't permanently set any eFuses"
|
||||
depends on SECURE_BOOT_INSECURE
|
||||
default N
|
||||
help
|
||||
If this option is set, all permanent secure boot changes (via eFuse) are disabled.
|
||||
|
||||
Log output will state changes which would be applied, but they will not be.
|
||||
|
||||
This option is for testing purposes only - it completely disables secure boot protection.
|
||||
|
||||
endmenu # Potentially Insecure
|
||||
|
||||
config FLASH_ENCRYPTION_DISABLE_PLAINTEXT
|
||||
bool "Disable serial reflashing of plaintext firmware"
|
||||
depends on FLASH_ENCRYPTION_ENABLED
|
||||
default y if SECURE_BOOT_ENABLED
|
||||
default n if !SECURE_BOOT_ENABLED
|
||||
help
|
||||
If this option is enabled, flash encryption is permanently enabled after first boot by write-protecting
|
||||
the FLASH_CRYPT_CNT efuse. This is the recommended configuration for a secure production system.
|
||||
|
||||
If this option is disabled, FLASH_CRYPT_CNT is left writeable and up to 4 plaintext re-flashes are allowed.
|
||||
An attacker with physical access will be able to read out encrypted flash contents until all plaintext
|
||||
re-flashes have been used up.
|
||||
|
||||
If this option is disabled and hardware Secure Boot is enabled, Secure Boot must be configured in
|
||||
Reflashable mode so that a new Secure Boot digest can be flashed at the same time as plaintext firmware.
|
||||
This combination is not secure and should not be used for a production system.
|
||||
|
||||
endmenu # Security features
|
||||
|
@ -49,10 +49,11 @@ if((NOT CONFIG_SECURE_BOOT_ENABLED) OR
|
||||
CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH)
|
||||
externalproject_add(bootloader
|
||||
# TODO: support overriding the bootloader in COMPONENT_PATHS
|
||||
SOURCE_DIR "${IDF_PATH}/components/bootloader/subproject"
|
||||
SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/subproject"
|
||||
BINARY_DIR "${bootloader_build_dir}"
|
||||
CMAKE_ARGS -DSDKCONFIG=${SDKCONFIG} -DIDF_PATH=${IDF_PATH}
|
||||
-DSECURE_BOOT_SIGNING_KEY=${secure_boot_signing_key}
|
||||
-DEXTRA_COMPONENT_DIRS=${CMAKE_CURRENT_LIST_DIR}
|
||||
INSTALL_COMMAND ""
|
||||
BUILD_ALWAYS 1 # no easy way around this...
|
||||
BUILD_BYPRODUCTS ${bootloader_binary_files}
|
||||
|
@ -27,9 +27,9 @@ target_linker_script(bootloader.elf
|
||||
# as cmake won't attach linker args to a header-only library, attach
|
||||
# linker args directly to the bootloader.elf
|
||||
set(ESP32_BOOTLOADER_LINKER_SCRIPTS
|
||||
"../../esp32/ld/esp32.rom.ld"
|
||||
"../../esp32/ld/esp32.rom.spiram_incompatible_fns.ld"
|
||||
"../../esp32/ld/esp32.peripherals.ld")
|
||||
"${IDF_PATH}/components/esp32/ld/esp32.rom.ld"
|
||||
"${IDF_PATH}/components/esp32/ld/esp32.rom.spiram_incompatible_fns.ld"
|
||||
"${IDF_PATH}/components/esp32/ld/esp32.peripherals.ld")
|
||||
|
||||
target_linker_script(bootloader.elf ${ESP32_BOOTLOADER_LINKER_SCRIPTS})
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "bootloader_common.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "rom/rtc.h"
|
||||
|
||||
static const char* TAG = "boot";
|
||||
|
||||
@ -74,7 +75,8 @@ static int selected_boot_partition(const bootloader_state_t *bs)
|
||||
int boot_index = bootloader_utility_get_selected_boot_partition(bs);
|
||||
if (boot_index == INVALID_INDEX) {
|
||||
return boot_index; // Unrecoverable failure (not due to corrupt ota data or bad partition contents)
|
||||
} else {
|
||||
}
|
||||
if (rtc_get_reset_reason(0) != DEEPSLEEP_RESET) {
|
||||
// Factory firmware.
|
||||
#ifdef CONFIG_BOOTLOADER_FACTORY_RESET
|
||||
if (bootloader_common_check_long_hold_gpio(CONFIG_BOOTLOADER_NUM_PIN_FACTORY_RESET, CONFIG_BOOTLOADER_HOLD_TIME_GPIO) == 1) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
set(COMPONENT_SRCS "src/bootloader_clock.c"
|
||||
"src/bootloader_common.c"
|
||||
"src/bootloader_flash.c"
|
||||
"src/bootloader_flash_config.c"
|
||||
"src/bootloader_random.c"
|
||||
"src/bootloader_sha.c"
|
||||
"src/bootloader_utility.c"
|
||||
|
@ -15,6 +15,7 @@
|
||||
#pragma once
|
||||
#include "esp_flash_data_types.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_image_format.h"
|
||||
|
||||
/// Type of hold a GPIO in low state
|
||||
typedef enum {
|
||||
@ -23,6 +24,11 @@ typedef enum {
|
||||
GPIO_NOT_HOLD = 0 /*!< If the GPIO input is not low */
|
||||
} esp_comm_gpio_hold_t;
|
||||
|
||||
typedef enum {
|
||||
ESP_IMAGE_BOOTLOADER,
|
||||
ESP_IMAGE_APPLICATION
|
||||
} esp_image_type;
|
||||
|
||||
/**
|
||||
* @brief Calculate crc for the OTA data select.
|
||||
*
|
||||
@ -125,7 +131,7 @@ int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata,
|
||||
|
||||
/**
|
||||
* @brief Returns esp_app_desc structure for app partition. This structure includes app version.
|
||||
*
|
||||
*
|
||||
* Returns a description for the requested app partition.
|
||||
* @param[in] partition App partition description.
|
||||
* @param[out] app_desc Structure of info about app.
|
||||
@ -136,3 +142,26 @@ int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata,
|
||||
* - ESP_FAIL: mapping is fail.
|
||||
*/
|
||||
esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t *partition, esp_app_desc_t *app_desc);
|
||||
|
||||
/**
|
||||
* @brief Get chip revision
|
||||
*
|
||||
* @return Chip revision number
|
||||
*/
|
||||
uint8_t bootloader_common_get_chip_revision(void);
|
||||
|
||||
/**
|
||||
* @brief Check if the image (bootloader and application) has valid chip ID and revision
|
||||
*
|
||||
* @param[in] img_hdr: image header
|
||||
* @param[in] type: image type, bootloader or application
|
||||
* @return
|
||||
* - ESP_OK: image and chip are matched well
|
||||
* - ESP_FAIL: image doesn't match to the chip
|
||||
*/
|
||||
esp_err_t bootloader_common_check_chip_validity(const esp_image_header_t* img_hdr, esp_image_type type);
|
||||
|
||||
/**
|
||||
* @brief Configure VDDSDIO, call this API to rise VDDSDIO to 1.9V when VDDSDIO regulator is enabled as 1.8V mode.
|
||||
*/
|
||||
void bootloader_common_vddsdio_configure();
|
||||
|
@ -0,0 +1,71 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_image_format.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Update the flash id in g_rom_flashchip(global esp_rom_spiflash_chip_t structure).
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void bootloader_flash_update_id();
|
||||
|
||||
/**
|
||||
* @brief Set the flash CS setup and hold time.
|
||||
*
|
||||
* @note CS setup time is recomemded to be 1.5T, and CS hold time is recommended to be 2.5T.
|
||||
* cs_setup = 1, cs_setup_time = 0; cs_hold = 1, cs_hold_time = 1.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void bootloader_flash_cs_timing_config();
|
||||
|
||||
/**
|
||||
* @brief Configure SPI flash clock.
|
||||
*
|
||||
* @note This function only set clock frequency for SPI0.
|
||||
*
|
||||
* @param pfhdr Pointer to App image header, from where to fetch flash settings.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void bootloader_flash_clock_config(const esp_image_header_t* pfhdr);
|
||||
|
||||
/**
|
||||
* @brief Configure SPI flash gpio, include the IO matrix and drive strength configuration.
|
||||
*
|
||||
* @param pfhdr Pointer to App image header, from where to fetch flash settings.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void bootloader_flash_gpio_config(const esp_image_header_t* pfhdr);
|
||||
|
||||
/**
|
||||
* @brief Configure SPI flash read dummy based on different mode and frequency.
|
||||
*
|
||||
* @param pfhdr Pointer to App image header, from where to fetch flash settings.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void bootloader_flash_dummy_config(const esp_image_header_t* pfhdr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -55,6 +55,19 @@ typedef enum {
|
||||
|
||||
#define ESP_IMAGE_HEADER_MAGIC 0xE9
|
||||
|
||||
/**
|
||||
* @brief ESP chip ID
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_CHIP_ID_ESP32 = 0x0000, /*!< chip ID: ESP32 */
|
||||
ESP_CHIP_ID_INVALID = 0xFFFF /*!< Invalid chip ID (we defined it to make sure the esp_chip_id_t is 2 bytes size) */
|
||||
} __attribute__((packed)) esp_chip_id_t;
|
||||
|
||||
/** @cond */
|
||||
_Static_assert(sizeof(esp_chip_id_t) == 2, "esp_chip_id_t should be 16 bit");
|
||||
/** @endcond */
|
||||
|
||||
/* Main header of binary image */
|
||||
typedef struct {
|
||||
uint8_t magic;
|
||||
@ -71,8 +84,9 @@ typedef struct {
|
||||
uint8_t wp_pin;
|
||||
/* Drive settings for the SPI flash pins (read by ROM bootloader) */
|
||||
uint8_t spi_pin_drv[3];
|
||||
/* Reserved bytes in ESP32 additional header space, currently unused */
|
||||
uint8_t reserved[11];
|
||||
esp_chip_id_t chip_id; /*!< Chip identification number */
|
||||
uint8_t min_chip_rev; /*!< Minimum chip revision supported by image */
|
||||
uint8_t reserved[8]; /*!< Reserved bytes in additional header space, currently unused */
|
||||
/* If 1, a SHA256 digest "simple hash" (of the entire image) is appended after the checksum. Included in image length. This digest
|
||||
* is separate to secure boot and only used for detecting corruption. For secure boot signed images, the signature
|
||||
* is appended after this (and the simple hash is included in the signed data). */
|
||||
|
@ -46,6 +46,25 @@ static inline bool esp_secure_boot_enabled(void) {
|
||||
return REG_READ(EFUSE_BLK0_RDATA6_REG) & EFUSE_RD_ABS_DONE_0;
|
||||
}
|
||||
|
||||
/** @brief Generate secure digest from bootloader image
|
||||
*
|
||||
* @important This function is intended to be called from bootloader code only.
|
||||
*
|
||||
* If secure boot is not yet enabled for bootloader, this will:
|
||||
* 1) generate the secure boot key and burn it on EFUSE
|
||||
* (without enabling R/W protection)
|
||||
* 2) generate the digest from bootloader and save it
|
||||
* to flash address 0x0
|
||||
*
|
||||
* If first boot gets interrupted after calling this function
|
||||
* but before esp_secure_boot_permanently_enable() is called, then
|
||||
* the key burned on EFUSE will not be regenerated, unless manually
|
||||
* done using espefuse.py tool
|
||||
*
|
||||
* @return ESP_OK if secure boot digest is generated
|
||||
* successfully or found to be already present
|
||||
*/
|
||||
esp_err_t esp_secure_boot_generate_digest(void);
|
||||
|
||||
/** @brief Enable secure boot if it is not already enabled.
|
||||
*
|
||||
@ -54,9 +73,13 @@ static inline bool esp_secure_boot_enabled(void) {
|
||||
*
|
||||
* @important This function is intended to be called from bootloader code only.
|
||||
*
|
||||
* @important This will enable r/w protection of secure boot key on EFUSE,
|
||||
* therefore it is to be ensured that esp_secure_boot_generate_digest()
|
||||
* is called before this
|
||||
*
|
||||
* If secure boot is not yet enabled for bootloader, this will
|
||||
* generate the secure boot digest and enable secure boot by blowing
|
||||
* the EFUSE_RD_ABS_DONE_0 efuse.
|
||||
* 1) enable R/W protection of secure boot key on EFUSE
|
||||
* 2) enable secure boot by blowing the EFUSE_RD_ABS_DONE_0 efuse.
|
||||
*
|
||||
* This function does not verify secure boot of the bootloader (the
|
||||
* ROM bootloader does this.)
|
||||
@ -64,7 +87,6 @@ static inline bool esp_secure_boot_enabled(void) {
|
||||
* Will fail if efuses have been part-burned in a way that indicates
|
||||
* secure boot should not or could not be correctly enabled.
|
||||
*
|
||||
*
|
||||
* @return ESP_ERR_INVALID_STATE if efuse state doesn't allow
|
||||
* secure boot to be enabled cleanly. ESP_OK if secure boot
|
||||
* is enabled on this chip from now on.
|
||||
|
@ -30,6 +30,13 @@
|
||||
bootloader_support components only.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Get number of free pages
|
||||
*
|
||||
* @return Number of free pages
|
||||
*/
|
||||
uint32_t bootloader_mmap_get_free_pages();
|
||||
|
||||
/**
|
||||
* @brief Map a region of flash to data memory
|
||||
*
|
||||
|
@ -27,6 +27,11 @@
|
||||
#include "bootloader_flash.h"
|
||||
#include "bootloader_common.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/spi_reg.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/apb_ctrl_reg.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "bootloader_sha.h"
|
||||
#include "sys/param.h"
|
||||
@ -257,3 +262,66 @@ esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void bootloader_common_vddsdio_configure()
|
||||
{
|
||||
#if CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V
|
||||
rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config();
|
||||
if (cfg.enable == 1 && cfg.tieh == RTC_VDDSDIO_TIEH_1_8V) { // VDDSDIO regulator is enabled @ 1.8V
|
||||
cfg.drefh = 3;
|
||||
cfg.drefm = 3;
|
||||
cfg.drefl = 3;
|
||||
cfg.force = 1;
|
||||
rtc_vddsdio_set_config(cfg);
|
||||
ets_delay_us(10); // wait for regulator to become stable
|
||||
}
|
||||
#endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
uint8_t bootloader_common_get_chip_revision(void)
|
||||
{
|
||||
uint8_t eco_bit0, eco_bit1, eco_bit2;
|
||||
eco_bit0 = (REG_READ(EFUSE_BLK0_RDATA3_REG) & 0xF000) >> 15;
|
||||
eco_bit1 = (REG_READ(EFUSE_BLK0_RDATA5_REG) & 0x100000) >> 20;
|
||||
eco_bit2 = (REG_READ(APB_CTRL_DATE_REG) & 0x80000000) >> 31;
|
||||
uint32_t combine_value = (eco_bit2 << 2) | (eco_bit1 << 1) | eco_bit0;
|
||||
uint8_t chip_ver = 0;
|
||||
switch (combine_value) {
|
||||
case 0:
|
||||
chip_ver = 0;
|
||||
break;
|
||||
case 1:
|
||||
chip_ver = 1;
|
||||
break;
|
||||
case 3:
|
||||
chip_ver = 2;
|
||||
break;
|
||||
case 7:
|
||||
chip_ver = 3;
|
||||
break;
|
||||
default:
|
||||
chip_ver = 0;
|
||||
break;
|
||||
}
|
||||
return chip_ver;
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_err_t bootloader_common_check_chip_validity(const esp_image_header_t* img_hdr, esp_image_type type)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
esp_chip_id_t chip_id = CONFIG_IDF_FIRMWARE_CHIP_ID;
|
||||
if (chip_id != img_hdr->chip_id) {
|
||||
ESP_LOGE(TAG, "mismatch chip ID, expected %d, found %d", chip_id, img_hdr->chip_id);
|
||||
err = ESP_FAIL;
|
||||
}
|
||||
uint8_t revision = bootloader_common_get_chip_revision();
|
||||
if (revision < img_hdr->min_chip_rev) {
|
||||
ESP_LOGE(TAG, "can't run on lower chip revision, expected %d, found %d", revision, img_hdr->min_chip_rev);
|
||||
err = ESP_FAIL;
|
||||
} else if (revision != img_hdr->min_chip_rev) {
|
||||
ESP_LOGI(TAG, "chip revision: %d, min. %s chip revision: %d", revision, type == ESP_IMAGE_BOOTLOADER ? "bootloader" : "application", img_hdr->min_chip_rev);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
@ -25,6 +25,11 @@ static const char *TAG = "bootloader_mmap";
|
||||
|
||||
static spi_flash_mmap_handle_t map;
|
||||
|
||||
uint32_t bootloader_mmap_get_free_pages()
|
||||
{
|
||||
return spi_flash_mmap_get_free_pages(SPI_FLASH_MMAP_DATA);
|
||||
}
|
||||
|
||||
const void *bootloader_mmap(uint32_t src_addr, uint32_t size)
|
||||
{
|
||||
if (map) {
|
||||
@ -91,12 +96,22 @@ static const char *TAG = "bootloader_flash";
|
||||
*/
|
||||
#define MMU_BLOCK0_VADDR 0x3f400000
|
||||
#define MMU_BLOCK50_VADDR 0x3f720000
|
||||
#define MMU_FREE_PAGES ((MMU_BLOCK50_VADDR - MMU_BLOCK0_VADDR) / FLASH_BLOCK_SIZE)
|
||||
|
||||
static bool mapped;
|
||||
|
||||
// Current bootloader mapping (ab)used for bootloader_read()
|
||||
static uint32_t current_read_mapping = UINT32_MAX;
|
||||
|
||||
uint32_t bootloader_mmap_get_free_pages()
|
||||
{
|
||||
/**
|
||||
* Allow mapping up to 50 of the 51 available MMU blocks (last one used for reads)
|
||||
* Since, bootloader_mmap function below assumes it to be 0x320000 (50 pages), we can safely do this.
|
||||
*/
|
||||
return MMU_FREE_PAGES;
|
||||
}
|
||||
|
||||
const void *bootloader_mmap(uint32_t src_addr, uint32_t size)
|
||||
{
|
||||
if (mapped) {
|
||||
|
165
components/bootloader_support/src/bootloader_flash_config.c
Normal file
165
components/bootloader_support/src/bootloader_flash_config.c
Normal file
@ -0,0 +1,165 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include "string.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "rom/gpio.h"
|
||||
#include "rom/spi_flash.h"
|
||||
#include "rom/efuse.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/spi_reg.h"
|
||||
#include "soc/spi_pins.h"
|
||||
#include "flash_qio_mode.h"
|
||||
#include "bootloader_flash_config.h"
|
||||
|
||||
void bootloader_flash_update_id()
|
||||
{
|
||||
g_rom_flashchip.device_id = bootloader_read_flash_id();
|
||||
}
|
||||
|
||||
void IRAM_ATTR bootloader_flash_cs_timing_config()
|
||||
{
|
||||
SET_PERI_REG_MASK(SPI_USER_REG(0), SPI_CS_HOLD_M | SPI_CS_SETUP_M);
|
||||
SET_PERI_REG_BITS(SPI_CTRL2_REG(0), SPI_HOLD_TIME_V, 1, SPI_HOLD_TIME_S);
|
||||
SET_PERI_REG_BITS(SPI_CTRL2_REG(0), SPI_SETUP_TIME_V, 0, SPI_SETUP_TIME_S);
|
||||
SET_PERI_REG_MASK(SPI_USER_REG(1), SPI_CS_HOLD_M | SPI_CS_SETUP_M);
|
||||
SET_PERI_REG_BITS(SPI_CTRL2_REG(1), SPI_HOLD_TIME_V, 1, SPI_HOLD_TIME_S);
|
||||
SET_PERI_REG_BITS(SPI_CTRL2_REG(1), SPI_SETUP_TIME_V, 0, SPI_SETUP_TIME_S);
|
||||
}
|
||||
|
||||
void IRAM_ATTR bootloader_flash_clock_config(const esp_image_header_t* pfhdr)
|
||||
{
|
||||
uint32_t spi_clk_div = 0;
|
||||
switch (pfhdr->spi_speed) {
|
||||
case ESP_IMAGE_SPI_SPEED_80M:
|
||||
spi_clk_div = 1;
|
||||
break;
|
||||
case ESP_IMAGE_SPI_SPEED_40M:
|
||||
spi_clk_div = 2;
|
||||
break;
|
||||
case ESP_IMAGE_SPI_SPEED_26M:
|
||||
spi_clk_div = 3;
|
||||
break;
|
||||
case ESP_IMAGE_SPI_SPEED_20M:
|
||||
spi_clk_div = 4;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
esp_rom_spiflash_config_clk(spi_clk_div, 0);
|
||||
}
|
||||
|
||||
void IRAM_ATTR bootloader_flash_gpio_config(const esp_image_header_t* pfhdr)
|
||||
{
|
||||
uint32_t drv = 2;
|
||||
if (pfhdr->spi_speed == ESP_IMAGE_SPI_SPEED_80M) {
|
||||
drv = 3;
|
||||
}
|
||||
|
||||
uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG);
|
||||
uint32_t pkg_ver = chip_ver & 0x7;
|
||||
|
||||
if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5) {
|
||||
// For ESP32D2WD the SPI pins are already configured
|
||||
// flash clock signal should come from IO MUX.
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) {
|
||||
// For ESP32PICOD2 the SPI pins are already configured
|
||||
// flash clock signal should come from IO MUX.
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) {
|
||||
// For ESP32PICOD4 the SPI pins are already configured
|
||||
// flash clock signal should come from IO MUX.
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||
} else {
|
||||
const uint32_t spiconfig = ets_efuse_get_spiconfig();
|
||||
if (spiconfig == EFUSE_SPICONFIG_SPI_DEFAULTS) {
|
||||
gpio_matrix_out(SPI_IOMUX_PIN_NUM_CS, SPICS0_OUT_IDX, 0, 0);
|
||||
gpio_matrix_out(SPI_IOMUX_PIN_NUM_MISO, SPIQ_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(SPI_IOMUX_PIN_NUM_MISO, SPIQ_IN_IDX, 0);
|
||||
gpio_matrix_out(SPI_IOMUX_PIN_NUM_MOSI, SPID_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(SPI_IOMUX_PIN_NUM_MOSI, SPID_IN_IDX, 0);
|
||||
gpio_matrix_out(SPI_IOMUX_PIN_NUM_WP, SPIWP_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(SPI_IOMUX_PIN_NUM_WP, SPIWP_IN_IDX, 0);
|
||||
gpio_matrix_out(SPI_IOMUX_PIN_NUM_HD, SPIHD_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(SPI_IOMUX_PIN_NUM_HD, SPIHD_IN_IDX, 0);
|
||||
//select pin function gpio
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA2_U, PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA3_U, PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, PIN_FUNC_GPIO);
|
||||
// flash clock signal should come from IO MUX.
|
||||
// set drive ability for clock
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||
|
||||
uint32_t flash_id = g_rom_flashchip.device_id;
|
||||
if (flash_id == FLASH_ID_GD25LQ32C) {
|
||||
// Set drive ability for 1.8v flash in 80Mhz.
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA0_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA1_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA2_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA3_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CMD_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t* pfhdr)
|
||||
{
|
||||
int spi_cache_dummy = 0;
|
||||
uint32_t modebit = READ_PERI_REG(SPI_CTRL_REG(0));
|
||||
if (modebit & SPI_FASTRD_MODE) {
|
||||
if (modebit & SPI_FREAD_QIO) { //SPI mode is QIO
|
||||
spi_cache_dummy = SPI0_R_QIO_DUMMY_CYCLELEN;
|
||||
} else if (modebit & SPI_FREAD_DIO) { //SPI mode is DIO
|
||||
spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN;
|
||||
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_ADDR_BITLEN_V, SPI0_R_DIO_ADDR_BITSLEN, SPI_USR_ADDR_BITLEN_S);
|
||||
} else if(modebit & (SPI_FREAD_QUAD | SPI_FREAD_DUAL)) { //SPI mode is QOUT or DIO
|
||||
spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN;
|
||||
}
|
||||
}
|
||||
|
||||
extern uint8_t g_rom_spiflash_dummy_len_plus[];
|
||||
switch (pfhdr->spi_speed) {
|
||||
case ESP_IMAGE_SPI_SPEED_80M:
|
||||
g_rom_spiflash_dummy_len_plus[0] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_80M;
|
||||
g_rom_spiflash_dummy_len_plus[1] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_80M;
|
||||
break;
|
||||
case ESP_IMAGE_SPI_SPEED_40M:
|
||||
g_rom_spiflash_dummy_len_plus[0] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_40M;
|
||||
g_rom_spiflash_dummy_len_plus[1] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_40M;
|
||||
break;
|
||||
case ESP_IMAGE_SPI_SPEED_26M:
|
||||
case ESP_IMAGE_SPI_SPEED_20M:
|
||||
g_rom_spiflash_dummy_len_plus[0] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_20M;
|
||||
g_rom_spiflash_dummy_len_plus[1] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_20M;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + g_rom_spiflash_dummy_len_plus[0],
|
||||
SPI_USR_DUMMY_CYCLELEN_S);
|
||||
}
|
@ -33,12 +33,10 @@
|
||||
#include "soc/cpu.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "soc/gpio_reg.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "soc/rtc_wdt.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
@ -50,6 +48,8 @@
|
||||
#include "bootloader_random.h"
|
||||
#include "bootloader_config.h"
|
||||
#include "bootloader_clock.h"
|
||||
#include "bootloader_common.h"
|
||||
#include "bootloader_flash_config.h"
|
||||
|
||||
#include "flash_qio_mode.h"
|
||||
|
||||
@ -63,8 +63,7 @@ static const char* TAG = "boot";
|
||||
static esp_err_t bootloader_main();
|
||||
static void print_flash_info(const esp_image_header_t* pfhdr);
|
||||
static void update_flash_config(const esp_image_header_t* pfhdr);
|
||||
static void vddsdio_configure();
|
||||
static void flash_gpio_configure(const esp_image_header_t* pfhdr);
|
||||
static void bootloader_init_flash_configure(const esp_image_header_t* pfhdr);
|
||||
static void uart_console_configure(void);
|
||||
static void wdt_reset_check(void);
|
||||
|
||||
@ -119,7 +118,7 @@ esp_err_t bootloader_init()
|
||||
|
||||
static esp_err_t bootloader_main()
|
||||
{
|
||||
vddsdio_configure();
|
||||
bootloader_common_vddsdio_configure();
|
||||
/* Read and keep flash ID, for further use. */
|
||||
g_rom_flashchip.device_id = bootloader_read_flash_id();
|
||||
esp_image_header_t fhdr;
|
||||
@ -127,7 +126,15 @@ static esp_err_t bootloader_main()
|
||||
ESP_LOGE(TAG, "failed to load bootloader header!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
flash_gpio_configure(&fhdr);
|
||||
|
||||
/* Check chip ID and minimum chip revision that supported by this image */
|
||||
uint8_t revision = bootloader_common_get_chip_revision();
|
||||
ESP_LOGI(TAG, "Chip Revision: %d", revision);
|
||||
if (bootloader_common_check_chip_validity(&fhdr, ESP_IMAGE_BOOTLOADER) != ESP_OK) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
bootloader_init_flash_configure(&fhdr);
|
||||
#if (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ == 240)
|
||||
//Check if ESP32 is rated for a CPU frequency of 160MHz only
|
||||
if (REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_CPU_FREQ_RATED) &&
|
||||
@ -287,128 +294,15 @@ static void print_flash_info(const esp_image_header_t* phdr)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void vddsdio_configure()
|
||||
{
|
||||
#if CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V
|
||||
rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config();
|
||||
if (cfg.enable == 1 && cfg.tieh == RTC_VDDSDIO_TIEH_1_8V) { // VDDSDIO regulator is enabled @ 1.8V
|
||||
cfg.drefh = 3;
|
||||
cfg.drefm = 3;
|
||||
cfg.drefl = 3;
|
||||
cfg.force = 1;
|
||||
rtc_vddsdio_set_config(cfg);
|
||||
ets_delay_us(10); // wait for regulator to become stable
|
||||
}
|
||||
#endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST
|
||||
}
|
||||
|
||||
#define FLASH_CLK_IO 6
|
||||
#define FLASH_CS_IO 11
|
||||
#define FLASH_SPIQ_IO 7
|
||||
#define FLASH_SPID_IO 8
|
||||
#define FLASH_SPIWP_IO 10
|
||||
#define FLASH_SPIHD_IO 9
|
||||
#define FLASH_IO_MATRIX_DUMMY_40M 1
|
||||
#define FLASH_IO_MATRIX_DUMMY_80M 2
|
||||
#define FLASH_IO_DRIVE_GD_WITH_1V8PSRAM 3
|
||||
|
||||
/*
|
||||
* Bootloader reads SPI configuration from bin header, so that
|
||||
* the burning configuration can be different with compiling configuration.
|
||||
*/
|
||||
static void IRAM_ATTR flash_gpio_configure(const esp_image_header_t* pfhdr)
|
||||
static void IRAM_ATTR bootloader_init_flash_configure(const esp_image_header_t* pfhdr)
|
||||
{
|
||||
int spi_cache_dummy = 0;
|
||||
int drv = 2;
|
||||
switch (pfhdr->spi_mode) {
|
||||
case ESP_IMAGE_SPI_MODE_QIO:
|
||||
spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN;
|
||||
break;
|
||||
case ESP_IMAGE_SPI_MODE_DIO:
|
||||
spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN; //qio 3
|
||||
break;
|
||||
case ESP_IMAGE_SPI_MODE_QOUT:
|
||||
case ESP_IMAGE_SPI_MODE_DOUT:
|
||||
default:
|
||||
spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN;
|
||||
break;
|
||||
}
|
||||
|
||||
/* dummy_len_plus values defined in ROM for SPI flash configuration */
|
||||
extern uint8_t g_rom_spiflash_dummy_len_plus[];
|
||||
switch (pfhdr->spi_speed) {
|
||||
case ESP_IMAGE_SPI_SPEED_80M:
|
||||
g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_80M;
|
||||
g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_80M;
|
||||
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_80M,
|
||||
SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
|
||||
drv = 3;
|
||||
break;
|
||||
case ESP_IMAGE_SPI_SPEED_40M:
|
||||
g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_40M;
|
||||
g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_40M;
|
||||
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_40M,
|
||||
SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG);
|
||||
uint32_t pkg_ver = chip_ver & 0x7;
|
||||
|
||||
if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5) {
|
||||
// For ESP32D2WD the SPI pins are already configured
|
||||
// flash clock signal should come from IO MUX.
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) {
|
||||
// For ESP32PICOD2 the SPI pins are already configured
|
||||
// flash clock signal should come from IO MUX.
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) {
|
||||
// For ESP32PICOD4 the SPI pins are already configured
|
||||
// flash clock signal should come from IO MUX.
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||
} else {
|
||||
const uint32_t spiconfig = ets_efuse_get_spiconfig();
|
||||
if (spiconfig == EFUSE_SPICONFIG_SPI_DEFAULTS) {
|
||||
gpio_matrix_out(FLASH_CS_IO, SPICS0_OUT_IDX, 0, 0);
|
||||
gpio_matrix_out(FLASH_SPIQ_IO, SPIQ_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(FLASH_SPIQ_IO, SPIQ_IN_IDX, 0);
|
||||
gpio_matrix_out(FLASH_SPID_IO, SPID_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(FLASH_SPID_IO, SPID_IN_IDX, 0);
|
||||
gpio_matrix_out(FLASH_SPIWP_IO, SPIWP_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(FLASH_SPIWP_IO, SPIWP_IN_IDX, 0);
|
||||
gpio_matrix_out(FLASH_SPIHD_IO, SPIHD_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(FLASH_SPIHD_IO, SPIHD_IN_IDX, 0);
|
||||
//select pin function gpio
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA2_U, PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA3_U, PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, PIN_FUNC_GPIO);
|
||||
// flash clock signal should come from IO MUX.
|
||||
// set drive ability for clock
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||
|
||||
#if CONFIG_SPIRAM_TYPE_ESPPSRAM32
|
||||
uint32_t flash_id = g_rom_flashchip.device_id;
|
||||
if (flash_id == FLASH_ID_GD25LQ32C) {
|
||||
// Set drive ability for 1.8v flash in 80Mhz.
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA0_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA1_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA2_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA3_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CMD_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
bootloader_flash_gpio_config(pfhdr);
|
||||
bootloader_flash_dummy_config(pfhdr);
|
||||
bootloader_flash_cs_timing_config();
|
||||
}
|
||||
|
||||
static void uart_console_configure(void)
|
||||
@ -442,10 +336,18 @@ static void uart_console_configure(void)
|
||||
// (arrays should be optimized away by the compiler)
|
||||
const uint32_t tx_idx_list[3] = { U0TXD_OUT_IDX, U1TXD_OUT_IDX, U2TXD_OUT_IDX };
|
||||
const uint32_t rx_idx_list[3] = { U0RXD_IN_IDX, U1RXD_IN_IDX, U2RXD_IN_IDX };
|
||||
const uint32_t uart_reset[3] = { DPORT_UART_RST, DPORT_UART1_RST, DPORT_UART2_RST };
|
||||
const uint32_t tx_idx = tx_idx_list[uart_num];
|
||||
const uint32_t rx_idx = rx_idx_list[uart_num];
|
||||
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[uart_rx_gpio]);
|
||||
gpio_pad_pullup(uart_rx_gpio);
|
||||
|
||||
gpio_matrix_out(uart_tx_gpio, tx_idx, 0, 0);
|
||||
gpio_matrix_in(uart_rx_gpio, rx_idx, 0);
|
||||
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, uart_reset[uart_num]);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, uart_reset[uart_num]);
|
||||
}
|
||||
#endif // CONFIG_CONSOLE_UART_CUSTOM
|
||||
|
||||
|
@ -114,17 +114,18 @@ void bootloader_random_enable(void)
|
||||
|
||||
void bootloader_random_disable(void)
|
||||
{
|
||||
/* Disable i2s clock */
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
|
||||
|
||||
|
||||
/* Reset some i2s configuration (possibly redundant as we reset entire
|
||||
I2S peripheral further down). */
|
||||
CLEAR_PERI_REG_MASK(I2S_CONF_REG(0), I2S_RX_START);
|
||||
SET_PERI_REG_MASK(I2S_CONF_REG(0), I2S_RX_RESET);
|
||||
CLEAR_PERI_REG_MASK(I2S_CONF_REG(0), I2S_RX_RESET);
|
||||
CLEAR_PERI_REG_MASK(I2S_CONF2_REG(0), I2S_CAMERA_EN);
|
||||
CLEAR_PERI_REG_MASK(I2S_CONF2_REG(0), I2S_LCD_EN);
|
||||
CLEAR_PERI_REG_MASK(I2S_CONF2_REG(0), I2S_DATA_ENABLE_TEST_EN);
|
||||
CLEAR_PERI_REG_MASK(I2S_CONF2_REG(0), I2S_DATA_ENABLE);
|
||||
CLEAR_PERI_REG_MASK(I2S_CONF_REG(0), I2S_RX_START);
|
||||
|
||||
/* Disable i2s clock */
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
|
||||
|
||||
/* Restore SYSCON mode registers */
|
||||
CLEAR_PERI_REG_MASK(SENS_SAR_READ_CTRL_REG, SENS_SAR1_DIG_FORCE);
|
||||
|
@ -478,24 +478,71 @@ void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_
|
||||
// Copy loaded segments to RAM, set up caches for mapped segments, and start application.
|
||||
static void load_image(const esp_image_metadata_t* image_data)
|
||||
{
|
||||
/**
|
||||
* Rough steps for a first boot, when encryption and secure boot are both disabled:
|
||||
* 1) Generate secure boot key and write to EFUSE.
|
||||
* 2) Write plaintext digest based on plaintext bootloader
|
||||
* 3) Generate flash encryption key and write to EFUSE.
|
||||
* 4) Encrypt flash in-place including bootloader, then digest,
|
||||
* then app partitions and other encrypted partitions
|
||||
* 5) Burn EFUSE to enable flash encryption (FLASH_CRYPT_CNT)
|
||||
* 6) Burn EFUSE to enable secure boot (ABS_DONE_0)
|
||||
*
|
||||
* If power failure happens during Step 1, probably the next boot will continue from Step 2.
|
||||
* There is some small chance that EFUSEs will be part-way through being written so will be
|
||||
* somehow corrupted here. Thankfully this window of time is very small, but if that's the
|
||||
* case, one has to use the espefuse tool to manually set the remaining bits and enable R/W
|
||||
* protection. Once the relevant EFUSE bits are set and R/W protected, Step 1 will be skipped
|
||||
* successfully on further reboots.
|
||||
*
|
||||
* If power failure happens during Step 2, Step 1 will be skipped and Step 2 repeated:
|
||||
* the digest will get re-written on the next boot.
|
||||
*
|
||||
* If power failure happens during Step 3, it's possible that EFUSE was partially written
|
||||
* with the generated flash encryption key, though the time window for that would again
|
||||
* be very small. On reboot, Step 1 will be skipped and Step 2 repeated, though, Step 3
|
||||
* may fail due to the above mentioned reason, in which case, one has to use the espefuse
|
||||
* tool to manually set the remaining bits and enable R/W protection. Once the relevant EFUSE
|
||||
* bits are set and R/W protected, Step 3 will be skipped successfully on further reboots.
|
||||
*
|
||||
* If power failure happens after start of 4 and before end of 5, the next boot will fail
|
||||
* (bootloader header is encrypted and flash encryption isn't enabled yet, so it looks like
|
||||
* noise to the ROM bootloader). The check in the ROM is pretty basic so if the first byte of
|
||||
* ciphertext happens to be the magic byte E9 then it may try to boot, but it will definitely
|
||||
* crash (no chance that the remaining ciphertext will look like a valid bootloader image).
|
||||
* Only solution is to reflash with all plaintext and the whole process starts again: skips
|
||||
* Step 1, repeats Step 2, skips Step 3, etc.
|
||||
*
|
||||
* If power failure happens after 5 but before 6, the device will reboot with flash
|
||||
* encryption on and will regenerate an encrypted digest in Step 2. This should still
|
||||
* be valid as the input data for the digest is read via flash cache (so will be decrypted)
|
||||
* and the code in secure_boot_generate() tells bootloader_flash_write() to encrypt the data
|
||||
* on write if flash encryption is enabled. Steps 3 - 5 are skipped (encryption already on),
|
||||
* then Step 6 enables secure boot.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_SECURE_BOOT_ENABLED) || defined(CONFIG_FLASH_ENCRYPTION_ENABLED)
|
||||
esp_err_t err;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
/* Generate secure digest from this bootloader to protect future
|
||||
modifications */
|
||||
ESP_LOGI(TAG, "Checking secure boot...");
|
||||
err = esp_secure_boot_permanently_enable();
|
||||
/* Steps 1 & 2 (see above for full description):
|
||||
* 1) Generate secure boot EFUSE key
|
||||
* 2) Compute digest of plaintext bootloader
|
||||
*/
|
||||
err = esp_secure_boot_generate_digest();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Bootloader digest generation failed (%d). SECURE BOOT IS NOT ENABLED.", err);
|
||||
/* Allow booting to continue, as the failure is probably
|
||||
due to user-configured EFUSEs for testing...
|
||||
*/
|
||||
ESP_LOGE(TAG, "Bootloader digest generation for secure boot failed (%d).", err);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FLASH_ENCRYPTION_ENABLED
|
||||
/* encrypt flash */
|
||||
/* Steps 3, 4 & 5 (see above for full description):
|
||||
* 3) Generate flash encryption EFUSE key
|
||||
* 4) Encrypt flash contents
|
||||
* 5) Burn EFUSE to enable flash encryption
|
||||
*/
|
||||
ESP_LOGI(TAG, "Checking flash encryption...");
|
||||
bool flash_encryption_enabled = esp_flash_encryption_enabled();
|
||||
err = esp_flash_encrypt_check_and_update();
|
||||
@ -503,7 +550,24 @@ static void load_image(const esp_image_metadata_t* image_data)
|
||||
ESP_LOGE(TAG, "Flash encryption check failed (%d).", err);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
/* Step 6 (see above for full description):
|
||||
* 6) Burn EFUSE to enable secure boot
|
||||
*/
|
||||
ESP_LOGI(TAG, "Checking secure boot...");
|
||||
err = esp_secure_boot_permanently_enable();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "FAILED TO ENABLE SECURE BOOT (%d).", err);
|
||||
/* Panic here as secure boot is not properly enabled
|
||||
due to one of the reasons in above function
|
||||
*/
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FLASH_ENCRYPTION_ENABLED
|
||||
if (!flash_encryption_enabled && esp_flash_encryption_enabled()) {
|
||||
/* Flash encryption was just enabled for the first time,
|
||||
so issue a system reset to ensure flash encryption
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <bootloader_random.h>
|
||||
#include <bootloader_sha.h>
|
||||
#include "bootloader_util.h"
|
||||
#include "bootloader_common.h"
|
||||
|
||||
/* Checking signatures as part of verifying images is necessary:
|
||||
- Always if secure boot is enabled
|
||||
@ -280,6 +281,9 @@ static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t
|
||||
}
|
||||
err = ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
if (bootloader_common_check_chip_validity(image, ESP_IMAGE_APPLICATION) != ESP_OK) {
|
||||
err = ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
if (!silent) {
|
||||
if (image->spi_mode > ESP_IMAGE_SPI_MODE_SLOW_READ) {
|
||||
ESP_LOGW(TAG, "image at 0x%x has invalid SPI mode %d", src_addr, image->spi_mode);
|
||||
@ -368,24 +372,22 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme
|
||||
}
|
||||
#endif // BOOTLOADER_BUILD
|
||||
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
uint32_t free_page_count = spi_flash_mmap_get_free_pages(SPI_FLASH_MMAP_DATA);
|
||||
ESP_LOGD(TAG, "free data page_count 0x%08x",free_page_count);
|
||||
uint32_t offset_page = 0;
|
||||
while (data_len >= free_page_count * SPI_FLASH_MMU_PAGE_SIZE) {
|
||||
offset_page = ((data_addr & MMAP_ALIGNED_MASK) != 0)?1:0;
|
||||
err = process_segment_data(load_addr, data_addr, (free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE, do_load, sha_handle, checksum);
|
||||
uint32_t free_page_count = bootloader_mmap_get_free_pages();
|
||||
ESP_LOGD(TAG, "free data page_count 0x%08x", free_page_count);
|
||||
|
||||
int32_t data_len_remain = data_len;
|
||||
while (data_len_remain > 0) {
|
||||
uint32_t offset_page = ((data_addr & MMAP_ALIGNED_MASK) != 0) ? 1 : 0;
|
||||
/* Data we could map in case we are not aligned to PAGE boundary is one page size lesser. */
|
||||
data_len = MIN(data_len_remain, ((free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE));
|
||||
err = process_segment_data(load_addr, data_addr, data_len, do_load, sha_handle, checksum);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
data_addr += (free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE;
|
||||
data_len -= (free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE;
|
||||
}
|
||||
#endif
|
||||
err = process_segment_data(load_addr, data_addr, data_len, do_load, sha_handle, checksum);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
data_addr += data_len;
|
||||
data_len_remain -= data_len;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
|
||||
err:
|
||||
|
@ -163,7 +163,7 @@ static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_cry
|
||||
|
||||
/* If the last flash_crypt_cnt bit is burned or write-disabled, the
|
||||
device can't re-encrypt itself. */
|
||||
if (flash_crypt_wr_dis || flash_crypt_cnt == 0xFF) {
|
||||
if (flash_crypt_wr_dis) {
|
||||
ESP_LOGE(TAG, "Cannot re-encrypt data (FLASH_CRYPT_CNT 0x%02x write disabled %d", flash_crypt_cnt, flash_crypt_wr_dis);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@ -200,11 +200,19 @@ static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_cry
|
||||
ESP_LOGD(TAG, "All flash regions checked for encryption pass");
|
||||
|
||||
/* Set least significant 0-bit in flash_crypt_cnt */
|
||||
int ffs_inv = __builtin_ffs((~flash_crypt_cnt) & 0xFF);
|
||||
/* ffs_inv shouldn't be zero, as zero implies flash_crypt_cnt == 0xFF */
|
||||
int ffs_inv = __builtin_ffs((~flash_crypt_cnt) & EFUSE_RD_FLASH_CRYPT_CNT);
|
||||
/* ffs_inv shouldn't be zero, as zero implies flash_crypt_cnt == EFUSE_RD_FLASH_CRYPT_CNT (0x7F) */
|
||||
uint32_t new_flash_crypt_cnt = flash_crypt_cnt + (1 << (ffs_inv - 1));
|
||||
ESP_LOGD(TAG, "FLASH_CRYPT_CNT 0x%x -> 0x%x", flash_crypt_cnt, new_flash_crypt_cnt);
|
||||
REG_SET_FIELD(EFUSE_BLK0_WDATA0_REG, EFUSE_FLASH_CRYPT_CNT, new_flash_crypt_cnt);
|
||||
|
||||
#ifdef CONFIG_FLASH_ENCRYPTION_DISABLE_PLAINTEXT
|
||||
ESP_LOGI(TAG, "Write protecting FLASH_CRYPT_CNT efuse...");
|
||||
REG_SET_BIT(EFUSE_BLK0_WDATA0_REG, EFUSE_WR_DIS_FLASH_CRYPT_CNT);
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling FLASH_CRYPT_CNT - plaintext flashing is still possible");
|
||||
#endif
|
||||
|
||||
esp_efuse_burn_new_values();
|
||||
|
||||
ESP_LOGI(TAG, "Flash encryption completed");
|
||||
@ -225,18 +233,18 @@ static esp_err_t encrypt_bootloader()
|
||||
return err;
|
||||
}
|
||||
|
||||
if (esp_secure_boot_enabled()) {
|
||||
/* If secure boot is enabled and bootloader was plaintext, also
|
||||
need to encrypt secure boot IV+digest.
|
||||
*/
|
||||
ESP_LOGD(TAG, "Encrypting secure bootloader IV & digest...");
|
||||
err = esp_flash_encrypt_region(FLASH_OFFS_SECURE_BOOT_IV_DIGEST,
|
||||
FLASH_SECTOR_SIZE);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to encrypt bootloader IV & digest in place: 0x%x", err);
|
||||
return err;
|
||||
}
|
||||
#ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
/* If secure boot is enabled and bootloader was plaintext, also
|
||||
* need to encrypt secure boot IV+digest.
|
||||
*/
|
||||
ESP_LOGD(TAG, "Encrypting secure bootloader IV & digest...");
|
||||
err = esp_flash_encrypt_region(FLASH_OFFS_SECURE_BOOT_IV_DIGEST,
|
||||
FLASH_SECTOR_SIZE);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to encrypt bootloader IV & digest in place: 0x%x", err);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
ESP_LOGW(TAG, "no valid bootloader was found");
|
||||
|
@ -36,6 +36,12 @@
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_efuse.h"
|
||||
|
||||
/* The following API implementations are used only when called
|
||||
* from the bootloader code.
|
||||
*/
|
||||
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
|
||||
static const char* TAG = "secure_boot";
|
||||
|
||||
/**
|
||||
@ -95,18 +101,15 @@ static bool secure_boot_generate(uint32_t image_len){
|
||||
/* Burn values written to the efuse write registers */
|
||||
static inline void burn_efuses()
|
||||
{
|
||||
#ifdef CONFIG_SECURE_BOOT_TEST_MODE
|
||||
ESP_LOGE(TAG, "SECURE BOOT TEST MODE. Not really burning any efuses! NOT SECURE");
|
||||
#else
|
||||
esp_efuse_burn_new_values();
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_err_t esp_secure_boot_permanently_enable(void) {
|
||||
esp_err_t esp_secure_boot_generate_digest(void)
|
||||
{
|
||||
esp_err_t err;
|
||||
if (esp_secure_boot_enabled())
|
||||
{
|
||||
ESP_LOGI(TAG, "bootloader secure boot is already enabled, continuing..");
|
||||
if (esp_secure_boot_enabled()) {
|
||||
ESP_LOGI(TAG, "bootloader secure boot is already enabled."
|
||||
" No need to generate digest. continuing..");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -124,6 +127,7 @@ esp_err_t esp_secure_boot_permanently_enable(void) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Generate secure boot key and keep in EFUSE */
|
||||
uint32_t dis_reg = REG_READ(EFUSE_BLK0_RDATA0_REG);
|
||||
bool efuse_key_read_protected = dis_reg & EFUSE_RD_DIS_BLK2;
|
||||
bool efuse_key_write_protected = dis_reg & EFUSE_WR_DIS_BLK2;
|
||||
@ -140,16 +144,11 @@ esp_err_t esp_secure_boot_permanently_enable(void) {
|
||||
ESP_LOGI(TAG, "Generating new secure boot key...");
|
||||
esp_efuse_write_random_key(EFUSE_BLK2_WDATA0_REG);
|
||||
burn_efuses();
|
||||
ESP_LOGI(TAG, "Read & write protecting new key...");
|
||||
REG_WRITE(EFUSE_BLK0_WDATA0_REG, EFUSE_WR_DIS_BLK2 | EFUSE_RD_DIS_BLK2);
|
||||
burn_efuses();
|
||||
efuse_key_read_protected = true;
|
||||
efuse_key_write_protected = true;
|
||||
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Using pre-loaded secure boot key in EFUSE block 2");
|
||||
}
|
||||
|
||||
/* Generate secure boot digest using programmed key in EFUSE */
|
||||
ESP_LOGI(TAG, "Generating secure boot digest...");
|
||||
uint32_t image_len = bootloader_data.image_len;
|
||||
if(bootloader_data.image.hash_appended) {
|
||||
@ -162,7 +161,28 @@ esp_err_t esp_secure_boot_permanently_enable(void) {
|
||||
}
|
||||
ESP_LOGI(TAG, "Digest generation complete.");
|
||||
|
||||
#ifndef CONFIG_SECURE_BOOT_TEST_MODE
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_secure_boot_permanently_enable(void)
|
||||
{
|
||||
if (esp_secure_boot_enabled()) {
|
||||
ESP_LOGI(TAG, "bootloader secure boot is already enabled, continuing..");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
uint32_t dis_reg = REG_READ(EFUSE_BLK0_RDATA0_REG);
|
||||
bool efuse_key_read_protected = dis_reg & EFUSE_RD_DIS_BLK2;
|
||||
bool efuse_key_write_protected = dis_reg & EFUSE_WR_DIS_BLK2;
|
||||
if (efuse_key_read_protected == false
|
||||
&& efuse_key_write_protected == false) {
|
||||
ESP_LOGI(TAG, "Read & write protecting new key...");
|
||||
REG_WRITE(EFUSE_BLK0_WDATA0_REG, EFUSE_WR_DIS_BLK2 | EFUSE_RD_DIS_BLK2);
|
||||
burn_efuses();
|
||||
efuse_key_read_protected = true;
|
||||
efuse_key_write_protected = true;
|
||||
}
|
||||
|
||||
if (!efuse_key_read_protected) {
|
||||
ESP_LOGE(TAG, "Pre-loaded key is not read protected. Refusing to blow secure boot efuse.");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
@ -171,7 +191,6 @@ esp_err_t esp_secure_boot_permanently_enable(void) {
|
||||
ESP_LOGE(TAG, "Pre-loaded key is not write protected. Refusing to blow secure boot efuse.");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
#endif
|
||||
|
||||
ESP_LOGI(TAG, "blowing secure boot efuse...");
|
||||
ESP_LOGD(TAG, "before updating, EFUSE_BLK0_RDATA6 %x", REG_READ(EFUSE_BLK0_RDATA6_REG));
|
||||
@ -200,11 +219,9 @@ esp_err_t esp_secure_boot_permanently_enable(void) {
|
||||
ESP_LOGI(TAG, "secure boot is now enabled for bootloader image");
|
||||
return ESP_OK;
|
||||
} else {
|
||||
#ifdef CONFIG_SECURE_BOOT_TEST_MODE
|
||||
ESP_LOGE(TAG, "secure boot not enabled due to test mode");
|
||||
#else
|
||||
ESP_LOGE(TAG, "secure boot not enabled for bootloader image, EFUSE_RD_ABS_DONE_0 is probably write protected!");
|
||||
#endif
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #ifdef BOOTLOADER_BUILD
|
||||
|
@ -21,12 +21,7 @@
|
||||
|
||||
#include "uECC.h"
|
||||
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
#include "rom/sha.h"
|
||||
typedef SHA_CTX sha_context;
|
||||
#else
|
||||
#include "hwcrypto/sha.h"
|
||||
#endif
|
||||
#include <sys/param.h>
|
||||
|
||||
static const char* TAG = "secure_boot";
|
||||
|
||||
@ -37,6 +32,9 @@ extern const uint8_t signature_verification_key_end[] asm("_binary_signature_ver
|
||||
|
||||
#define DIGEST_LEN 32
|
||||
|
||||
/* Mmap source address mask */
|
||||
#define MMAP_ALIGNED_MASK 0x0000FFFF
|
||||
|
||||
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
|
||||
{
|
||||
uint8_t digest[DIGEST_LEN];
|
||||
@ -45,26 +43,44 @@ esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
|
||||
|
||||
ESP_LOGD(TAG, "verifying signature src_addr 0x%x length 0x%x", src_addr, length);
|
||||
|
||||
data = bootloader_mmap(src_addr, length + sizeof(esp_secure_boot_sig_block_t));
|
||||
if(data == NULL) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr, length+sizeof(esp_secure_boot_sig_block_t));
|
||||
return ESP_FAIL;
|
||||
bootloader_sha256_handle_t handle = bootloader_sha256_start();
|
||||
|
||||
uint32_t free_page_count = bootloader_mmap_get_free_pages();
|
||||
ESP_LOGD(TAG, "free data page_count 0x%08x", free_page_count);
|
||||
|
||||
int32_t data_len_remain = length;
|
||||
uint32_t data_addr = src_addr;
|
||||
while (data_len_remain > 0) {
|
||||
uint32_t offset_page = ((data_addr & MMAP_ALIGNED_MASK) != 0) ? 1 : 0;
|
||||
/* Data we could map in case we are not aligned to PAGE boundary is one page size lesser. */
|
||||
uint32_t data_len = MIN(data_len_remain, ((free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE));
|
||||
data = (const uint8_t *) bootloader_mmap(data_addr, data_len);
|
||||
if(!data) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", data_addr, data_len);
|
||||
bootloader_sha256_finish(handle, NULL);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
bootloader_sha256_data(handle, data, data_len);
|
||||
bootloader_munmap(data);
|
||||
|
||||
data_addr += data_len;
|
||||
data_len_remain -= data_len;
|
||||
}
|
||||
|
||||
// Calculate digest of main image
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
bootloader_sha256_handle_t handle = bootloader_sha256_start();
|
||||
bootloader_sha256_data(handle, data, length);
|
||||
/* Done! Get the digest */
|
||||
bootloader_sha256_finish(handle, digest);
|
||||
#else
|
||||
/* Use thread-safe esp-idf SHA function */
|
||||
esp_sha(SHA2_256, data, length, digest);
|
||||
#endif
|
||||
|
||||
// Map the signature block and verify the signature
|
||||
sigblock = (const esp_secure_boot_sig_block_t *)(data + length);
|
||||
// Map the signature block
|
||||
sigblock = (const esp_secure_boot_sig_block_t *) bootloader_mmap(src_addr + length, sizeof(esp_secure_boot_sig_block_t));
|
||||
if(!sigblock) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr + length, sizeof(esp_secure_boot_sig_block_t));
|
||||
return ESP_FAIL;
|
||||
}
|
||||
// Verify the signature
|
||||
esp_err_t err = esp_secure_boot_verify_signature_block(sigblock, digest);
|
||||
bootloader_munmap(data);
|
||||
// Unmap
|
||||
bootloader_munmap(sigblock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
if(CONFIG_BT_ENABLED)
|
||||
|
||||
set(COMPONENT_SRCS "bt.c")
|
||||
set(COMPONENT_SRCS "bt.c"
|
||||
"hli_api.c")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS include)
|
||||
|
||||
if(CONFIG_BLUEDROID_ENABLED)
|
||||
@ -21,6 +22,7 @@ if(CONFIG_BT_ENABLED)
|
||||
bluedroid/osi/include
|
||||
bluedroid/external/sbc/decoder/include
|
||||
bluedroid/external/sbc/encoder/include
|
||||
bluedroid/external/sbc/plc/include
|
||||
bluedroid/btc/profile/esp/blufi/include
|
||||
bluedroid/btc/profile/esp/include
|
||||
bluedroid/btc/profile/std/a2dp/include
|
||||
@ -94,6 +96,14 @@ if(CONFIG_BT_ENABLED)
|
||||
"bluedroid/bta/jv/bta_jv_api.c"
|
||||
"bluedroid/bta/jv/bta_jv_cfg.c"
|
||||
"bluedroid/bta/jv/bta_jv_main.c"
|
||||
"bluedroid/bta/hf_client/bta_hf_client_act.c"
|
||||
"bluedroid/bta/hf_client/bta_hf_client_api.c"
|
||||
"bluedroid/bta/hf_client/bta_hf_client_at.c"
|
||||
"bluedroid/bta/hf_client/bta_hf_client_cmd.c"
|
||||
"bluedroid/bta/hf_client/bta_hf_client_main.c"
|
||||
"bluedroid/bta/hf_client/bta_hf_client_rfc.c"
|
||||
"bluedroid/bta/hf_client/bta_hf_client_sco.c"
|
||||
"bluedroid/bta/hf_client/bta_hf_client_sdp.c"
|
||||
"bluedroid/bta/sdp/bta_sdp.c"
|
||||
"bluedroid/bta/sdp/bta_sdp_act.c"
|
||||
"bluedroid/bta/sdp/bta_sdp_api.c"
|
||||
@ -123,6 +133,9 @@ if(CONFIG_BT_ENABLED)
|
||||
"bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c"
|
||||
"bluedroid/btc/profile/std/a2dp/btc_av.c"
|
||||
"bluedroid/btc/profile/std/avrc/btc_avrc.c"
|
||||
"bluedroid/btc/profile/std/avrc/bta_avrc_co.c"
|
||||
"bluedroid/btc/profile/std/hf_client/btc_hf_client.c"
|
||||
"bluedroid/btc/profile/std/hf_client/bta_hf_client_co.c"
|
||||
"bluedroid/btc/profile/std/gap/btc_gap_ble.c"
|
||||
"bluedroid/btc/profile/std/gap/btc_gap_bt.c"
|
||||
"bluedroid/btc/profile/std/gatt/btc_gatt_common.c"
|
||||
@ -155,6 +168,7 @@ if(CONFIG_BT_ENABLED)
|
||||
"bluedroid/external/sbc/encoder/srce/sbc_enc_coeffs.c"
|
||||
"bluedroid/external/sbc/encoder/srce/sbc_encoder.c"
|
||||
"bluedroid/external/sbc/encoder/srce/sbc_packing.c"
|
||||
"bluedroid/external/sbc/plc/sbc_plc.c"
|
||||
"bluedroid/hci/hci_audio.c"
|
||||
"bluedroid/hci/hci_hal_h4.c"
|
||||
"bluedroid/hci/hci_layer.c"
|
||||
@ -269,11 +283,96 @@ if(CONFIG_BT_ENABLED)
|
||||
"bluedroid/stack/smp/smp_l2c.c"
|
||||
"bluedroid/stack/smp/smp_main.c"
|
||||
"bluedroid/stack/smp/smp_utils.c")
|
||||
|
||||
if(CONFIG_BLE_MESH)
|
||||
list(APPEND COMPONENT_ADD_INCLUDEDIRS bluedroid/osi/include)
|
||||
list(APPEND COMPONENT_SRCS "esp_ble_mesh/mesh_core/bluedroid_host/mesh_bearer_adapt.c")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if(CONFIG_BLE_MESH)
|
||||
list(APPEND COMPONENT_ADD_INCLUDEDIRS
|
||||
"esp_ble_mesh/mesh_common/include"
|
||||
"esp_ble_mesh/mesh_core"
|
||||
"esp_ble_mesh/mesh_core/include"
|
||||
"esp_ble_mesh/mesh_core/storage"
|
||||
"esp_ble_mesh/btc/include"
|
||||
"esp_ble_mesh/mesh_models/common/include"
|
||||
"esp_ble_mesh/mesh_models/client/include"
|
||||
"esp_ble_mesh/mesh_models/server/include"
|
||||
"esp_ble_mesh/api/core/include"
|
||||
"esp_ble_mesh/api/models/include"
|
||||
"esp_ble_mesh/api")
|
||||
|
||||
list(APPEND COMPONENT_SRCS
|
||||
"esp_ble_mesh/api/core/esp_ble_mesh_ble_api.c"
|
||||
"esp_ble_mesh/api/core/esp_ble_mesh_common_api.c"
|
||||
"esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c"
|
||||
"esp_ble_mesh/api/core/esp_ble_mesh_low_power_api.c"
|
||||
"esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c"
|
||||
"esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c"
|
||||
"esp_ble_mesh/api/core/esp_ble_mesh_proxy_api.c"
|
||||
"esp_ble_mesh/api/models/esp_ble_mesh_config_model_api.c"
|
||||
"esp_ble_mesh/api/models/esp_ble_mesh_generic_model_api.c"
|
||||
"esp_ble_mesh/api/models/esp_ble_mesh_health_model_api.c"
|
||||
"esp_ble_mesh/api/models/esp_ble_mesh_lighting_model_api.c"
|
||||
"esp_ble_mesh/api/models/esp_ble_mesh_sensor_model_api.c"
|
||||
"esp_ble_mesh/api/models/esp_ble_mesh_time_scene_model_api.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_ble.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_config_model.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_generic_model.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_health_model.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_lighting_model.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_prov.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_sensor_model.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_time_scene_model.c"
|
||||
"esp_ble_mesh/mesh_common/mesh_aes_encrypt.c"
|
||||
"esp_ble_mesh/mesh_common/mesh_atomic.c"
|
||||
"esp_ble_mesh/mesh_common/mesh_buf.c"
|
||||
"esp_ble_mesh/mesh_common/mesh_common.c"
|
||||
"esp_ble_mesh/mesh_common/mesh_kernel.c"
|
||||
"esp_ble_mesh/mesh_common/mesh_util.c"
|
||||
"esp_ble_mesh/mesh_core/storage/settings_nvs.c"
|
||||
"esp_ble_mesh/mesh_core/access.c"
|
||||
"esp_ble_mesh/mesh_core/adv.c"
|
||||
"esp_ble_mesh/mesh_core/beacon.c"
|
||||
"esp_ble_mesh/mesh_core/cfg_cli.c"
|
||||
"esp_ble_mesh/mesh_core/cfg_srv.c"
|
||||
"esp_ble_mesh/mesh_core/crypto.c"
|
||||
"esp_ble_mesh/mesh_core/friend.c"
|
||||
"esp_ble_mesh/mesh_core/health_cli.c"
|
||||
"esp_ble_mesh/mesh_core/health_srv.c"
|
||||
"esp_ble_mesh/mesh_core/local_operation.c"
|
||||
"esp_ble_mesh/mesh_core/lpn.c"
|
||||
"esp_ble_mesh/mesh_core/main.c"
|
||||
"esp_ble_mesh/mesh_core/net.c"
|
||||
"esp_ble_mesh/mesh_core/prov.c"
|
||||
"esp_ble_mesh/mesh_core/provisioner_main.c"
|
||||
"esp_ble_mesh/mesh_core/provisioner_prov.c"
|
||||
"esp_ble_mesh/mesh_core/proxy_client.c"
|
||||
"esp_ble_mesh/mesh_core/proxy_server.c"
|
||||
"esp_ble_mesh/mesh_core/settings.c"
|
||||
"esp_ble_mesh/mesh_core/test.c"
|
||||
"esp_ble_mesh/mesh_core/transport.c"
|
||||
"esp_ble_mesh/mesh_models/client/client_common.c"
|
||||
"esp_ble_mesh/mesh_models/client/generic_client.c"
|
||||
"esp_ble_mesh/mesh_models/client/lighting_client.c"
|
||||
"esp_ble_mesh/mesh_models/client/sensor_client.c"
|
||||
"esp_ble_mesh/mesh_models/client/time_scene_client.c"
|
||||
"esp_ble_mesh/mesh_models/server/device_property.c"
|
||||
"esp_ble_mesh/mesh_models/server/generic_server.c"
|
||||
"esp_ble_mesh/mesh_models/server/lighting_server.c"
|
||||
"esp_ble_mesh/mesh_models/server/sensor_server.c"
|
||||
"esp_ble_mesh/mesh_models/server/server_common.c"
|
||||
"esp_ble_mesh/mesh_models/server/state_binding.c"
|
||||
"esp_ble_mesh/mesh_models/server/state_transition.c"
|
||||
"esp_ble_mesh/mesh_models/server/time_scene_server.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# requirements can't depend on config
|
||||
set(COMPONENT_PRIV_REQUIRES nvs_flash)
|
||||
set(COMPONENT_PRIV_REQUIRES nvs_flash nimble)
|
||||
|
||||
register_component()
|
||||
|
||||
@ -284,4 +383,6 @@ if(CONFIG_BT_ENABLED)
|
||||
|
||||
target_link_libraries(${COMPONENT_TARGET} "-L${CMAKE_CURRENT_LIST_DIR}/lib")
|
||||
target_link_libraries(${COMPONENT_TARGET} btdm_app)
|
||||
|
||||
target_link_libraries(${COMPONENT_TARGET} "-u ld_include_hli_vectors_bt")
|
||||
endif()
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -32,7 +32,7 @@ esp_err_t esp_avrc_ct_register_callback(esp_avrc_ct_cb_t callback)
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
btc_profile_cb_set(BTC_PID_AVRC, callback);
|
||||
btc_profile_cb_set(BTC_PID_AVRC_CT, callback);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -45,8 +45,8 @@ esp_err_t esp_avrc_ct_init(void)
|
||||
btc_msg_t msg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC;
|
||||
msg.act = BTC_AVRC_CTRL_API_INIT_EVT;
|
||||
msg.pid = BTC_PID_AVRC_CT;
|
||||
msg.act = BTC_AVRC_CT_API_INIT_EVT;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
@ -62,8 +62,8 @@ esp_err_t esp_avrc_ct_deinit(void)
|
||||
btc_msg_t msg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC;
|
||||
msg.act = BTC_AVRC_CTRL_API_DEINIT_EVT;
|
||||
msg.pid = BTC_PID_AVRC_CT;
|
||||
msg.act = BTC_AVRC_CT_API_DEINIT_EVT;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
@ -82,8 +82,8 @@ esp_err_t esp_avrc_ct_send_set_player_value_cmd(uint8_t tl, uint8_t attr_id, uin
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC;
|
||||
msg.act = BTC_AVRC_CTRL_API_SET_PLAYER_SETTING_EVT;
|
||||
msg.pid = BTC_PID_AVRC_CT;
|
||||
msg.act = BTC_AVRC_CTRL_API_SND_SET_PLAYER_SETTING_EVT;
|
||||
|
||||
btc_avrc_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_avrc_args_t));
|
||||
@ -97,6 +97,30 @@ esp_err_t esp_avrc_ct_send_set_player_value_cmd(uint8_t tl, uint8_t attr_id, uin
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_avrc_ct_send_get_rn_capabilities_cmd(uint8_t tl)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (tl >= 16) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC_CT;
|
||||
msg.act = BTC_AVRC_STATUS_API_SND_GET_RN_CAPS_EVT;
|
||||
|
||||
btc_avrc_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_avrc_args_t));
|
||||
|
||||
arg.get_caps_cmd.tl = tl;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_avrc_ct_send_register_notification_cmd(uint8_t tl, uint8_t event_id, uint32_t event_parameter)
|
||||
{
|
||||
@ -108,9 +132,13 @@ esp_err_t esp_avrc_ct_send_register_notification_cmd(uint8_t tl, uint8_t event_i
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (!btc_avrc_ct_rn_evt_supported(event_id)) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC;
|
||||
msg.pid = BTC_PID_AVRC_CT;
|
||||
msg.act = BTC_AVRC_NOTIFY_API_SND_REG_NOTIFY_EVT;
|
||||
|
||||
btc_avrc_args_t arg;
|
||||
@ -137,7 +165,7 @@ esp_err_t esp_avrc_ct_send_metadata_cmd(uint8_t tl, uint8_t attr_mask)
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC;
|
||||
msg.pid = BTC_PID_AVRC_CT;
|
||||
msg.act = BTC_AVRC_STATUS_API_SND_META_EVT;
|
||||
|
||||
btc_avrc_args_t arg;
|
||||
@ -163,7 +191,7 @@ esp_err_t esp_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC;
|
||||
msg.pid = BTC_PID_AVRC_CT;
|
||||
msg.act = BTC_AVRC_CTRL_API_SND_PTCMD_EVT;
|
||||
|
||||
btc_avrc_args_t arg;
|
||||
@ -178,4 +206,246 @@ esp_err_t esp_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
/** following is the API of AVRCP target role **/
|
||||
/*********************************************************************************************/
|
||||
|
||||
esp_err_t esp_avrc_tg_register_callback(esp_avrc_tg_cb_t callback)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (callback == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
btc_profile_cb_set(BTC_PID_AVRC_TG, callback);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_avrc_tg_init(void)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC_TG;
|
||||
msg.act = BTC_AVRC_TG_API_INIT_EVT;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_avrc_tg_deinit(void)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC_TG;
|
||||
msg.act = BTC_AVRC_TG_API_DEINIT_EVT;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
bool esp_avrc_psth_bit_mask_operation(esp_avrc_bit_mask_op_t op, esp_avrc_psth_bit_mask_t *psth,
|
||||
esp_avrc_pt_cmd_t cmd)
|
||||
{
|
||||
if (!psth ||
|
||||
cmd > ESP_AVRC_PT_CMD_VENDOR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t *p = &psth->bits[(uint8_t)cmd >> 4];
|
||||
uint16_t mask = (uint16_t)1 << ((uint8_t)cmd & 0x0F);
|
||||
switch (op) {
|
||||
case ESP_AVRC_BIT_MASK_OP_SET:
|
||||
*p |= mask;
|
||||
break;
|
||||
case ESP_AVRC_BIT_MASK_OP_CLEAR:
|
||||
*p &= ~mask;
|
||||
break;
|
||||
case ESP_AVRC_BIT_MASK_OP_TEST:
|
||||
return (*p & mask);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
esp_err_t esp_avrc_tg_get_psth_cmd_filter(esp_avrc_psth_filter_t filter, esp_avrc_psth_bit_mask_t *cmd_set)
|
||||
{
|
||||
if ((esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) ||
|
||||
(! btc_avrc_tg_init_p())) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
if (filter >= ESP_AVRC_PSTH_FILTER_SUPPORT_MAX ||
|
||||
cmd_set == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (filter == ESP_AVRC_PSTH_FILTER_ALLOWED_CMD) {
|
||||
const uint16_t *allowed_cmd_set = btc_avrc_tg_get_allowed_command();
|
||||
memcpy(cmd_set, allowed_cmd_set, sizeof(esp_avrc_psth_bit_mask_t));
|
||||
} else if (filter == ESP_AVRC_PSTH_FILTER_SUPPORTED_CMD) {
|
||||
const uint16_t *supported_cmd_set = btc_avrc_tg_get_supported_command();
|
||||
memcpy(cmd_set, supported_cmd_set, sizeof(esp_avrc_psth_bit_mask_t));
|
||||
} else {
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_avrc_tg_set_psth_cmd_filter(esp_avrc_psth_filter_t filter, const esp_avrc_psth_bit_mask_t *cmd_set)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
if (filter >= ESP_AVRC_PSTH_FILTER_SUPPORT_MAX ||
|
||||
cmd_set == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (filter == ESP_AVRC_PSTH_FILTER_ALLOWED_CMD) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
if (filter == ESP_AVRC_PSTH_FILTER_SUPPORTED_CMD) {
|
||||
bool allowed = btc_avrc_tg_check_supported_command(cmd_set->bits);
|
||||
if (!allowed) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC_TG;
|
||||
msg.act = BTC_AVRC_TG_API_SET_PSTH_SUPPORTED_CMD_EVT;
|
||||
|
||||
btc_avrc_tg_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_avrc_tg_args_t));
|
||||
arg.set_psth_cmd = (uint16_t *)cmd_set->bits;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_tg_args_t),
|
||||
btc_avrc_tg_arg_deep_copy);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
} else {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t esp_avrc_tg_get_rn_evt_cap(esp_avrc_rn_evt_cap_t cap, esp_avrc_rn_evt_cap_mask_t *evt_set)
|
||||
{
|
||||
if ((esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) ||
|
||||
(! btc_avrc_tg_init_p())) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
if (cap >= ESP_AVRC_RN_CAP_MAX ||
|
||||
evt_set == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (cap == ESP_AVRC_RN_CAP_ALLOWED_EVT) {
|
||||
evt_set->bits = btc_avrc_tg_get_rn_allowed_evt();
|
||||
} else if (cap == ESP_AVRC_RN_CAP_SUPPORTED_EVT) {
|
||||
evt_set->bits = btc_avrc_tg_get_rn_supported_evt();
|
||||
} else {
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_avrc_tg_set_rn_evt_cap(const esp_avrc_rn_evt_cap_mask_t *evt_set)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
if (evt_set == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
bool allowed = btc_avrc_tg_check_rn_supported_evt(evt_set->bits);
|
||||
if (!allowed) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC_TG;
|
||||
msg.act = BTC_AVRC_TG_API_SET_RN_SUPPORTED_EVT;
|
||||
|
||||
btc_avrc_tg_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_avrc_tg_args_t));
|
||||
|
||||
arg.set_rn_evt = evt_set->bits;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_tg_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
bool esp_avrc_rn_evt_bit_mask_operation(esp_avrc_bit_mask_op_t op, esp_avrc_rn_evt_cap_mask_t *events,
|
||||
esp_avrc_rn_event_ids_t event_id)
|
||||
{
|
||||
if (!events ||
|
||||
event_id >= ESP_AVRC_RN_MAX_EVT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t *p = &events->bits;
|
||||
uint16_t mask = (uint16_t)1 << ((uint8_t)event_id & 0x0F);
|
||||
switch (op) {
|
||||
case ESP_AVRC_BIT_MASK_OP_SET:
|
||||
*p |= mask;
|
||||
break;
|
||||
case ESP_AVRC_BIT_MASK_OP_CLEAR:
|
||||
*p &= ~mask;
|
||||
break;
|
||||
case ESP_AVRC_BIT_MASK_OP_TEST:
|
||||
return (*p & mask);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
esp_err_t esp_avrc_tg_send_rn_rsp(esp_avrc_rn_event_ids_t event_id, esp_avrc_rn_rsp_t rsp,
|
||||
esp_avrc_rn_param_t *param)
|
||||
{
|
||||
if ((esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) ||
|
||||
(! btc_avrc_tg_connected_p())) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if ( ! btc_avrc_tg_rn_evt_supported((uint8_t)event_id)) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC_TG;
|
||||
msg.act = BTC_AVRC_TG_API_SEND_RN_RSP_EVT;
|
||||
|
||||
btc_avrc_tg_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_avrc_tg_args_t));
|
||||
|
||||
arg.rn_rsp.event_id = event_id;
|
||||
arg.rn_rsp.rsp = rsp;
|
||||
memcpy(&arg.rn_rsp.param, param, sizeof(esp_avrc_rn_param_t));
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_tg_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
|
||||
}
|
||||
|
||||
#endif /* #if BTC_AV_INCLUDED */
|
||||
|
@ -457,7 +457,7 @@ esp_err_t esp_ble_gap_add_duplicate_scan_exceptional_device(esp_ble_duplicate_ex
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
if (!device_info){
|
||||
if (!device_info && type <= ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_LINK_ID) {
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
@ -465,7 +465,9 @@ esp_err_t esp_ble_gap_add_duplicate_scan_exceptional_device(esp_ble_duplicate_ex
|
||||
msg.act = BTC_GAP_BLE_UPDATE_DUPLICATE_SCAN_EXCEPTIONAL_LIST;
|
||||
arg.update_duplicate_exceptional_list.subcode = ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_ADD;
|
||||
arg.update_duplicate_exceptional_list.info_type = type;
|
||||
memcpy(arg.update_duplicate_exceptional_list.device_info, device_info, sizeof(esp_bd_addr_t));
|
||||
if (device_info) {
|
||||
memcpy(arg.update_duplicate_exceptional_list.device_info, device_info, sizeof(esp_bd_addr_t));
|
||||
}
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
@ -479,7 +481,7 @@ esp_err_t esp_ble_gap_remove_duplicate_scan_exceptional_device(esp_ble_duplicate
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
if (!device_info){
|
||||
if (!device_info && type <= ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_LINK_ID) {
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
@ -487,7 +489,9 @@ esp_err_t esp_ble_gap_remove_duplicate_scan_exceptional_device(esp_ble_duplicate
|
||||
msg.act = BTC_GAP_BLE_UPDATE_DUPLICATE_SCAN_EXCEPTIONAL_LIST;
|
||||
arg.update_duplicate_exceptional_list.subcode = ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_REMOVE;
|
||||
arg.update_duplicate_exceptional_list.info_type = type;
|
||||
memcpy(arg.update_duplicate_exceptional_list.device_info, device_info, sizeof(esp_bd_addr_t));
|
||||
if (device_info) {
|
||||
memcpy(arg.update_duplicate_exceptional_list.device_info, device_info, sizeof(esp_bd_addr_t));
|
||||
}
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
|
@ -89,6 +89,7 @@ typedef enum {
|
||||
ESP_A2D_AUDIO_STATE_EVT, /*!< audio stream transmission state changed event */
|
||||
ESP_A2D_AUDIO_CFG_EVT, /*!< audio codec is configured, only used for A2DP SINK */
|
||||
ESP_A2D_MEDIA_CTRL_ACK_EVT, /*!< acknowledge event in response to media control commands */
|
||||
ESP_A2D_PROF_STATE_EVT, /*!< indicate a2dp deinit complete */
|
||||
} esp_a2d_cb_event_t;
|
||||
|
||||
/// A2DP state callback parameters
|
||||
@ -125,6 +126,13 @@ typedef union {
|
||||
esp_a2d_media_ctrl_t cmd; /*!< media control commands to acknowledge */
|
||||
esp_a2d_media_ctrl_ack_t status; /*!< acknowledgement to media control commands */
|
||||
} media_ctrl_stat; /*!< status in acknowledgement to media control commands */
|
||||
|
||||
/**
|
||||
* @brief ESP_A2D_PROF_STATE_EVT
|
||||
*/
|
||||
struct a2d_prof_stat_param {
|
||||
int init_state; /*!< a2dp profile state param */
|
||||
} a2d_prof_stat; /*!< status to indicate a2d prof init or deinit */
|
||||
} esp_a2d_cb_param_t;
|
||||
|
||||
/**
|
||||
|
@ -34,17 +34,97 @@ typedef enum {
|
||||
ESP_AVRC_FEAT_ADV_CTRL = 0x0200, /*!< remote control advanced control commmand/response */
|
||||
} esp_avrc_features_t;
|
||||
|
||||
/// AVRC supported features flag retrieved in SDP record
|
||||
typedef enum {
|
||||
ESP_AVRC_FEAT_FLAG_CAT1 = 0x0001, /*!< category 1 */
|
||||
ESP_AVRC_FEAT_FLAG_CAT2 = 0x0002, /*!< category 2 */
|
||||
ESP_AVRC_FEAT_FLAG_CAT3 = 0x0004, /*!< category 3 */
|
||||
ESP_AVRC_FEAT_FLAG_CAT4 = 0x0008, /*!< category 4 */
|
||||
ESP_AVRC_FEAT_FLAG_BROWSING = 0x0040, /*!< browsing */
|
||||
ESP_AVRC_FEAT_FLAG_COVER_ART_GET_IMAGE_PROP = 0x0080, /*!< Cover Art GetImageProperties */
|
||||
ESP_AVRC_FEAT_FLAG_COVER_ART_GET_IMAGE = 0x0100, /*!< Cover Art GetImage */
|
||||
ESP_AVRC_FEAT_FLAG_COVER_ART_GET_LINKED_THUMBNAIL = 0x0200, /*!< Cover Art GetLinkedThumbnail */
|
||||
} esp_avrc_feature_flag_t;
|
||||
|
||||
/// AVRC passthrough command code
|
||||
typedef enum {
|
||||
ESP_AVRC_PT_CMD_PLAY = 0x44, /*!< play */
|
||||
ESP_AVRC_PT_CMD_STOP = 0x45, /*!< stop */
|
||||
ESP_AVRC_PT_CMD_PAUSE = 0x46, /*!< pause */
|
||||
ESP_AVRC_PT_CMD_FORWARD = 0x4B, /*!< forward */
|
||||
ESP_AVRC_PT_CMD_BACKWARD = 0x4C, /*!< backward */
|
||||
ESP_AVRC_PT_CMD_REWIND = 0x48, /*!< rewind */
|
||||
ESP_AVRC_PT_CMD_FAST_FORWARD = 0x49 /*!< fast forward */
|
||||
ESP_AVRC_PT_CMD_SELECT = 0x00, /*!< select */
|
||||
ESP_AVRC_PT_CMD_UP = 0x01, /*!< up */
|
||||
ESP_AVRC_PT_CMD_DOWN = 0x02, /*!< down */
|
||||
ESP_AVRC_PT_CMD_LEFT = 0x03, /*!< left */
|
||||
ESP_AVRC_PT_CMD_RIGHT = 0x04, /*!< right */
|
||||
ESP_AVRC_PT_CMD_RIGHT_UP = 0x05, /*!< right-up */
|
||||
ESP_AVRC_PT_CMD_RIGHT_DOWN = 0x06, /*!< right-down */
|
||||
ESP_AVRC_PT_CMD_LEFT_UP = 0x07, /*!< left-up */
|
||||
ESP_AVRC_PT_CMD_LEFT_DOWN = 0x08, /*!< left-down */
|
||||
ESP_AVRC_PT_CMD_ROOT_MENU = 0x09, /*!< root menu */
|
||||
ESP_AVRC_PT_CMD_SETUP_MENU = 0x0A, /*!< setup menu */
|
||||
ESP_AVRC_PT_CMD_CONT_MENU = 0x0B, /*!< contents menu */
|
||||
ESP_AVRC_PT_CMD_FAV_MENU = 0x0C, /*!< favorite menu */
|
||||
ESP_AVRC_PT_CMD_EXIT = 0x0D, /*!< exit */
|
||||
ESP_AVRC_PT_CMD_0 = 0x20, /*!< 0 */
|
||||
ESP_AVRC_PT_CMD_1 = 0x21, /*!< 1 */
|
||||
ESP_AVRC_PT_CMD_2 = 0x22, /*!< 2 */
|
||||
ESP_AVRC_PT_CMD_3 = 0x23, /*!< 3 */
|
||||
ESP_AVRC_PT_CMD_4 = 0x24, /*!< 4 */
|
||||
ESP_AVRC_PT_CMD_5 = 0x25, /*!< 5 */
|
||||
ESP_AVRC_PT_CMD_6 = 0x26, /*!< 6 */
|
||||
ESP_AVRC_PT_CMD_7 = 0x27, /*!< 7 */
|
||||
ESP_AVRC_PT_CMD_8 = 0x28, /*!< 8 */
|
||||
ESP_AVRC_PT_CMD_9 = 0x29, /*!< 9 */
|
||||
ESP_AVRC_PT_CMD_DOT = 0x2A, /*!< dot */
|
||||
ESP_AVRC_PT_CMD_ENTER = 0x2B, /*!< enter */
|
||||
ESP_AVRC_PT_CMD_CLEAR = 0x2C, /*!< clear */
|
||||
ESP_AVRC_PT_CMD_CHAN_UP = 0x30, /*!< channel up */
|
||||
ESP_AVRC_PT_CMD_CHAN_DOWN = 0x31, /*!< channel down */
|
||||
ESP_AVRC_PT_CMD_PREV_CHAN = 0x32, /*!< previous channel */
|
||||
ESP_AVRC_PT_CMD_SOUND_SEL = 0x33, /*!< sound select */
|
||||
ESP_AVRC_PT_CMD_INPUT_SEL = 0x34, /*!< input select */
|
||||
ESP_AVRC_PT_CMD_DISP_INFO = 0x35, /*!< display information */
|
||||
ESP_AVRC_PT_CMD_HELP = 0x36, /*!< help */
|
||||
ESP_AVRC_PT_CMD_PAGE_UP = 0x37, /*!< page up */
|
||||
ESP_AVRC_PT_CMD_PAGE_DOWN = 0x38, /*!< page down */
|
||||
ESP_AVRC_PT_CMD_POWER = 0x40, /*!< power */
|
||||
ESP_AVRC_PT_CMD_VOL_UP = 0x41, /*!< volume up */
|
||||
ESP_AVRC_PT_CMD_VOL_DOWN = 0x42, /*!< volume down */
|
||||
ESP_AVRC_PT_CMD_MUTE = 0x43, /*!< mute */
|
||||
ESP_AVRC_PT_CMD_PLAY = 0x44, /*!< play */
|
||||
ESP_AVRC_PT_CMD_STOP = 0x45, /*!< stop */
|
||||
ESP_AVRC_PT_CMD_PAUSE = 0x46, /*!< pause */
|
||||
ESP_AVRC_PT_CMD_RECORD = 0x47, /*!< record */
|
||||
ESP_AVRC_PT_CMD_REWIND = 0x48, /*!< rewind */
|
||||
ESP_AVRC_PT_CMD_FAST_FORWARD = 0x49, /*!< fast forward */
|
||||
ESP_AVRC_PT_CMD_EJECT = 0x4A, /*!< eject */
|
||||
ESP_AVRC_PT_CMD_FORWARD = 0x4B, /*!< forward */
|
||||
ESP_AVRC_PT_CMD_BACKWARD = 0x4C, /*!< backward */
|
||||
ESP_AVRC_PT_CMD_ANGLE = 0x50, /*!< angle */
|
||||
ESP_AVRC_PT_CMD_SUBPICT = 0x51, /*!< subpicture */
|
||||
ESP_AVRC_PT_CMD_F1 = 0x71, /*!< F1 */
|
||||
ESP_AVRC_PT_CMD_F2 = 0x72, /*!< F2 */
|
||||
ESP_AVRC_PT_CMD_F3 = 0x73, /*!< F3 */
|
||||
ESP_AVRC_PT_CMD_F4 = 0x74, /*!< F4 */
|
||||
ESP_AVRC_PT_CMD_F5 = 0x75, /*!< F5 */
|
||||
ESP_AVRC_PT_CMD_VENDOR = 0x7E, /*!< vendor unique */
|
||||
} esp_avrc_pt_cmd_t;
|
||||
|
||||
/// AVRC passthrough command filter
|
||||
typedef enum {
|
||||
ESP_AVRC_PSTH_FILTER_ALLOWED_CMD = 0, /*!< all of the PASSTHROUGH commands that can possibly be used, immuateble */
|
||||
ESP_AVRC_PSTH_FILTER_SUPPORTED_CMD = 1, /*!< PASSTHROUGH commands selectively supported according to the current configuration */
|
||||
ESP_AVRC_PSTH_FILTER_SUPPORT_MAX,
|
||||
} esp_avrc_psth_filter_t;
|
||||
|
||||
/// AVRC passthrough command bit mask
|
||||
typedef struct {
|
||||
uint16_t bits[8]; /*!< bit mask representation of PASSTHROUGH commands */
|
||||
} esp_avrc_psth_bit_mask_t;
|
||||
|
||||
typedef enum {
|
||||
ESP_AVRC_BIT_MASK_OP_TEST = 0, /*!< operation code to test a specific bit */
|
||||
ESP_AVRC_BIT_MASK_OP_SET = 1, /*!< operation code to set a specific bit */
|
||||
ESP_AVRC_BIT_MASK_OP_CLEAR = 2, /*!< operation code to clear a specific bit */
|
||||
} esp_avrc_bit_mask_op_t;
|
||||
|
||||
/// AVRC passthrough command state
|
||||
typedef enum {
|
||||
ESP_AVRC_PT_CMD_STATE_PRESSED = 0, /*!< key pressed */
|
||||
@ -59,8 +139,18 @@ typedef enum {
|
||||
ESP_AVRC_CT_PLAY_STATUS_RSP_EVT = 3, /*!< play status response event */
|
||||
ESP_AVRC_CT_CHANGE_NOTIFY_EVT = 4, /*!< notification event */
|
||||
ESP_AVRC_CT_REMOTE_FEATURES_EVT = 5, /*!< feature of remote device indication event */
|
||||
ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT = 6, /*!< supported notification events capability of peer device */
|
||||
} esp_avrc_ct_cb_event_t;
|
||||
|
||||
/// AVRC Target callback events
|
||||
typedef enum {
|
||||
ESP_AVRC_TG_CONNECTION_STATE_EVT = 0, /*!< connection state changed event */
|
||||
ESP_AVRC_TG_REMOTE_FEATURES_EVT = 1, /*!< feature of remote device indication event */
|
||||
ESP_AVRC_TG_PASSTHROUGH_CMD_EVT = 2, /*!< passthrough command event */
|
||||
ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT = 3, /*!< set absolute volume command from remote device */
|
||||
ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT = 4, /*!< register notification event */
|
||||
} esp_avrc_tg_cb_event_t;
|
||||
|
||||
/// AVRC metadata attribute mask
|
||||
typedef enum {
|
||||
ESP_AVRC_MD_ATTR_TITLE = 0x1, /*!< title of the playing track */
|
||||
@ -82,9 +172,32 @@ typedef enum {
|
||||
ESP_AVRC_RN_BATTERY_STATUS_CHANGE = 0x06, /*!< battery status changed */
|
||||
ESP_AVRC_RN_SYSTEM_STATUS_CHANGE = 0x07, /*!< system status changed */
|
||||
ESP_AVRC_RN_APP_SETTING_CHANGE = 0x08, /*!< application settings changed */
|
||||
ESP_AVRC_RN_NOW_PLAYING_CHANGE = 0x09, /*!< now playing content changed */
|
||||
ESP_AVRC_RN_AVAILABLE_PLAYERS_CHANGE = 0x0a, /*!< available players changed */
|
||||
ESP_AVRC_RN_ADDRESSED_PLAYER_CHANGE = 0x0b, /*!< the addressed player changed */
|
||||
ESP_AVRC_RN_UIDS_CHANGE = 0x0c, /*!< UIDs changed */
|
||||
ESP_AVRC_RN_VOLUME_CHANGE = 0x0d, /*!< volume changed locally on TG */
|
||||
ESP_AVRC_RN_MAX_EVT
|
||||
} esp_avrc_rn_event_ids_t;
|
||||
|
||||
/// AVRC target notification event notification capability
|
||||
typedef enum {
|
||||
ESP_AVRC_RN_CAP_ALLOWED_EVT = 0, /*!< all of the notification events that can possibly be supported, immutable */
|
||||
ESP_AVRC_RN_CAP_SUPPORTED_EVT = 1, /*!< notification events selectively supported according to the current configuration */
|
||||
ESP_AVRC_RN_CAP_MAX,
|
||||
} esp_avrc_rn_evt_cap_t;
|
||||
|
||||
/// AVRC target notification event capability bit mask
|
||||
typedef struct {
|
||||
uint16_t bits; /*!< bit mask representation of PASSTHROUGH commands */
|
||||
} esp_avrc_rn_evt_cap_mask_t;
|
||||
|
||||
/// AVRC notification response type
|
||||
typedef enum {
|
||||
ESP_AVRC_RN_RSP_INTERIM = 13, /*!< initial response to RegisterNotification, should be sent T_mtp(1000ms) from receiving the command */
|
||||
ESP_AVRC_RN_RSP_CHANGED = 15, /*!< final response to RegisterNotification command */
|
||||
} esp_avrc_rn_rsp_t;
|
||||
|
||||
/// AVRC player setting ids
|
||||
typedef enum {
|
||||
ESP_AVRC_PS_EQUALIZER = 0x01, /*!< equalizer, on or off */
|
||||
@ -122,6 +235,46 @@ typedef enum {
|
||||
ESP_AVRC_PS_SCAN_GROUP = 0x3 /*!< group scan */
|
||||
} esp_avrc_ps_scn_value_ids_t;
|
||||
|
||||
/// AVCTP response codes
|
||||
typedef enum {
|
||||
ESP_AVRC_RSP_NOT_IMPL = 8, /*!< not implemented */
|
||||
ESP_AVRC_RSP_ACCEPT = 9, /*!< accept */
|
||||
ESP_AVRC_RSP_REJECT = 10, /*!< reject */
|
||||
ESP_AVRC_RSP_IN_TRANS = 11, /*!< in transition */
|
||||
ESP_AVRC_RSP_IMPL_STBL = 12, /*!< implemented/stable */
|
||||
ESP_AVRC_RSP_CHANGED = 13, /*!< changed */
|
||||
ESP_AVRC_RSP_INTERIM = 15, /*!< interim */
|
||||
} esp_avrc_rsp_t;
|
||||
|
||||
/// AVRCP battery status
|
||||
typedef enum {
|
||||
ESP_AVRC_BATT_NORMAL = 0, /*!< normal state */
|
||||
ESP_AVRC_BATT_WARNING = 1, /*!< unable to operate soon */
|
||||
ESP_AVRC_BATT_CRITICAL = 2, /*!< cannot operate any more */
|
||||
ESP_AVRC_BATT_EXTERNAL = 3, /*!< plugged to external power supply */
|
||||
ESP_AVRC_BATT_FULL_CHARGE = 4, /*!< when completely charged from external power supply */
|
||||
} esp_avrc_batt_stat_t;
|
||||
|
||||
/// AVRCP current status of playback
|
||||
typedef enum {
|
||||
ESP_AVRC_PLAYBACK_STOPPED = 0, /*!< stopped */
|
||||
ESP_AVRC_PLAYBACK_PLAYING = 1, /*!< playing */
|
||||
ESP_AVRC_PLAYBACK_PAUSED = 2, /*!< paused */
|
||||
ESP_AVRC_PLAYBACK_FWD_SEEK = 3, /*!< forward seek */
|
||||
ESP_AVRC_PLAYBACK_REV_SEEK = 4, /*!< reverse seek */
|
||||
ESP_AVRC_PLAYBACK_ERROR = 0xFF, /*!< error */
|
||||
} esp_avrc_playback_stat_t;
|
||||
|
||||
/// AVRCP notification parameters
|
||||
typedef union
|
||||
{
|
||||
uint8_t volume; /*!< response data for ESP_AVRC_RN_VOLUME_CHANGE, ranges 0..127 */
|
||||
esp_avrc_playback_stat_t playback; /*!< response data for ESP_AVRC_RN_PLAY_STATUS_CHANGE */
|
||||
uint8_t elm_id[8]; /*!< response data for ESP_AVRC_RN_TRACK_CHANGE */
|
||||
uint32_t play_pos; /*!< response data for ESP_AVRC_RN_PLAY_POS_CHANGED, in millisecond */
|
||||
esp_avrc_batt_stat_t batt; /*!< response data for ESP_AVRC_RN_BATTERY_STATUS_CHANGE */
|
||||
} esp_avrc_rn_param_t;
|
||||
|
||||
/// AVRC controller callback parameters
|
||||
typedef union {
|
||||
/**
|
||||
@ -155,7 +308,7 @@ typedef union {
|
||||
*/
|
||||
struct avrc_ct_change_notify_param {
|
||||
uint8_t event_id; /*!< id of AVRC event notification */
|
||||
uint32_t event_parameter; /*!< event notification parameter */
|
||||
esp_avrc_rn_param_t event_parameter; /*!< event notification parameter */
|
||||
} change_ntf; /*!< notifications */
|
||||
|
||||
/**
|
||||
@ -163,11 +316,61 @@ typedef union {
|
||||
*/
|
||||
struct avrc_ct_rmt_feats_param {
|
||||
uint32_t feat_mask; /*!< AVRC feature mask of remote device */
|
||||
uint16_t tg_feat_flag; /*!< feature flag of remote device as TG */
|
||||
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
|
||||
} rmt_feats; /*!< AVRC features discovered from remote SDP server */
|
||||
|
||||
|
||||
/**
|
||||
* @brief ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT
|
||||
*/
|
||||
struct avrc_ct_get_rn_caps_rsp_param {
|
||||
uint8_t cap_count; /*!< number of items provided in event or company_id according to cap_id used */
|
||||
esp_avrc_rn_evt_cap_mask_t evt_set; /*!< supported event_ids represented in bit-mask */
|
||||
} get_rn_caps_rsp; /*!< get supported event capabilities response from AVRCP target */
|
||||
} esp_avrc_ct_cb_param_t;
|
||||
|
||||
/// AVRC target callback parameters
|
||||
typedef union {
|
||||
/**
|
||||
* @brief ESP_AVRC_TG_CONNECTION_STATE_EVT
|
||||
*/
|
||||
struct avrc_tg_conn_stat_param {
|
||||
bool connected; /*!< whether AVRC connection is set up */
|
||||
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
|
||||
} conn_stat; /*!< AVRC connection status */
|
||||
|
||||
/**
|
||||
* @brief ESP_AVRC_TG_REMOTE_FEATURES_EVT
|
||||
*/
|
||||
struct avrc_tg_rmt_feats_param {
|
||||
uint32_t feat_mask; /*!< AVRC feature mask of remote device */
|
||||
uint16_t ct_feat_flag; /*!< feature flag of remote device as CT */
|
||||
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
|
||||
} rmt_feats; /*!< AVRC features discovered through SDP */
|
||||
|
||||
/**
|
||||
* @brief ESP_AVRC_TG_PASSTHROUGH_CMD_EVT
|
||||
*/
|
||||
struct avrc_tg_psth_cmd_param {
|
||||
uint8_t key_code; /*!< passthrough command code */
|
||||
uint8_t key_state; /*!< 0 for PRESSED, 1 for RELEASED */
|
||||
} psth_cmd; /*!< passthrough command */
|
||||
|
||||
/**
|
||||
* @brief ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT
|
||||
*/
|
||||
struct avrc_tg_set_abs_vol_param {
|
||||
uint8_t volume; /*!< volume ranges from 0 to 127 */
|
||||
} set_abs_vol; /*!< set absolute volume command targeted on audio sink */
|
||||
|
||||
/**
|
||||
* @brief ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT
|
||||
*/
|
||||
struct avrc_tg_reg_ntf_param {
|
||||
uint8_t event_id; /*!< event id of AVRC RegisterNotification */
|
||||
uint32_t event_parameter; /*!< event notification parameter */
|
||||
} reg_ntf; /*!< register notification */
|
||||
} esp_avrc_tg_cb_param_t;
|
||||
|
||||
/**
|
||||
* @brief AVRCP controller callback function type
|
||||
@ -176,23 +379,28 @@ typedef union {
|
||||
*/
|
||||
typedef void (* esp_avrc_ct_cb_t)(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param);
|
||||
|
||||
/**
|
||||
* @brief AVRCP target callback function type
|
||||
* @param event : Event type
|
||||
* @param param : Pointer to callback parameter union
|
||||
*/
|
||||
typedef void (* esp_avrc_tg_cb_t)(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Register application callbacks to AVRCP module; for now only AVRCP Controller
|
||||
* role is supported. This function should be called after esp_bluedroid_enable()
|
||||
* completes successfully
|
||||
* @brief Register application callbacks to AVRCP module. This function should be
|
||||
* called after esp_bluedroid_enable() completes successfully
|
||||
*
|
||||
* @param[in] callback: AVRCP controller callback function
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_avrc_ct_register_callback(esp_avrc_ct_cb_t callback);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Initialize the bluetooth AVRCP controller module, This function should be called
|
||||
@ -200,13 +408,12 @@ esp_err_t esp_avrc_ct_register_callback(esp_avrc_ct_cb_t callback);
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_avrc_ct_init(void);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief De-initialize AVRCP controller module. This function should be called after
|
||||
@ -214,7 +421,7 @@ esp_err_t esp_avrc_ct_init(void);
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*/
|
||||
esp_err_t esp_avrc_ct_deinit(void);
|
||||
@ -229,11 +436,24 @@ esp_err_t esp_avrc_ct_deinit(void);
|
||||
* @param[in] value_id : attribute value defined for the specific player application setting attribute
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*/
|
||||
esp_err_t esp_avrc_ct_send_set_player_value_cmd(uint8_t tl, uint8_t attr_id, uint8_t value_id);
|
||||
|
||||
/**
|
||||
* @brief Send GetCapabilities PDU to AVRCP target to retrieve remote device's supported
|
||||
* notification event_ids. This function should be called after
|
||||
* ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established
|
||||
*
|
||||
* @param[in] tl : transaction label, 0 to 15, consecutive commands should use different values.
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*/
|
||||
esp_err_t esp_avrc_ct_send_get_rn_capabilities_cmd(uint8_t tl);
|
||||
|
||||
/**
|
||||
* @brief Send register notification command to AVRCP target, This function should be called after
|
||||
* ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established
|
||||
@ -243,7 +463,8 @@ esp_err_t esp_avrc_ct_send_set_player_value_cmd(uint8_t tl, uint8_t attr_id, uin
|
||||
* @param[in] event_parameter : special parameters, eg. playback interval for ESP_AVRC_RN_PLAY_POS_CHANGED
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_ERR_NOT_SUPPORTED: if the event_id is not supported in current implementation
|
||||
* - ESP_FAIL: others
|
||||
*/
|
||||
esp_err_t esp_avrc_ct_send_register_notification_cmd(uint8_t tl, uint8_t event_id, uint32_t event_parameter);
|
||||
@ -258,7 +479,7 @@ esp_err_t esp_avrc_ct_send_register_notification_cmd(uint8_t tl, uint8_t event_i
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*/
|
||||
esp_err_t esp_avrc_ct_send_metadata_cmd(uint8_t tl, uint8_t attr_mask);
|
||||
@ -275,12 +496,176 @@ esp_err_t esp_avrc_ct_send_metadata_cmd(uint8_t tl, uint8_t attr_mask);
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*/
|
||||
esp_err_t esp_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t key_state);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Register application callbacks to AVRCP target module; This function should be
|
||||
* called after esp_bluedroid_enable() completes successfully
|
||||
*
|
||||
* @param[in] callback: AVRCP target callback function
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_avrc_tg_register_callback(esp_avrc_tg_cb_t callback);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Initialize the bluetooth AVRCP target module, This function should be called
|
||||
* after esp_bluedroid_enable() completes successfully
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_avrc_tg_init(void);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief De-initialize AVRCP target module. This function should be called after
|
||||
* after esp_bluedroid_enable() completes successfully
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*/
|
||||
esp_err_t esp_avrc_tg_deinit(void);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Get the current filter of remote passthrough commands on AVRC target. Filter is given by
|
||||
* filter type and bit mask for the passthrough commands. This function should be called
|
||||
* after esp_avrc_tg_init().
|
||||
* For filter type ESP_AVRC_PSTH_FILTER_ALLOWED_CMD, the retrieved command set is constant and
|
||||
* it covers all of the passthrough commands that can possibly be supported.
|
||||
* For filter type ESP_AVRC_PSTH_FILTER_SUPPORT_COMMANDS, the retrieved command set covers the
|
||||
* passthrough commands selected to be supported according to current configuration. The
|
||||
* configuration can be changed using esp_avrc_tg_set_psth_cmd_filter()
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not enabled or AVRC TG is not initialized
|
||||
* - ESP_ERR_INVALID_ARG: if filter type is invalid or cmd_set is NULL
|
||||
* - ESP_FAIL: otherwise
|
||||
*/
|
||||
esp_err_t esp_avrc_tg_get_psth_cmd_filter(esp_avrc_psth_filter_t filter, esp_avrc_psth_bit_mask_t *cmd_set);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Set the filter of remote passthrough commands on AVRC target. Filter is given by
|
||||
* filter type and bit mask for the passthrough commands. This function should be called
|
||||
* after esp_avrc_tg_init().
|
||||
* If filter type is ESP_AVRC_PSTH_FILTER_SUPPORT_CMD, the passthrough commands which
|
||||
* are set "1" as given in cmd_set will generate ESP_AVRC_CT_PASSTHROUGH_RSP_EVT callback
|
||||
* event and are auto-accepted in the protocol stack, other commands are replied with response
|
||||
* type "NOT IMPLEMENTED" (8). The set of supported commands should be a subset of allowed
|
||||
* command set. The allowed command set can be retrieved using esp_avrc_tg_get_psth_cmd_filter()
|
||||
* with filter type "ESP_AVRC_PSTH_FILTER_ALLOWED_CMD".
|
||||
*
|
||||
* Filter type "ESP_AVRC_PSTH_FILTER_ALLOWED_CMD" does not apply to this function
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not enabled
|
||||
* - ESP_ERR_INVALID_ARG: if filter type is invalid or cmd_set is NULL
|
||||
* - ESP_ERR_NOT_SUPPORTED:: if filter type is ESP_AVRC_PSTH_FILTER_ALLOWED_CMD, or cmd_set
|
||||
* includes unallowed commands
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_avrc_tg_set_psth_cmd_filter(esp_avrc_psth_filter_t filter, const esp_avrc_psth_bit_mask_t *cmd_set);
|
||||
|
||||
/**
|
||||
* @brief Operate on the type esp_avrc_psth_bit_mask_t with regard to a specific PASSTHROUGH command
|
||||
* @param[in] op: operation requested on the bit mask field
|
||||
* @param[in] psth: pointer to passthrough command bit mask structure
|
||||
* @param[in] cmd: passthrough command code
|
||||
*
|
||||
* @return For operation ESP_AVRC_BIT_MASK_OP_SET or ESP_AVRC_BIT_MASK_OP_CLEAR, return
|
||||
* true for a successful operation, otherwise return false
|
||||
* For operation ESP_AVRC_BIT_MASK_OP_TEST, return true if the corresponding bit
|
||||
* is set, otherwise false
|
||||
*
|
||||
*/
|
||||
bool esp_avrc_psth_bit_mask_operation(esp_avrc_bit_mask_op_t op, esp_avrc_psth_bit_mask_t *psth,
|
||||
esp_avrc_pt_cmd_t cmd);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Get the requested event notification capabilies on local AVRC target. The capability is returned
|
||||
* in a bit mask representation in evt_set. This function should be called after
|
||||
* esp_avrc_tg_init().
|
||||
* For capability type "ESP_AVRC_RN_CAP_ALLOWED_EVT, the retrieved event set is constant and
|
||||
* it covers all of the notifcation events that can possibly be supported with current
|
||||
* implementation.
|
||||
* For capability type ESP_AVRC_RN_CAP_SUPPORTED_EVT, the event set covers the notification
|
||||
* events selected to be supported under current configuration, The configuration can be
|
||||
* changed using esp_avrc_tg_set_rn_evt_cap()
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not enabled or AVRC TG is not initialized
|
||||
* - ESP_ERR_INVALID_ARG: if cap is invalid or evt_set is NULL
|
||||
* - ESP_FAIL: otherwise
|
||||
*/
|
||||
esp_err_t esp_avrc_tg_get_rn_evt_cap(esp_avrc_rn_evt_cap_t cap, esp_avrc_rn_evt_cap_mask_t *evt_set);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Set the event notification capabilities on local AVRCP target. The capability is given in a
|
||||
* bit mask representation in evt_set and must be a subset of allowed event IDs with current
|
||||
* implementation. This function should be called after esp_avrc_tg_init().
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not enabled
|
||||
* - ESP_ERR_INVALID_ARG: if evt_set is NULL
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_avrc_tg_set_rn_evt_cap(const esp_avrc_rn_evt_cap_mask_t *evt_set);
|
||||
|
||||
/**
|
||||
* @brief Operate on the type esp_avrc_rn_evt_cap_mask_t with regard to a specific event
|
||||
* @param[in] op: operation requested on the bit mask field
|
||||
* @param[in] events: pointer to event notification capability bit mask structure
|
||||
* @param[in] event_id: notification event code
|
||||
*
|
||||
* @return For operation ESP_AVRC_BIT_MASK_OP_SET or ESP_AVRC_BIT_MASK_OP_CLEAR, return
|
||||
* true for a successful operation, otherwise return false
|
||||
* For operation ESP_AVRC_BIT_MASK_OP_TEST, return true if the corresponding bit
|
||||
* is set, otherwise false
|
||||
*
|
||||
*/
|
||||
bool esp_avrc_rn_evt_bit_mask_operation(esp_avrc_bit_mask_op_t op, esp_avrc_rn_evt_cap_mask_t *events,
|
||||
esp_avrc_rn_event_ids_t event_id);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Send RegisterNotification Response to remote AVRCP controller. Local event notification
|
||||
* capability can be set using esp_avrc_tg_set_rn_evt_cap(),
|
||||
* in a bit mask representation in evt_set. This function should be called after
|
||||
* esp_avrc_tg_init()
|
||||
* @param[in] event_id: notification event ID that remote AVRCP CT registers
|
||||
* @param[in] rsp: notification response code
|
||||
* @param[in] param: parameters included in the specific notification
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not enabled or AVRC TG is not initialized
|
||||
* - ESP_ERR_INVALID_ARG: if evt_set is NULL
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_avrc_tg_send_rn_rsp(esp_avrc_rn_event_ids_t event_id, esp_avrc_rn_rsp_t rsp,
|
||||
esp_avrc_rn_param_t *param);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -267,14 +267,25 @@ typedef enum {
|
||||
|
||||
typedef enum {
|
||||
ESP_BLE_SM_PASSKEY = 0,
|
||||
/* Authentication requirements of local device */
|
||||
ESP_BLE_SM_AUTHEN_REQ_MODE,
|
||||
/* The IO capability of local device */
|
||||
ESP_BLE_SM_IOCAP_MODE,
|
||||
/* Initiator Key Distribution/Generation */
|
||||
ESP_BLE_SM_SET_INIT_KEY,
|
||||
/* Responder Key Distribution/Generation */
|
||||
ESP_BLE_SM_SET_RSP_KEY,
|
||||
/* Maximum Encryption key size to support */
|
||||
ESP_BLE_SM_MAX_KEY_SIZE,
|
||||
/* Minimum Encryption key size requirement from Peer */
|
||||
ESP_BLE_SM_MIN_KEY_SIZE,
|
||||
/* Set static Passkey */
|
||||
ESP_BLE_SM_SET_STATIC_PASSKEY,
|
||||
/* Reset static Passkey */
|
||||
ESP_BLE_SM_CLEAR_STATIC_PASSKEY,
|
||||
/* Accept only specified SMP Authentication requirement */
|
||||
ESP_BLE_SM_ONLY_ACCEPT_SPECIFIED_SEC_AUTH,
|
||||
/* Enable/Disable OOB support */
|
||||
ESP_BLE_SM_OOB_SUPPORT,
|
||||
ESP_BLE_SM_MAX_PARAM,
|
||||
} esp_ble_sm_param_t;
|
||||
@ -558,6 +569,7 @@ typedef enum {
|
||||
ESP_GAP_SEARCH_DISC_CMPL_EVT = 4, /*!< Discovery complete. */
|
||||
ESP_GAP_SEARCH_DI_DISC_CMPL_EVT = 5, /*!< Discovery complete. */
|
||||
ESP_GAP_SEARCH_SEARCH_CANCEL_CMPL_EVT = 6, /*!< Search cancelled */
|
||||
ESP_GAP_SEARCH_INQ_DISCARD_NUM_EVT = 7, /*!< The number of pkt discarded by flow control */
|
||||
} esp_gap_search_evt_t;
|
||||
|
||||
/**
|
||||
@ -588,12 +600,18 @@ typedef enum {
|
||||
typedef enum {
|
||||
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_ADV_ADDR = 0, /*!< BLE advertising address , device info will be added into ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_ADDR_LIST */
|
||||
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_LINK_ID, /*!< BLE mesh link ID, it is for BLE mesh, device info will be added into ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_LINK_ID_LIST */
|
||||
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_BEACON_TYPE, /*!< BLE mesh beacon AD type, the format is | Len | 0x2B | Beacon Type | Beacon Data | */
|
||||
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_PROV_SRV_ADV, /*!< BLE mesh provisioning service uuid, the format is | 0x02 | 0x01 | flags | 0x03 | 0x03 | 0x1827 | .... |` */
|
||||
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_PROXY_SRV_ADV, /*!< BLE mesh adv with proxy service uuid, the format is | 0x02 | 0x01 | flags | 0x03 | 0x03 | 0x1828 | .... |` */
|
||||
} esp_ble_duplicate_exceptional_info_type_t;
|
||||
|
||||
typedef enum {
|
||||
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_ADDR_LIST = BLE_BIT(0), /*!< duplicate scan exceptional addr list */
|
||||
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_LINK_ID_LIST = BLE_BIT(1), /*!< duplicate scan exceptional mesh link ID list */
|
||||
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_ALL_LIST = (BLE_BIT(0) | BLE_BIT(1)), /*!< duplicate scan exceptional all list */
|
||||
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_ADDR_LIST = BLE_BIT(0), /*!< duplicate scan exceptional addr list */
|
||||
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_LINK_ID_LIST = BLE_BIT(1), /*!< duplicate scan exceptional mesh link ID list */
|
||||
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_BEACON_TYPE_LIST = BLE_BIT(2), /*!< duplicate scan exceptional mesh beacon type list */
|
||||
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_PROV_SRV_ADV_LIST = BLE_BIT(3), /*!< duplicate scan exceptional mesh adv with provisioning service uuid */
|
||||
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_PROXY_SRV_ADV_LIST = BLE_BIT(4), /*!< duplicate scan exceptional mesh adv with provisioning service uuid */
|
||||
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_ALL_LIST = 0xFFFF, /*!< duplicate scan exceptional all list */
|
||||
} esp_duplicate_scan_exceptional_list_type_t;
|
||||
|
||||
typedef uint8_t esp_duplicate_info_t[ESP_BD_ADDR_LEN];
|
||||
@ -635,6 +653,7 @@ typedef union {
|
||||
int num_resps; /*!< Scan result number */
|
||||
uint8_t adv_data_len; /*!< Adv data length */
|
||||
uint8_t scan_rsp_len; /*!< Scan response length */
|
||||
uint32_t num_dis; /*!< The number of discard packets */
|
||||
} scan_rst; /*!< Event parameter of ESP_GAP_BLE_SCAN_RESULT_EVT */
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT
|
||||
@ -1049,6 +1068,7 @@ esp_err_t esp_ble_gap_read_rssi(esp_bd_addr_t remote_addr);
|
||||
*
|
||||
*
|
||||
* @param[in] type: device info type, it is defined in esp_ble_duplicate_exceptional_info_type_t
|
||||
* when type is MESH_BEACON_TYPE, MESH_PROV_SRV_ADV or MESH_PROXY_SRV_ADV , device_info is invalid.
|
||||
* @param[in] device_info: the device information.
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
@ -1061,6 +1081,7 @@ esp_err_t esp_ble_gap_add_duplicate_scan_exceptional_device(esp_ble_duplicate_ex
|
||||
*
|
||||
*
|
||||
* @param[in] type: device info type, it is defined in esp_ble_duplicate_exceptional_info_type_t
|
||||
* when type is MESH_BEACON_TYPE, MESH_PROV_SRV_ADV or MESH_PROXY_SRV_ADV , device_info is invalid.
|
||||
* @param[in] device_info: the device information.
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
|
@ -41,6 +41,7 @@
|
||||
#if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
|
||||
#include "bta/bta_ar_api.h"
|
||||
#endif
|
||||
#include "bta/bta_api.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
@ -73,26 +74,6 @@ enum {
|
||||
BTA_AV_CLOSING_SST
|
||||
};
|
||||
|
||||
|
||||
/* the call out functions for audio stream */
|
||||
/* const tBTA_AV_CO_FUNCTS bta_av_a2d_cos =
|
||||
{
|
||||
bta_av_co_audio_init,
|
||||
bta_av_co_audio_disc_res,
|
||||
bta_av_co_audio_getconfig,
|
||||
bta_av_co_audio_setconfig,
|
||||
bta_av_co_audio_open,
|
||||
bta_av_co_audio_close,
|
||||
bta_av_co_audio_start,
|
||||
bta_av_co_audio_stop,
|
||||
bta_av_co_audio_src_data_path,
|
||||
bta_av_co_audio_delay
|
||||
};
|
||||
*/
|
||||
tBTA_AV_CO_FUNCTS *p_bta_av_a2d_cos = NULL;
|
||||
|
||||
|
||||
|
||||
/* ssm action functions for audio stream */
|
||||
const tBTA_AV_SACT bta_av_a2d_action[] = {
|
||||
bta_av_do_disc_a2d, /* BTA_AV_DO_DISC */
|
||||
@ -528,8 +509,21 @@ static void bta_av_proc_stream_evt(UINT8 handle, BD_ADDR bd_addr, UINT8 event, t
|
||||
/* look up application event */
|
||||
if ((p_data == NULL) || (p_data->hdr.err_code == 0)) {
|
||||
p_msg->hdr.event = bta_av_stream_evt_ok[event];
|
||||
if (p_msg->hdr.event == BTA_AV_STR_START_OK_EVT) {
|
||||
BTA_DmCoexEventTrigger(BTA_COEX_EVT_STREAMING_STARTED);
|
||||
} else if (p_msg->hdr.event == BTA_AV_STR_START_FAIL_EVT ||
|
||||
p_msg->hdr.event == BTA_AV_STR_SUSPEND_CFM_EVT ||
|
||||
p_msg->hdr.event == BTA_AV_STR_CLOSE_EVT) {
|
||||
BTA_DmCoexEventTrigger(BTA_COEX_EVT_STREAMING_STOPPED);
|
||||
}
|
||||
} else {
|
||||
p_msg->hdr.event = bta_av_stream_evt_fail[event];
|
||||
if (p_msg->hdr.event == BTA_AV_STR_START_FAIL_EVT ||
|
||||
p_msg->hdr.event == BTA_AV_STR_START_OK_EVT ||
|
||||
p_msg->hdr.event == BTA_AV_STR_SUSPEND_CFM_EVT ||
|
||||
p_msg->hdr.event == BTA_AV_STR_CLOSE_EVT) {
|
||||
BTA_DmCoexEventTrigger(BTA_COEX_EVT_STREAMING_STOPPED);
|
||||
}
|
||||
}
|
||||
|
||||
p_msg->initiator = FALSE;
|
||||
@ -1293,9 +1287,10 @@ void bta_av_setconfig_rsp (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
|
||||
/* if SBC is used by the SNK as INT, discover req is not sent in bta_av_config_ind.
|
||||
* call disc_res now */
|
||||
/* this is called in A2DP SRC path only, In case of SINK we don't need it */
|
||||
if (local_sep == AVDT_TSEP_SRC)
|
||||
if (local_sep == AVDT_TSEP_SRC) {
|
||||
p_scb->p_cos->disc_res(p_scb->hndl, num, num, 0, p_scb->peer_addr,
|
||||
UUID_SERVCLASS_AUDIO_SOURCE);
|
||||
}
|
||||
} else {
|
||||
/* we do not know the peer device and it is using non-SBC codec
|
||||
* we need to know all the SEPs on SNK */
|
||||
|
@ -335,6 +335,8 @@ UINT8 bta_av_rc_create(tBTA_AV_CB *p_cb, UINT8 role, UINT8 shdl, UINT8 lidx)
|
||||
p_rcb->shdl = shdl;
|
||||
p_rcb->lidx = lidx;
|
||||
p_rcb->peer_features = 0;
|
||||
p_rcb->peer_ct_features = 0;
|
||||
p_rcb->peer_tg_features = 0;
|
||||
if (lidx == (BTA_AV_NUM_LINKS + 1)) {
|
||||
/* this LIDX is reserved for the AVRCP ACP connection */
|
||||
p_cb->rc_acp_handle = p_rcb->handle;
|
||||
@ -397,22 +399,13 @@ static tBTA_AV_CODE bta_av_group_navi_supported(UINT8 len, UINT8 *p_data, BOOLEA
|
||||
static tBTA_AV_CODE bta_av_op_supported(tBTA_AV_RC rc_id, BOOLEAN is_inquiry)
|
||||
{
|
||||
tBTA_AV_CODE ret_code = BTA_AV_RSP_NOT_IMPL;
|
||||
BOOLEAN rc_id_allowed = FALSE;
|
||||
if (bta_av_cb.p_rc_cos && bta_av_cb.p_rc_cos->rc_cmd) {
|
||||
rc_id_allowed = bta_av_cb.p_rc_cos->rc_cmd(rc_id);
|
||||
}
|
||||
|
||||
if (p_bta_av_rc_id) {
|
||||
if (is_inquiry) {
|
||||
if (p_bta_av_rc_id[rc_id >> 4] & (1 << (rc_id & 0x0F))) {
|
||||
ret_code = BTA_AV_RSP_IMPL_STBL;
|
||||
}
|
||||
} else {
|
||||
if (p_bta_av_rc_id[rc_id >> 4] & (1 << (rc_id & 0x0F))) {
|
||||
ret_code = BTA_AV_RSP_ACCEPT;
|
||||
} else if ((p_bta_av_cfg->rc_pass_rsp == BTA_AV_RSP_INTERIM) && p_bta_av_rc_id_ac) {
|
||||
if (p_bta_av_rc_id_ac[rc_id >> 4] & (1 << (rc_id & 0x0F))) {
|
||||
ret_code = BTA_AV_RSP_INTERIM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rc_id_allowed == TRUE) {
|
||||
ret_code = is_inquiry ? BTA_AV_RSP_IMPL_STBL : BTA_AV_RSP_ACCEPT;
|
||||
}
|
||||
return ret_code;
|
||||
}
|
||||
@ -529,6 +522,8 @@ void bta_av_rc_opened(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
|
||||
|
||||
bdcpy(rc_open.peer_addr, p_data->rc_conn_chg.peer_addr);
|
||||
rc_open.peer_features = p_cb->rcb[i].peer_features;
|
||||
rc_open.peer_ct_features = p_cb->rcb[i].peer_ct_features;
|
||||
rc_open.peer_tg_features = p_cb->rcb[i].peer_tg_features;
|
||||
rc_open.sdp_disc_done = TRUE;
|
||||
rc_open.status = BTA_AV_SUCCESS;
|
||||
APPL_TRACE_DEBUG("local features:x%x peer_features:x%x", p_cb->features,
|
||||
@ -687,7 +682,6 @@ void bta_av_rc_free_msg (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
|
||||
static tAVRC_STS bta_av_chk_notif_evt_id(tAVRC_MSG_VENDOR *p_vendor)
|
||||
{
|
||||
tAVRC_STS status = BTA_AV_STS_NO_RSP;
|
||||
UINT8 xx;
|
||||
UINT16 u16;
|
||||
UINT8 *p = p_vendor->p_vendor_data + 2;
|
||||
|
||||
@ -696,15 +690,13 @@ static tAVRC_STS bta_av_chk_notif_evt_id(tAVRC_MSG_VENDOR *p_vendor)
|
||||
if ((u16 != 5) || (p_vendor->vendor_len != 9)) {
|
||||
status = AVRC_STS_INTERNAL_ERR;
|
||||
} else {
|
||||
/* make sure the player_id is valid */
|
||||
for (xx = 0; xx < p_bta_av_cfg->num_evt_ids; xx++) {
|
||||
if (*p == p_bta_av_cfg->p_meta_evt_ids[xx]) {
|
||||
break;
|
||||
/* make sure the event_id is valid */
|
||||
status = AVRC_STS_BAD_PARAM;
|
||||
if (bta_av_cb.p_rc_cos && bta_av_cb.p_rc_cos->rn_evt_supported) {
|
||||
if (bta_av_cb.p_rc_cos->rn_evt_supported(*p) == TRUE) {
|
||||
status = BTA_AV_STS_NO_RSP;
|
||||
}
|
||||
}
|
||||
if (xx == p_bta_av_cfg->num_evt_ids) {
|
||||
status = AVRC_STS_BAD_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
@ -763,9 +755,12 @@ tBTA_AV_EVT bta_av_proc_meta_cmd(tAVRC_RESPONSE *p_rc_rsp, tBTA_AV_RC_MSG *p_ms
|
||||
(p_bta_av_cfg->num_co_ids << 2));
|
||||
} else if (u8 == AVRC_CAP_EVENTS_SUPPORTED) {
|
||||
*p_ctype = AVRC_RSP_IMPL_STBL;
|
||||
p_rc_rsp->get_caps.count = p_bta_av_cfg->num_evt_ids;
|
||||
memcpy(p_rc_rsp->get_caps.param.event_id, p_bta_av_cfg->p_meta_evt_ids,
|
||||
p_bta_av_cfg->num_evt_ids);
|
||||
if (bta_av_cb.p_rc_cos && bta_av_cb.p_rc_cos->rn_evt_cap) {
|
||||
p_rc_rsp->get_caps.count = bta_av_cb.p_rc_cos->rn_evt_cap(
|
||||
p_rc_rsp->get_caps.param.event_id);
|
||||
} else {
|
||||
p_rc_rsp->get_caps.count = 0;
|
||||
}
|
||||
} else {
|
||||
APPL_TRACE_DEBUG("Invalid capability ID: 0x%x", u8);
|
||||
/* reject - unknown capability ID */
|
||||
@ -774,7 +769,6 @@ tBTA_AV_EVT bta_av_proc_meta_cmd(tAVRC_RESPONSE *p_rc_rsp, tBTA_AV_RC_MSG *p_ms
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case AVRC_PDU_REGISTER_NOTIFICATION:
|
||||
/* make sure the event_id is implemented */
|
||||
p_rc_rsp->rsp.status = bta_av_chk_notif_evt_id (p_vendor);
|
||||
@ -783,6 +777,12 @@ tBTA_AV_EVT bta_av_proc_meta_cmd(tAVRC_RESPONSE *p_rc_rsp, tBTA_AV_RC_MSG *p_ms
|
||||
}
|
||||
break;
|
||||
|
||||
case AVRC_PDU_SET_ABSOLUTE_VOLUME:
|
||||
p_rc_rsp->rsp.status = BTA_AV_STS_NO_RSP;
|
||||
break;
|
||||
default:
|
||||
APPL_TRACE_WARNING("%s unhandled RC vendor PDU: 0x%x", __FUNCTION__, pdu);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
@ -829,10 +829,11 @@ void bta_av_rc_msg(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
|
||||
if (p_data->rc_msg.msg.pass.op_id == AVRC_ID_VENDOR) {
|
||||
p_data->rc_msg.msg.hdr.ctype = BTA_AV_RSP_NOT_IMPL;
|
||||
#if (AVRC_METADATA_INCLUDED == TRUE)
|
||||
if (p_cb->features & BTA_AV_FEAT_METADATA)
|
||||
if (p_cb->features & BTA_AV_FEAT_METADATA) {
|
||||
p_data->rc_msg.msg.hdr.ctype =
|
||||
bta_av_group_navi_supported(p_data->rc_msg.msg.pass.pass_len,
|
||||
p_data->rc_msg.msg.pass.p_pass_data, is_inquiry);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
p_data->rc_msg.msg.hdr.ctype = bta_av_op_supported(p_data->rc_msg.msg.pass.op_id, is_inquiry);
|
||||
@ -856,6 +857,10 @@ void bta_av_rc_msg(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
|
||||
av.remote_cmd.label = p_data->rc_msg.label;
|
||||
}
|
||||
}
|
||||
/* else if this is a pass thru respone that TG doesn't implement thie command */
|
||||
else if (p_data->rc_msg.msg.hdr.ctype == AVRC_RSP_NOT_IMPL) {
|
||||
/* do nothing, no need to setup for callback */
|
||||
}
|
||||
/* else if this is a pass thru response */
|
||||
else if (p_data->rc_msg.msg.hdr.ctype >= AVRC_RSP_ACCEPT) {
|
||||
/* set up for callback */
|
||||
@ -890,7 +895,9 @@ void bta_av_rc_msg(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
|
||||
evt = bta_av_proc_meta_cmd (&rc_rsp, &p_data->rc_msg, &ctype);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
evt = BTA_AV_VENDOR_CMD_EVT;
|
||||
}
|
||||
}
|
||||
/* else if configured to support vendor specific and it's a response */
|
||||
else if ((p_cb->features & BTA_AV_FEAT_VENDOR) &&
|
||||
@ -902,7 +909,9 @@ void bta_av_rc_msg(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
|
||||
evt = BTA_AV_META_MSG_EVT;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
evt = BTA_AV_VENDOR_RSP_EVT;
|
||||
}
|
||||
|
||||
}
|
||||
/* else if not configured to support vendor specific and it's a command */
|
||||
@ -1479,15 +1488,15 @@ static void bta_av_acp_sig_timer_cback (TIMER_LIST_ENT *p_tle)
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_check_peer_features
|
||||
** Function bta_av_check_peer_rc_features
|
||||
**
|
||||
** Description check supported features on the peer device from the SDP record
|
||||
** and return the feature mask
|
||||
** Description check supported AVRC features on the peer device from the SDP
|
||||
** record and return the feature mask
|
||||
**
|
||||
** Returns tBTA_AV_FEAT peer device feature mask
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_AV_FEAT bta_av_check_peer_features (UINT16 service_uuid)
|
||||
tBTA_AV_FEAT bta_av_check_peer_rc_features (UINT16 service_uuid, UINT16 *rc_features)
|
||||
{
|
||||
tBTA_AV_FEAT peer_features = 0;
|
||||
tBTA_AV_CB *p_cb = &bta_av_cb;
|
||||
@ -1496,7 +1505,7 @@ tBTA_AV_FEAT bta_av_check_peer_features (UINT16 service_uuid)
|
||||
UINT16 peer_rc_version = 0;
|
||||
UINT16 categories = 0;
|
||||
|
||||
APPL_TRACE_DEBUG("bta_av_check_peer_features service_uuid:x%x", service_uuid);
|
||||
APPL_TRACE_DEBUG("bta_av_check_peer_rc features service_uuid:x%x", service_uuid);
|
||||
/* loop through all records we found */
|
||||
while (TRUE) {
|
||||
/* get next record; if none found, we're done */
|
||||
@ -1536,7 +1545,12 @@ tBTA_AV_FEAT bta_av_check_peer_features (UINT16 service_uuid)
|
||||
}
|
||||
}
|
||||
}
|
||||
APPL_TRACE_DEBUG("peer_features:x%x", peer_features);
|
||||
|
||||
if (rc_features) {
|
||||
*rc_features = categories;
|
||||
}
|
||||
|
||||
APPL_TRACE_DEBUG("peer_features:x%x, rc:x%x", peer_features, categories);
|
||||
return peer_features;
|
||||
}
|
||||
|
||||
@ -1559,6 +1573,8 @@ void bta_av_rc_disc_done(tBTA_AV_DATA *p_data)
|
||||
tBTA_AV_RC_FEAT rc_feat;
|
||||
UINT8 rc_handle;
|
||||
tBTA_AV_FEAT peer_features; /* peer features mask */
|
||||
UINT16 peer_ct_features; /* peer features mask as controller */
|
||||
UINT16 peer_tg_features; /* peer features mask as target */
|
||||
UNUSED(p_data);
|
||||
|
||||
APPL_TRACE_DEBUG("bta_av_rc_disc_done disc:x%x", p_cb->disc);
|
||||
@ -1584,17 +1600,13 @@ void bta_av_rc_disc_done(tBTA_AV_DATA *p_data)
|
||||
|
||||
APPL_TRACE_DEBUG("rc_handle %d", rc_handle);
|
||||
/* check peer version and whether support CT and TG role */
|
||||
peer_features = bta_av_check_peer_features (UUID_SERVCLASS_AV_REMOTE_CONTROL);
|
||||
if ((p_cb->features & BTA_AV_FEAT_ADV_CTRL) && ((peer_features & BTA_AV_FEAT_ADV_CTRL) == 0)) {
|
||||
/* if we support advance control and peer does not, check their support on TG role
|
||||
* some implementation uses 1.3 on CT ans 1.4 on TG */
|
||||
peer_features |= bta_av_check_peer_features (UUID_SERVCLASS_AV_REM_CTRL_TARGET);
|
||||
}
|
||||
peer_features = bta_av_check_peer_rc_features (UUID_SERVCLASS_AV_REMOTE_CONTROL, &peer_ct_features);
|
||||
peer_features |= bta_av_check_peer_rc_features (UUID_SERVCLASS_AV_REM_CTRL_TARGET, &peer_tg_features);
|
||||
|
||||
p_cb->disc = 0;
|
||||
utl_freebuf((void **) &p_cb->p_disc_db);
|
||||
|
||||
APPL_TRACE_DEBUG("peer_features 0x%x, features 0x%x", peer_features, p_cb->features);
|
||||
APPL_TRACE_DEBUG("peer_features 0x%x, local features 0x%x", peer_features, p_cb->features);
|
||||
|
||||
/* if we have no rc connection */
|
||||
if (rc_handle == BTA_AV_RC_HANDLE_NONE) {
|
||||
@ -1606,6 +1618,8 @@ void bta_av_rc_disc_done(tBTA_AV_DATA *p_data)
|
||||
if (p_lcb) {
|
||||
rc_handle = bta_av_rc_create(p_cb, AVCT_INT, (UINT8)(p_scb->hdi + 1), p_lcb->lidx);
|
||||
p_cb->rcb[rc_handle].peer_features = peer_features;
|
||||
p_cb->rcb[rc_handle].peer_ct_features = peer_ct_features;
|
||||
p_cb->rcb[rc_handle].peer_tg_features = peer_tg_features;
|
||||
}
|
||||
#if (BT_USE_TRACES == TRUE || BT_TRACE_APPL == TRUE)
|
||||
else {
|
||||
@ -1626,6 +1640,8 @@ void bta_av_rc_disc_done(tBTA_AV_DATA *p_data)
|
||||
p_cb->rcb[rc_handle].peer_features = peer_features;
|
||||
rc_feat.rc_handle = rc_handle;
|
||||
rc_feat.peer_features = peer_features;
|
||||
rc_feat.peer_ct_features = peer_ct_features;
|
||||
rc_feat.peer_tg_features = peer_tg_features;
|
||||
(*p_cb->p_cback)(BTA_AV_RC_FEAT_EVT, (tBTA_AV *) &rc_feat);
|
||||
}
|
||||
}
|
||||
@ -1660,6 +1676,8 @@ void bta_av_rc_closed(tBTA_AV_DATA *p_data)
|
||||
rc_close.rc_handle = i;
|
||||
p_rcb->status &= ~BTA_AV_RC_CONN_MASK;
|
||||
p_rcb->peer_features = 0;
|
||||
p_rcb->peer_ct_features = 0;
|
||||
p_rcb->peer_tg_features = 0;
|
||||
APPL_TRACE_DEBUG(" shdl:%d, lidx:%d", p_rcb->shdl, p_rcb->lidx);
|
||||
if (p_rcb->shdl) {
|
||||
if ((p_rcb->shdl - 1) < BTA_AV_NUM_STRS) {
|
||||
|
@ -105,7 +105,9 @@ void BTA_AvDisable(void)
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name, UINT8 app_id, tBTA_AV_DATA_CBACK *p_data_cback, tBTA_AV_CO_FUNCTS *bta_av_cos, UINT8 tsep)
|
||||
void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name, UINT8 app_id,
|
||||
tBTA_AV_DATA_CBACK *p_data_cback, tBTA_AV_CO_FUNCTS *bta_av_cos,
|
||||
tBTA_AVRC_CO_FUNCTS *bta_avrc_cos, UINT8 tsep)
|
||||
{
|
||||
tBTA_AV_API_REG *p_buf;
|
||||
|
||||
@ -122,6 +124,7 @@ void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name, UINT8 app_id,
|
||||
p_buf->app_id = app_id;
|
||||
p_buf->p_app_data_cback = p_data_cback;
|
||||
p_buf->bta_av_cos = bta_av_cos;
|
||||
p_buf->bta_avrc_cos = bta_avrc_cos;
|
||||
p_buf->tsep = tsep;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ const UINT32 bta_av_meta_caps_co_ids[] = {
|
||||
};
|
||||
|
||||
/* AVRCP cupported categories */
|
||||
#define BTA_AV_RC_SUPF_CT (AVRC_SUPF_CT_CAT2)
|
||||
#define BTA_AV_RC_SUPF_CT (AVRC_SUPF_CT_CAT1)
|
||||
|
||||
/* Added to modify
|
||||
** 1. flush timeout
|
||||
@ -62,26 +62,11 @@ const UINT16 bta_av_audio_flush_to[] = {
|
||||
/* Note: Android doesnt support AVRC_SUPF_TG_GROUP_NAVI */
|
||||
/* Note: if AVRC_SUPF_TG_GROUP_NAVI is set, bta_av_cfg.avrc_group should be TRUE */
|
||||
#if AVRC_METADATA_INCLUDED == TRUE
|
||||
#define BTA_AV_RC_SUPF_TG (AVRC_SUPF_TG_CAT1) /* TODO: | AVRC_SUPF_TG_APP_SETTINGS) */
|
||||
#define BTA_AV_RC_SUPF_TG (AVRC_SUPF_TG_CAT2) /* TODO: | AVRC_SUPF_TG_APP_SETTINGS) */
|
||||
#else
|
||||
#define BTA_AV_RC_SUPF_TG (AVRC_SUPF_TG_CAT1)
|
||||
#define BTA_AV_RC_SUPF_TG (AVRC_SUPF_TG_CAT2)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If the number of event IDs is changed in this array, BTA_AV_ NUM_RC_EVT_IDS also needs to be changed.
|
||||
*/
|
||||
const UINT8 bta_av_meta_caps_evt_ids[] = {
|
||||
AVRC_EVT_PLAY_STATUS_CHANGE,
|
||||
AVRC_EVT_TRACK_CHANGE,
|
||||
AVRC_EVT_PLAY_POS_CHANGED,
|
||||
/* TODO: Add support for these events
|
||||
AVRC_EVT_APP_SETTING_CHANGE,
|
||||
*/
|
||||
};
|
||||
#ifndef BTA_AV_NUM_RC_EVT_IDS
|
||||
#define BTA_AV_NUM_RC_EVT_IDS (sizeof(bta_av_meta_caps_evt_ids) / sizeof(bta_av_meta_caps_evt_ids[0]))
|
||||
#endif /* BTA_AV_NUM_RC_EVT_IDS */
|
||||
|
||||
/* the MTU for the AVRCP browsing channel */
|
||||
#ifndef BTA_AV_MAX_RC_BR_MTU
|
||||
#define BTA_AV_MAX_RC_BR_MTU 1008
|
||||
@ -105,10 +90,8 @@ const tBTA_AV_CFG bta_av_cfg = {
|
||||
600, /* AVDTP video transport channel flush timeout */
|
||||
FALSE, /* TRUE, to accept AVRC 1.3 group nevigation command */
|
||||
2, /* company id count in p_meta_co_ids */
|
||||
BTA_AV_NUM_RC_EVT_IDS, /* event id count in p_meta_evt_ids */
|
||||
BTA_AV_RC_PASS_RSP_CODE,/* the default response code for pass through commands */
|
||||
bta_av_meta_caps_co_ids,/* the metadata Get Capabilities response for company id */
|
||||
bta_av_meta_caps_evt_ids,/* the the metadata Get Capabilities response for event id */
|
||||
NULL, /* the action function table for VDP stream */
|
||||
NULL, /* action function to register VDP */
|
||||
{0}, /* Default AVRCP controller name */
|
||||
@ -117,91 +100,4 @@ const tBTA_AV_CFG bta_av_cfg = {
|
||||
|
||||
tBTA_AV_CFG *p_bta_av_cfg = (tBTA_AV_CFG *) &bta_av_cfg;
|
||||
|
||||
const UINT16 bta_av_rc_id[] = {
|
||||
0x0000, /* bit mask: 0=SELECT, 1=UP, 2=DOWN, 3=LEFT,
|
||||
4=RIGHT, 5=RIGHT_UP, 6=RIGHT_DOWN, 7=LEFT_UP,
|
||||
8=LEFT_DOWN, 9=ROOT_MENU, 10=SETUP_MENU, 11=CONT_MENU,
|
||||
12=FAV_MENU, 13=EXIT */
|
||||
|
||||
0, /* not used */
|
||||
|
||||
0x0000, /* bit mask: 0=0, 1=1, 2=2, 3=3,
|
||||
4=4, 5=5, 6=6, 7=7,
|
||||
8=8, 9=9, 10=DOT, 11=ENTER,
|
||||
12=CLEAR */
|
||||
|
||||
0x0000, /* bit mask: 0=CHAN_UP, 1=CHAN_DOWN, 2=PREV_CHAN, 3=SOUND_SEL,
|
||||
4=INPUT_SEL, 5=DISP_INFO, 6=HELP, 7=PAGE_UP,
|
||||
8=PAGE_DOWN */
|
||||
|
||||
#if (BTA_AV_RC_PASS_RSP_CODE == BTA_AV_RSP_INTERIM)
|
||||
/* btui_app provides an example of how to leave the decision of rejecting a command or not
|
||||
* based on which media player is currently addressed (this is only applicable for AVRCP 1.4 or later)
|
||||
* If the decision is per player for a particular rc_id, the related bit is clear (not set) */
|
||||
0x0070, /* bit mask: 0=POWER, 1=VOL_UP, 2=VOL_DOWN, 3=MUTE,
|
||||
4=PLAY, 5=STOP, 6=PAUSE, 7=RECORD,
|
||||
8=REWIND, 9=FAST_FOR, 10=EJECT, 11=FORWARD,
|
||||
12=BACKWARD */
|
||||
#else
|
||||
#if (defined BTA_AVRCP_FF_RW_SUPPORT) && (BTA_AVRCP_FF_RW_SUPPORT == TRUE)
|
||||
0x1b70, /* bit mask: 0=POWER, 1=VOL_UP, 2=VOL_DOWN, 3=MUTE,
|
||||
4=PLAY, 5=STOP, 6=PAUSE, 7=RECORD,
|
||||
8=REWIND, 9=FAST_FOR, 10=EJECT, 11=FORWARD,
|
||||
12=BACKWARD */
|
||||
#else
|
||||
0x1870, /* bit mask: 0=POWER, 1=VOL_UP, 2=VOL_DOWN, 3=MUTE,
|
||||
4=PLAY, 5=STOP, 6=PAUSE, 7=RECORD,
|
||||
8=REWIND, 9=FAST_FOR, 10=EJECT, 11=FORWARD,
|
||||
12=BACKWARD */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
0x0000, /* bit mask: 0=ANGLE, 1=SUBPICT */
|
||||
|
||||
0, /* not used */
|
||||
|
||||
0x0000 /* bit mask: 0=not used, 1=F1, 2=F2, 3=F3,
|
||||
4=F4, 5=F5 */
|
||||
};
|
||||
|
||||
#if (BTA_AV_RC_PASS_RSP_CODE == BTA_AV_RSP_INTERIM)
|
||||
const UINT16 bta_av_rc_id_ac[] = {
|
||||
0x0000, /* bit mask: 0=SELECT, 1=UP, 2=DOWN, 3=LEFT,
|
||||
4=RIGHT, 5=RIGHT_UP, 6=RIGHT_DOWN, 7=LEFT_UP,
|
||||
8=LEFT_DOWN, 9=ROOT_MENU, 10=SETUP_MENU, 11=CONT_MENU,
|
||||
12=FAV_MENU, 13=EXIT */
|
||||
|
||||
0, /* not used */
|
||||
|
||||
0x0000, /* bit mask: 0=0, 1=1, 2=2, 3=3,
|
||||
4=4, 5=5, 6=6, 7=7,
|
||||
8=8, 9=9, 10=DOT, 11=ENTER,
|
||||
12=CLEAR */
|
||||
|
||||
0x0000, /* bit mask: 0=CHAN_UP, 1=CHAN_DOWN, 2=PREV_CHAN, 3=SOUND_SEL,
|
||||
4=INPUT_SEL, 5=DISP_INFO, 6=HELP, 7=PAGE_UP,
|
||||
8=PAGE_DOWN */
|
||||
|
||||
/* btui_app provides an example of how to leave the decision of rejecting a command or not
|
||||
* based on which media player is currently addressed (this is only applicable for AVRCP 1.4 or later)
|
||||
* If the decision is per player for a particular rc_id, the related bit is set */
|
||||
0x1800, /* bit mask: 0=POWER, 1=VOL_UP, 2=VOL_DOWN, 3=MUTE,
|
||||
4=PLAY, 5=STOP, 6=PAUSE, 7=RECORD,
|
||||
8=REWIND, 9=FAST_FOR, 10=EJECT, 11=FORWARD,
|
||||
12=BACKWARD */
|
||||
|
||||
0x0000, /* bit mask: 0=ANGLE, 1=SUBPICT */
|
||||
|
||||
0, /* not used */
|
||||
|
||||
0x0000 /* bit mask: 0=not used, 1=F1, 2=F2, 3=F3,
|
||||
4=F4, 5=F5 */
|
||||
};
|
||||
UINT16 *p_bta_av_rc_id_ac = (UINT16 *) bta_av_rc_id_ac;
|
||||
#else
|
||||
UINT16 *p_bta_av_rc_id_ac = NULL;
|
||||
#endif
|
||||
|
||||
UINT16 *p_bta_av_rc_id = (UINT16 *) bta_av_rc_id;
|
||||
|
||||
#endif /* if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE) */
|
||||
|
@ -534,6 +534,11 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
|
||||
registr.app_id = p_data->api_reg.app_id;
|
||||
registr.chnl = (tBTA_AV_CHNL)p_data->hdr.layer_specific;
|
||||
registr.p_bta_av_cos = p_data->api_reg.bta_av_cos;
|
||||
registr.p_bta_avrc_cos = p_data->api_reg.bta_avrc_cos;
|
||||
|
||||
// set the avrc call-out functions
|
||||
bta_av_cb.p_rc_cos = p_data->api_reg.bta_avrc_cos;
|
||||
|
||||
do {
|
||||
p_scb = bta_av_alloc_scb(registr.chnl);
|
||||
if (p_scb == NULL) {
|
||||
@ -619,7 +624,6 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
|
||||
if (registr.chnl == BTA_AV_CHNL_AUDIO) {
|
||||
/* set up the audio stream control block */
|
||||
p_scb->p_act_tbl = (const tBTA_AV_ACT *)bta_av_a2d_action;
|
||||
// p_scb->p_cos = &bta_av_a2d_cos;
|
||||
p_scb->p_cos = registr.p_bta_av_cos;
|
||||
p_scb->media_type = AVDT_MEDIA_AUDIO;
|
||||
cs.cfg.psc_mask = AVDT_PSC_TRANS;
|
||||
@ -1247,9 +1251,11 @@ BOOLEAN bta_av_hdl_event(BT_HDR *p_msg)
|
||||
} else {
|
||||
APPL_TRACE_VERBOSE("handle=0x%x\n", p_msg->layer_specific);
|
||||
tBTA_AV_SCB *p_scb = bta_av_hndl_to_scb(p_msg->layer_specific);
|
||||
p_scb->disc_rsn = p_msg->offset;
|
||||
/* stream state machine events */
|
||||
bta_av_ssm_execute(p_scb, p_msg->event, (tBTA_AV_DATA *) p_msg);
|
||||
if (p_scb) {
|
||||
p_scb->disc_rsn = p_msg->offset;
|
||||
/* stream state machine events */
|
||||
bta_av_ssm_execute(p_scb, p_msg->event, (tBTA_AV_DATA *) p_msg);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@ -1268,7 +1274,7 @@ BOOLEAN bta_av_hdl_event(BT_HDR *p_msg)
|
||||
** Returns char *
|
||||
**
|
||||
*******************************************************************************/
|
||||
static char *bta_av_st_code(UINT8 state)
|
||||
UNUSED_ATTR static char *bta_av_st_code(UINT8 state)
|
||||
{
|
||||
switch (state) {
|
||||
case BTA_AV_INIT_ST: return "INIT";
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <string.h>
|
||||
#include "bta/bta_av_co.h"
|
||||
#include "bta_av_int.h"
|
||||
#include "osi/osi.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and types
|
||||
@ -564,7 +565,7 @@ void bta_av_set_scb_sst_incoming (tBTA_AV_SCB *p_scb)
|
||||
** Returns char *
|
||||
**
|
||||
*******************************************************************************/
|
||||
static char *bta_av_sst_code(UINT8 state)
|
||||
UNUSED_ATTR static char *bta_av_sst_code(UINT8 state)
|
||||
{
|
||||
switch (state) {
|
||||
case BTA_AV_INIT_SST: return "INIT";
|
||||
|
@ -174,6 +174,7 @@ typedef struct {
|
||||
UINT8 tsep; // local SEP type
|
||||
tBTA_AV_DATA_CBACK *p_app_data_cback;
|
||||
tBTA_AV_CO_FUNCTS *bta_av_cos;
|
||||
tBTA_AVRC_CO_FUNCTS *bta_avrc_cos;
|
||||
} tBTA_AV_API_REG;
|
||||
|
||||
|
||||
@ -473,6 +474,8 @@ typedef struct {
|
||||
UINT8 shdl; /* stream handle (hdi + 1) */
|
||||
UINT8 lidx; /* (index+1) to LCB */
|
||||
tBTA_AV_FEAT peer_features; /* peer features mask */
|
||||
UINT16 peer_ct_features;
|
||||
UINT16 peer_tg_features;
|
||||
} tBTA_AV_RCB;
|
||||
#define BTA_AV_NUM_RCB (BTA_AV_NUM_STRS + 2)
|
||||
|
||||
@ -509,6 +512,7 @@ typedef struct {
|
||||
tBTA_AV_FEAT features; /* features mask */
|
||||
tBTA_SEC sec_mask; /* security mask */
|
||||
tBTA_AV_HNDL handle; /* the handle for SDP activity */
|
||||
tBTA_AVRC_CO_FUNCTS *p_rc_cos; /* AVRCP call-out functions */
|
||||
BOOLEAN disabling; /* TRUE if api disabled called */
|
||||
UINT8 disc; /* (hdi+1) or (rc_handle|BTA_AV_CHNL_MSK) if p_disc_db is in use */
|
||||
UINT8 state; /* state machine state */
|
||||
@ -544,12 +548,7 @@ extern tBTA_AV_CB *bta_av_cb_ptr;
|
||||
/* config struct */
|
||||
extern tBTA_AV_CFG *p_bta_av_cfg;
|
||||
|
||||
/* rc id config struct */
|
||||
extern UINT16 *p_bta_av_rc_id;
|
||||
extern UINT16 *p_bta_av_rc_id_ac;
|
||||
|
||||
extern const tBTA_AV_SACT bta_av_a2d_action[];
|
||||
// extern const tBTA_AV_CO_FUNCTS bta_av_a2d_cos;
|
||||
extern const tBTA_AV_SACT bta_av_vdp_action[];
|
||||
extern tAVDT_CTRL_CBACK *const bta_av_dt_cback[];
|
||||
extern void bta_av_stream_data_cback(UINT8 handle, BT_HDR *p_pkt, UINT32 time_stamp, UINT8 m_pt);
|
||||
|
@ -127,6 +127,7 @@ static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr);
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
static void bta_dm_observe_results_cb(tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir);
|
||||
static void bta_dm_observe_cmpl_cb(void *p_result);
|
||||
static void bta_dm_observe_discard_cb (uint32_t num_dis);
|
||||
static void bta_dm_delay_role_switch_cback(TIMER_LIST_ENT *p_tle);
|
||||
extern void sdpu_uuid16_to_uuid128(UINT16 uuid16, UINT8 *p_uuid128);
|
||||
static void bta_dm_disable_timer_cback(TIMER_LIST_ENT *p_tle);
|
||||
@ -635,31 +636,39 @@ void bta_dm_set_visibility(tBTA_DM_MSG *p_data)
|
||||
|
||||
/* set modes for Discoverability and connectability if not ignore */
|
||||
if (p_data->set_visibility.disc_mode != (BTA_DM_IGNORE | BTA_DM_LE_IGNORE)) {
|
||||
if ((p_data->set_visibility.disc_mode & BTA_DM_LE_IGNORE) == BTA_DM_LE_IGNORE)
|
||||
if ((p_data->set_visibility.disc_mode & BTA_DM_LE_IGNORE) == BTA_DM_LE_IGNORE) {
|
||||
p_data->set_visibility.disc_mode =
|
||||
((p_data->set_visibility.disc_mode & ~BTA_DM_LE_IGNORE) | le_disc_mode);
|
||||
}
|
||||
|
||||
if ((p_data->set_visibility.disc_mode & BTA_DM_IGNORE) == BTA_DM_IGNORE)
|
||||
if ((p_data->set_visibility.disc_mode & BTA_DM_IGNORE) == BTA_DM_IGNORE) {
|
||||
p_data->set_visibility.disc_mode =
|
||||
((p_data->set_visibility.disc_mode & ~BTA_DM_IGNORE) | disc_mode);
|
||||
}
|
||||
|
||||
BTM_SetDiscoverability(p_data->set_visibility.disc_mode,
|
||||
if (p_data->set_visibility.disc_mode != (le_disc_mode | disc_mode)) {
|
||||
BTM_SetDiscoverability(p_data->set_visibility.disc_mode,
|
||||
bta_dm_cb.inquiry_scan_window,
|
||||
bta_dm_cb.inquiry_scan_interval);
|
||||
}
|
||||
}
|
||||
|
||||
if (p_data->set_visibility.conn_mode != (BTA_DM_IGNORE | BTA_DM_LE_IGNORE)) {
|
||||
if ((p_data->set_visibility.conn_mode & BTA_DM_LE_IGNORE) == BTA_DM_LE_IGNORE)
|
||||
if ((p_data->set_visibility.conn_mode & BTA_DM_LE_IGNORE) == BTA_DM_LE_IGNORE) {
|
||||
p_data->set_visibility.conn_mode =
|
||||
((p_data->set_visibility.conn_mode & ~BTA_DM_LE_IGNORE) | le_conn_mode);
|
||||
}
|
||||
|
||||
if ((p_data->set_visibility.conn_mode & BTA_DM_IGNORE) == BTA_DM_IGNORE)
|
||||
if ((p_data->set_visibility.conn_mode & BTA_DM_IGNORE) == BTA_DM_IGNORE) {
|
||||
p_data->set_visibility.conn_mode =
|
||||
((p_data->set_visibility.conn_mode & ~BTA_DM_IGNORE) | conn_mode);
|
||||
}
|
||||
|
||||
BTM_SetConnectability(p_data->set_visibility.conn_mode,
|
||||
if (p_data->set_visibility.conn_mode != (le_conn_mode | conn_mode)) {
|
||||
BTM_SetConnectability(p_data->set_visibility.conn_mode,
|
||||
bta_dm_cb.page_scan_window,
|
||||
bta_dm_cb.page_scan_interval);
|
||||
}
|
||||
}
|
||||
|
||||
/* Send False or True if not ignore */
|
||||
@ -688,7 +697,6 @@ void bta_dm_set_visibility(tBTA_DM_MSG *p_data)
|
||||
if (p_data->set_visibility.pair_mode != BTA_DM_IGNORE || p_data->set_visibility.conn_paired_only != BTA_DM_IGNORE) {
|
||||
BTM_SetPairableMode((BOOLEAN)(!(bta_dm_cb.disable_pair_mode)), bta_dm_cb.conn_paired_only);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -1900,10 +1908,12 @@ void bta_dm_disc_result (tBTA_DM_MSG *p_data)
|
||||
|
||||
#if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
|
||||
/* if any BR/EDR service discovery has been done, report the event */
|
||||
if ((bta_dm_search_cb.services & ((BTA_ALL_SERVICE_MASK | BTA_USER_SERVICE_MASK ) & ~BTA_BLE_SERVICE_MASK)))
|
||||
#endif
|
||||
if ((bta_dm_search_cb.services & ((BTA_ALL_SERVICE_MASK | BTA_USER_SERVICE_MASK ) & ~BTA_BLE_SERVICE_MASK))) {
|
||||
bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT, &p_data->disc_result.result);
|
||||
|
||||
}
|
||||
#else
|
||||
bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT, &p_data->disc_result.result);
|
||||
#endif
|
||||
tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG));
|
||||
|
||||
/* send a message to change state */
|
||||
@ -2169,9 +2179,10 @@ static void bta_dm_find_services ( BD_ADDR bd_addr)
|
||||
}
|
||||
|
||||
/* last one? clear the BLE service bit if all discovery has been done */
|
||||
if (bta_dm_search_cb.uuid_to_search == 0)
|
||||
if (bta_dm_search_cb.uuid_to_search == 0) {
|
||||
bta_dm_search_cb.services_to_search &=
|
||||
(tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index)));
|
||||
}
|
||||
|
||||
} else
|
||||
#endif
|
||||
@ -3654,11 +3665,11 @@ static char *bta_dm_get_remname(void)
|
||||
char *p_temp;
|
||||
|
||||
/* If the name isn't already stored, try retrieving from BTM */
|
||||
if (*p_name == '\0')
|
||||
if (*p_name == '\0') {
|
||||
if ((p_temp = BTM_SecReadDevName(bta_dm_search_cb.peer_bdaddr)) != NULL) {
|
||||
p_name = p_temp;
|
||||
}
|
||||
|
||||
}
|
||||
return p_name;
|
||||
}
|
||||
#endif ///SDP_INCLUDED == TRUE || SMP_INCLUDED == TRUE
|
||||
@ -4273,6 +4284,28 @@ static void bta_dm_observe_cmpl_cb (void *p_result)
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_observe_discard_cb
|
||||
**
|
||||
** Description Callback for BLE Observe lost
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_dm_observe_discard_cb (uint32_t num_dis)
|
||||
{
|
||||
tBTA_DM_SEARCH data;
|
||||
|
||||
APPL_TRACE_DEBUG("bta_dm_observe_discard_cb");
|
||||
|
||||
data.inq_dis.num_dis = num_dis;
|
||||
if (bta_dm_search_cb.p_scan_cback) {
|
||||
bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_DISCARD_NUM_EVT, &data);
|
||||
}
|
||||
}
|
||||
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
/*******************************************************************************
|
||||
**
|
||||
@ -4815,7 +4848,7 @@ void bta_dm_ble_scan (tBTA_DM_MSG *p_data)
|
||||
bta_dm_search_cb.p_scan_cback = p_data->ble_scan.p_cback;
|
||||
|
||||
if ((status = BTM_BleScan(TRUE, p_data->ble_scan.duration,
|
||||
bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb)) != BTM_CMD_STARTED) {
|
||||
bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb, bta_dm_observe_discard_cb)) != BTM_CMD_STARTED) {
|
||||
APPL_TRACE_WARNING(" %s start scan failed. status=0x%x\n", __FUNCTION__, status);
|
||||
}
|
||||
|
||||
@ -4825,7 +4858,7 @@ void bta_dm_ble_scan (tBTA_DM_MSG *p_data)
|
||||
}
|
||||
} else {
|
||||
bta_dm_search_cb.p_scan_cback = NULL;
|
||||
status = BTM_BleScan(FALSE, 0, NULL, NULL);
|
||||
status = BTM_BleScan(FALSE, 0, NULL, NULL, NULL);
|
||||
|
||||
if (status != BTM_CMD_STARTED){
|
||||
APPL_TRACE_WARNING(" %s stop scan failed, status=0x%x\n", __FUNCTION__, status);
|
||||
@ -5219,9 +5252,10 @@ void bta_dm_ble_setup_storage (tBTA_DM_MSG *p_data)
|
||||
p_data->ble_set_storage.ref_value);
|
||||
}
|
||||
|
||||
if (BTM_CMD_STARTED != btm_status)
|
||||
if (BTM_CMD_STARTED != btm_status) {
|
||||
bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_CFG_STRG_EVT, p_data->ble_set_storage.ref_value,
|
||||
btm_status);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -5249,9 +5283,10 @@ void bta_dm_ble_enable_batch_scan (tBTA_DM_MSG *p_data)
|
||||
p_data->ble_enable_scan.ref_value);
|
||||
}
|
||||
|
||||
if (BTM_CMD_STARTED != btm_status)
|
||||
if (BTM_CMD_STARTED != btm_status) {
|
||||
bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_ENABLE_EVT, p_data->ble_enable_scan.ref_value,
|
||||
btm_status);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -5275,9 +5310,10 @@ void bta_dm_ble_disable_batch_scan (tBTA_DM_MSG *p_data)
|
||||
btm_status = BTM_BleDisableBatchScan(p_data->ble_disable_scan.ref_value);
|
||||
}
|
||||
|
||||
if (BTM_CMD_STARTED != btm_status)
|
||||
if (BTM_CMD_STARTED != btm_status) {
|
||||
bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_DISABLE_EVT, p_data->ble_enable_scan.ref_value,
|
||||
btm_status);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -5301,9 +5337,10 @@ void bta_dm_ble_read_scan_reports(tBTA_DM_MSG *p_data)
|
||||
p_data->ble_read_reports.ref_value);
|
||||
}
|
||||
|
||||
if (BTM_CMD_STARTED != btm_status)
|
||||
if (BTM_CMD_STARTED != btm_status) {
|
||||
bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_READ_REPTS_EVT, p_data->ble_enable_scan.ref_value,
|
||||
btm_status);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -5433,10 +5470,11 @@ void bta_dm_cfg_filter_cond (tBTA_DM_MSG *p_data)
|
||||
}
|
||||
}
|
||||
|
||||
if (p_data->ble_cfg_filter_cond.p_filt_cfg_cback)
|
||||
if (p_data->ble_cfg_filter_cond.p_filt_cfg_cback) {
|
||||
p_data->ble_cfg_filter_cond.p_filt_cfg_cback(BTA_DM_BLE_PF_CONFIG_EVT,
|
||||
p_data->ble_cfg_filter_cond.cond_type, 0, status,
|
||||
p_data->ble_cfg_filter_cond.ref_value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -5467,9 +5505,10 @@ void bta_dm_enable_scan_filter(tBTA_DM_MSG *p_data)
|
||||
return;
|
||||
}
|
||||
|
||||
if (p_data->ble_enable_scan_filt.p_filt_status_cback)
|
||||
if (p_data->ble_enable_scan_filt.p_filt_status_cback) {
|
||||
p_data->ble_enable_scan_filt.p_filt_status_cback (BTA_DM_BLE_PF_ENABLE_EVT,
|
||||
p_data->ble_enable_scan_filt.ref_value, status);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -5503,9 +5542,10 @@ void bta_dm_scan_filter_param_setup (tBTA_DM_MSG *p_data)
|
||||
}
|
||||
}
|
||||
|
||||
if (p_data->ble_scan_filt_param_setup.p_filt_param_cback)
|
||||
if (p_data->ble_scan_filt_param_setup.p_filt_param_cback) {
|
||||
p_data->ble_scan_filt_param_setup.p_filt_param_cback (BTA_DM_BLE_PF_ENABLE_EVT, 0,
|
||||
p_data->ble_scan_filt_param_setup.ref_value, status);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -5815,6 +5855,8 @@ void bta_dm_proc_open_evt(tBTA_GATTC_OPEN *p_data)
|
||||
((p2[0]) << 24) + ((p2[1]) << 16) + ((p2[2]) << 8) + (p2[3]),
|
||||
((p2[4]) << 8) + p2[5]);
|
||||
|
||||
UNUSED(p1);
|
||||
UNUSED(p2);
|
||||
APPL_TRACE_DEBUG("BTA_GATTC_OPEN_EVT conn_id = %d client_if=%d status = %d" ,
|
||||
p_data->conn_id,
|
||||
p_data->client_if,
|
||||
|
@ -243,7 +243,7 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF, 3000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open active */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
|
@ -48,6 +48,7 @@ tBTE_APPL_CFG bte_appl_cfg = {
|
||||
BTM_BLE_INITIATOR_KEY_SIZE,
|
||||
BTM_BLE_RESPONDER_KEY_SIZE,
|
||||
BTM_BLE_MAX_KEY_SIZE,
|
||||
BTM_BLE_MIN_KEY_SIZE,
|
||||
BTM_BLE_ONLY_ACCEPT_SPECIFIED_SEC_AUTH_DISABLE,
|
||||
BTM_BLE_OOB_DISABLE,
|
||||
};
|
||||
@ -407,7 +408,7 @@ void bta_dm_co_ble_set_rsp_key_req(UINT8 rsp_key)
|
||||
void bta_dm_co_ble_set_max_key_size(UINT8 ble_key_size)
|
||||
{
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
if(ble_key_size >= BTM_BLE_MIN_KEY_SIZE && ble_key_size <= BTM_BLE_MAX_KEY_SIZE) {
|
||||
if(ble_key_size >= bte_appl_cfg.ble_min_key_size && ble_key_size <= BTM_BLE_MAX_KEY_SIZE) {
|
||||
bte_appl_cfg.ble_max_key_size = ble_key_size;
|
||||
} else {
|
||||
APPL_TRACE_ERROR("%s error:Invalid key size value, key_size =%d",__func__, ble_key_size);
|
||||
@ -415,6 +416,17 @@ void bta_dm_co_ble_set_max_key_size(UINT8 ble_key_size)
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
}
|
||||
|
||||
void bta_dm_co_ble_set_min_key_size(UINT8 ble_key_size)
|
||||
{
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
if(ble_key_size >= BTM_BLE_MIN_KEY_SIZE && ble_key_size <= bte_appl_cfg.ble_max_key_size) {
|
||||
bte_appl_cfg.ble_min_key_size = ble_key_size;
|
||||
} else {
|
||||
APPL_TRACE_ERROR("%s error:Invalid key size value, key_size =%d",__func__, ble_key_size);
|
||||
}
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
}
|
||||
|
||||
void bta_dm_co_ble_set_accept_auth_enable(UINT8 enable)
|
||||
{
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "osi/allocator.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_coexist.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and types
|
||||
@ -452,3 +453,27 @@ BOOLEAN bta_dm_search_sm_execute(BT_HDR *p_msg)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void BTA_DmCoexEventTrigger(uint32_t event)
|
||||
{
|
||||
switch(event) {
|
||||
case BTA_COEX_EVT_SCAN_STARTED:
|
||||
case BTA_COEX_EVT_SCAN_STOPPED:
|
||||
case BTA_COEX_EVT_SNIFF_ENTER:
|
||||
case BTA_COEX_EVT_SNIFF_EXIT:
|
||||
case BTA_COEX_EVT_A2DP_PAUSED_ENTER:
|
||||
case BTA_COEX_EVT_A2DP_PAUSED_EXIT:
|
||||
case BTA_COEX_EVT_ACL_CONNECTED:
|
||||
case BTA_COEX_EVT_ACL_DISCONNECTED:
|
||||
break;
|
||||
case BTA_COEX_EVT_STREAMING_STARTED:
|
||||
esp_coex_status_bit_set(ESP_COEX_ST_TYPE_BT, ESP_COEX_BT_ST_A2DP_STREAMING);
|
||||
esp_coex_status_bit_clear(ESP_COEX_ST_TYPE_BT, ESP_COEX_BT_ST_A2DP_PAUSED);
|
||||
break;
|
||||
case BTA_COEX_EVT_STREAMING_STOPPED:
|
||||
esp_coex_status_bit_clear(ESP_COEX_ST_TYPE_BT, ESP_COEX_BT_ST_A2DP_STREAMING);
|
||||
esp_coex_status_bit_clear(ESP_COEX_ST_TYPE_BT, ESP_COEX_BT_ST_A2DP_PAUSED);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
@ -1038,9 +1038,10 @@ static void bta_dm_pm_hid_check(BOOLEAN bScoActive)
|
||||
bta_dm_pm_set_sniff_policy( bta_dm_find_peer_device(bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr), bScoActive);
|
||||
|
||||
/* if we had disabled link policy, seems like the hid device stop retrying SNIFF after a few tries. force sniff if needed */
|
||||
if (!bScoActive)
|
||||
if (!bScoActive) {
|
||||
bta_dm_pm_set_mode(bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr, BTA_DM_PM_NO_ACTION,
|
||||
BTA_DM_PM_RESTART);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -531,7 +531,9 @@ void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg
|
||||
if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, TRUE, FALSE)) {
|
||||
/* always call open to hold a connection */
|
||||
if (!GATT_Connect(p_data->client_if, p_data->remote_bda, p_data->remote_addr_type, FALSE, p_data->transport)) {
|
||||
#if (!CONFIG_BT_STACK_NO_LOG)
|
||||
uint8_t *bda = (uint8_t *)p_data->remote_bda;
|
||||
#endif
|
||||
status = BTA_GATT_ERROR;
|
||||
APPL_TRACE_ERROR("%s unable to connect to remote bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
__func__, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
|
||||
@ -674,7 +676,7 @@ void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
|
||||
bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK);
|
||||
//register service change
|
||||
bta_gattc_register_service_change_notify(p_clcb->bta_conn_id, p_clcb->bda);
|
||||
} else
|
||||
} else
|
||||
#endif
|
||||
{ /* cache is building */
|
||||
p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC;
|
||||
@ -1071,8 +1073,9 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
|
||||
*******************************************************************************/
|
||||
void bta_gattc_read(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
|
||||
{
|
||||
if (!bta_gattc_enqueue(p_clcb, p_data))
|
||||
if (!bta_gattc_enqueue(p_clcb, p_data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
tGATT_READ_PARAM read_param;
|
||||
memset (&read_param, 0 ,sizeof(tGATT_READ_PARAM));
|
||||
@ -1140,8 +1143,9 @@ void bta_gattc_read_multi(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
|
||||
*******************************************************************************/
|
||||
void bta_gattc_write(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
|
||||
{
|
||||
if (!bta_gattc_enqueue(p_clcb, p_data))
|
||||
if (!bta_gattc_enqueue(p_clcb, p_data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
tBTA_GATT_STATUS status = BTA_GATT_OK;
|
||||
tGATT_VALUE attr;
|
||||
@ -1742,7 +1746,7 @@ void bta_gattc_process_api_cache_assoc(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_m
|
||||
tBTA_GATTC gattc_cb = {0};
|
||||
gattc_cb.set_assoc.client_if = p_msg->api_assoc.client_if;
|
||||
BOOLEAN state = FALSE;
|
||||
tBTA_GATTC_CLCB *p_assoc_clcb = bta_gattc_find_clcb_by_cif(p_msg->api_assoc.client_if,
|
||||
tBTA_GATTC_CLCB *p_assoc_clcb = bta_gattc_find_clcb_by_cif(p_msg->api_assoc.client_if,
|
||||
p_msg->api_assoc.assoc_addr, BTA_TRANSPORT_LE);
|
||||
tBTA_GATTC_RCB *p_clrcb = bta_gattc_cl_get_regcb(p_msg->api_assoc.client_if);
|
||||
if (p_assoc_clcb != NULL) {
|
||||
@ -1783,7 +1787,7 @@ void bta_gattc_process_api_cache_assoc(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_m
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
|
||||
}
|
||||
void bta_gattc_process_api_cache_get_addr_list(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
|
||||
{
|
||||
|
@ -93,7 +93,7 @@ static char *bta_gattc_attr_type[] = {
|
||||
};
|
||||
/* utility functions */
|
||||
|
||||
bool display_cache_attribute(void *data, void *context)
|
||||
bool display_cache_attribute(void *data, void *context)
|
||||
{
|
||||
//tBTA_GATTC_CACHE_ATTR *p_attr = data;
|
||||
//APPL_TRACE_ERROR("\t Attr handle[%d] uuid[0x%04x] type[%s] prop[0x%1x]",
|
||||
@ -102,7 +102,7 @@ bool display_cache_attribute(void *data, void *context)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool display_cache_service(void *data, void *context)
|
||||
bool display_cache_service(void *data, void *context)
|
||||
{
|
||||
tBTA_GATTC_SERVICE *p_cur_srvc = data;
|
||||
APPL_TRACE_API("Service: handle[%d ~ %d] %s[0x%04x] inst[%d]",
|
||||
@ -213,9 +213,9 @@ static void bta_gattc_free(void *ptr)
|
||||
osi_free(ptr);
|
||||
}
|
||||
|
||||
void bta_gattc_insert_sec_service_to_cache(list_t *services, tBTA_GATTC_SERVICE *p_new_srvc)
|
||||
void bta_gattc_insert_sec_service_to_cache(list_t *services, tBTA_GATTC_SERVICE *p_new_srvc)
|
||||
{
|
||||
// services/p_new_srvc is NULL
|
||||
// services/p_new_srvc is NULL
|
||||
if (!services || !p_new_srvc) {
|
||||
APPL_TRACE_ERROR("%s services/p_new_srvc is NULL", __func__);
|
||||
return;
|
||||
@ -243,7 +243,7 @@ void bta_gattc_insert_sec_service_to_cache(list_t *services, tBTA_GATTC_SERVICE
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -314,8 +314,9 @@ static tBTA_GATT_STATUS bta_gattc_add_char_to_cache(tBTA_GATTC_SERV *p_srvc_cb,
|
||||
/* TODO(jpawlowski): We should use attribute handle, not value handle to refer to characteristic.
|
||||
This is just a temporary workaround.
|
||||
*/
|
||||
if (service->e_handle < value_handle)
|
||||
if (service->e_handle < value_handle) {
|
||||
service->e_handle = value_handle;
|
||||
}
|
||||
|
||||
tBTA_GATTC_CHARACTERISTIC *characteristic = osi_malloc(sizeof(tBTA_GATTC_CHARACTERISTIC));
|
||||
if (!characteristic) {
|
||||
@ -554,10 +555,10 @@ void bta_gattc_update_include_service(const list_t *services) {
|
||||
if(include_service && !include_service->included_service) {
|
||||
//update
|
||||
include_service->included_service = bta_gattc_find_matching_service(services, include_service->incl_srvc_s_handle);
|
||||
if(!include_service->included_service) {
|
||||
if(!include_service->included_service) {
|
||||
//not match, free it
|
||||
list_remove(service->included_svc, include_service);
|
||||
osi_free(include_service);
|
||||
osi_free(include_service);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -980,12 +981,13 @@ void bta_gattc_disc_res_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_
|
||||
p_data->value.incl_service.e_handle,
|
||||
p_data->value.incl_service.service_type);
|
||||
|
||||
if (!pri_srvc)
|
||||
if (!pri_srvc) {
|
||||
bta_gattc_add_srvc_to_list(p_srvc_cb,
|
||||
p_data->value.incl_service.s_handle,
|
||||
p_data->value.incl_service.e_handle,
|
||||
p_data->value.incl_service.service_type,
|
||||
FALSE);
|
||||
}
|
||||
/* add into database */
|
||||
bta_gattc_add_attr_to_cache(p_srvc_cb,
|
||||
p_data->handle,
|
||||
@ -1007,8 +1009,8 @@ void bta_gattc_disc_res_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_
|
||||
|
||||
case GATT_DISC_CHAR_DSCPT:
|
||||
bta_gattc_add_attr_to_cache(p_srvc_cb,
|
||||
p_data->handle,
|
||||
&p_data->type,
|
||||
p_data->handle,
|
||||
&p_data->type,
|
||||
0,
|
||||
0 /* incl_srvc_s_handle */,
|
||||
0 /* incl_srvc_e_handle */,
|
||||
@ -1023,8 +1025,9 @@ void bta_gattc_disc_cmpl_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT
|
||||
tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
|
||||
|
||||
if ( p_clcb && (status != GATT_SUCCESS || p_clcb->status != GATT_SUCCESS) ) {
|
||||
if (status == GATT_SUCCESS)
|
||||
if (status == GATT_SUCCESS) {
|
||||
p_clcb->status = status;
|
||||
}
|
||||
bta_gattc_sm_execute(p_clcb, BTA_GATTC_DISCOVER_CMPL_EVT, NULL);
|
||||
return;
|
||||
}
|
||||
@ -1071,15 +1074,17 @@ void bta_gattc_search_service(tBTA_GATTC_CLCB *p_clcb, tBT_UUID *p_uuid)
|
||||
{
|
||||
tBTA_GATTC cb_data;
|
||||
|
||||
if (!p_clcb->p_srcb->p_srvc_cache || list_is_empty(p_clcb->p_srcb->p_srvc_cache))
|
||||
if (!p_clcb->p_srcb->p_srvc_cache || list_is_empty(p_clcb->p_srcb->p_srvc_cache)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (list_node_t *sn = list_begin(p_clcb->p_srcb->p_srvc_cache);
|
||||
sn != list_end(p_clcb->p_srcb->p_srvc_cache); sn = list_next(sn)) {
|
||||
tBTA_GATTC_SERVICE *p_cache = list_node(sn);
|
||||
|
||||
if (!bta_gattc_uuid_compare(p_uuid, &p_cache->uuid, FALSE))
|
||||
if (!bta_gattc_uuid_compare(p_uuid, &p_cache->uuid, FALSE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
#if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
|
||||
APPL_TRACE_DEBUG("found service [0x%04x], inst[%d] handle [%d]",
|
||||
@ -1087,8 +1092,9 @@ void bta_gattc_search_service(tBTA_GATTC_CLCB *p_clcb, tBT_UUID *p_uuid)
|
||||
p_cache->handle,
|
||||
p_cache->s_handle);
|
||||
#endif
|
||||
if (!p_clcb->p_rcb->p_cback)
|
||||
if (!p_clcb->p_rcb->p_cback) {
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(&cb_data, 0, sizeof(tBTA_GATTC));
|
||||
|
||||
@ -1103,8 +1109,9 @@ void bta_gattc_search_service(tBTA_GATTC_CLCB *p_clcb, tBT_UUID *p_uuid)
|
||||
}
|
||||
|
||||
list_t* bta_gattc_get_services_srcb(tBTA_GATTC_SERV *p_srcb) {
|
||||
if (!p_srcb || !p_srcb->p_srvc_cache || list_is_empty(p_srcb->p_srvc_cache))
|
||||
if (!p_srcb || !p_srcb->p_srvc_cache || list_is_empty(p_srcb->p_srvc_cache)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return p_srcb->p_srvc_cache;
|
||||
}
|
||||
@ -1112,8 +1119,9 @@ list_t* bta_gattc_get_services_srcb(tBTA_GATTC_SERV *p_srcb) {
|
||||
const list_t* bta_gattc_get_services(UINT16 conn_id) {
|
||||
tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
|
||||
|
||||
if (p_clcb == NULL )
|
||||
if (p_clcb == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tBTA_GATTC_SERV *p_srcb = p_clcb->p_srcb;
|
||||
|
||||
@ -1121,63 +1129,68 @@ const list_t* bta_gattc_get_services(UINT16 conn_id) {
|
||||
}
|
||||
|
||||
tBTA_GATTC_SERVICE* bta_gattc_find_matching_service(const list_t *services, UINT16 handle) {
|
||||
if (!services || list_is_empty(services))
|
||||
if (!services || list_is_empty(services)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (list_node_t *sn = list_begin(services);
|
||||
sn != list_end(services); sn = list_next(sn)) {
|
||||
tBTA_GATTC_SERVICE *service = list_node(sn);
|
||||
|
||||
if (handle >= service->s_handle && handle <= service->e_handle)
|
||||
if (handle >= service->s_handle && handle <= service->e_handle) {
|
||||
return service;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const tBTA_GATTC_SERVICE* bta_gattc_get_service_for_handle_srcb(tBTA_GATTC_SERV *p_srcb, UINT16 handle)
|
||||
const tBTA_GATTC_SERVICE* bta_gattc_get_service_for_handle_srcb(tBTA_GATTC_SERV *p_srcb, UINT16 handle)
|
||||
{
|
||||
const list_t *services = bta_gattc_get_services_srcb(p_srcb);
|
||||
|
||||
return bta_gattc_find_matching_service(services, handle);
|
||||
}
|
||||
|
||||
const tBTA_GATTC_SERVICE* bta_gattc_get_service_for_handle(UINT16 conn_id, UINT16 handle)
|
||||
const tBTA_GATTC_SERVICE* bta_gattc_get_service_for_handle(UINT16 conn_id, UINT16 handle)
|
||||
{
|
||||
const list_t *services = bta_gattc_get_services(conn_id);
|
||||
|
||||
return bta_gattc_find_matching_service(services, handle);
|
||||
}
|
||||
|
||||
tBTA_GATTC_CHARACTERISTIC* bta_gattc_get_characteristic_srcb(tBTA_GATTC_SERV *p_srcb, UINT16 handle)
|
||||
tBTA_GATTC_CHARACTERISTIC* bta_gattc_get_characteristic_srcb(tBTA_GATTC_SERV *p_srcb, UINT16 handle)
|
||||
{
|
||||
const tBTA_GATTC_SERVICE* service = bta_gattc_get_service_for_handle_srcb(p_srcb, handle);
|
||||
|
||||
if (!service)
|
||||
if (!service) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (list_node_t *cn = list_begin(service->characteristics);
|
||||
cn != list_end(service->characteristics); cn = list_next(cn)) {
|
||||
tBTA_GATTC_CHARACTERISTIC *p_char = list_node(cn);
|
||||
if (handle == p_char->handle)
|
||||
if (handle == p_char->handle) {
|
||||
return p_char;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tBTA_GATTC_CHARACTERISTIC* bta_gattc_get_characteristic(UINT16 conn_id, UINT16 handle)
|
||||
tBTA_GATTC_CHARACTERISTIC* bta_gattc_get_characteristic(UINT16 conn_id, UINT16 handle)
|
||||
{
|
||||
tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
|
||||
|
||||
if (p_clcb == NULL )
|
||||
if (p_clcb == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tBTA_GATTC_SERV *p_srcb = p_clcb->p_srcb;
|
||||
return bta_gattc_get_characteristic_srcb(p_srcb, handle);
|
||||
}
|
||||
|
||||
tBTA_GATTC_DESCRIPTOR* bta_gattc_get_descriptor_srcb(tBTA_GATTC_SERV *p_srcb, UINT16 handle)
|
||||
tBTA_GATTC_DESCRIPTOR* bta_gattc_get_descriptor_srcb(tBTA_GATTC_SERV *p_srcb, UINT16 handle)
|
||||
{
|
||||
const tBTA_GATTC_SERVICE* service = bta_gattc_get_service_for_handle_srcb(p_srcb, handle);
|
||||
|
||||
@ -1191,20 +1204,22 @@ tBTA_GATTC_DESCRIPTOR* bta_gattc_get_descriptor_srcb(tBTA_GATTC_SERV *p_srcb, U
|
||||
for (list_node_t *dn = list_begin(p_char->descriptors);
|
||||
dn != list_end(p_char->descriptors); dn = list_next(dn)) {
|
||||
tBTA_GATTC_DESCRIPTOR *p_desc = list_node(dn);
|
||||
if (handle == p_desc->handle)
|
||||
if (handle == p_desc->handle) {
|
||||
return p_desc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tBTA_GATTC_DESCRIPTOR* bta_gattc_get_descriptor(UINT16 conn_id, UINT16 handle)
|
||||
tBTA_GATTC_DESCRIPTOR* bta_gattc_get_descriptor(UINT16 conn_id, UINT16 handle)
|
||||
{
|
||||
tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
|
||||
|
||||
if (p_clcb == NULL )
|
||||
if (p_clcb == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tBTA_GATTC_SERV *p_srcb = p_clcb->p_srcb;
|
||||
return bta_gattc_get_descriptor_srcb(p_srcb, handle);
|
||||
@ -1443,7 +1458,7 @@ void bta_gattc_get_db_with_opration(UINT16 conn_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1476,7 +1491,7 @@ static size_t bta_gattc_get_db_size_with_type(list_t *services,
|
||||
}
|
||||
|
||||
if (type == BTGATT_DB_PRIMARY_SERVICE || type == BTGATT_DB_SECONDARY_SERVICE) {
|
||||
if ((type == BTGATT_DB_PRIMARY_SERVICE && p_cur_srvc->is_primary) ||
|
||||
if ((type == BTGATT_DB_PRIMARY_SERVICE && p_cur_srvc->is_primary) ||
|
||||
(type == BTGATT_DB_SECONDARY_SERVICE && !p_cur_srvc->is_primary)) {
|
||||
// if the current service is the last service in the db, need to ensure the current service start handle is not less than the start_handle.
|
||||
if (!svc_length) {
|
||||
@ -1572,10 +1587,11 @@ static size_t bta_gattc_get_db_size_with_type(list_t *services,
|
||||
** Returns number of elements inside db from start_handle to end_handle
|
||||
*******************************************************************************/
|
||||
static size_t bta_gattc_get_db_size(list_t *services,
|
||||
UINT16 start_handle, UINT16 end_handle)
|
||||
UINT16 start_handle, UINT16 end_handle)
|
||||
{
|
||||
if (!services || list_is_empty(services))
|
||||
if (!services || list_is_empty(services)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t db_size = 0;
|
||||
UINT16 svc_length = list_length(services) - 1;
|
||||
@ -1598,9 +1614,10 @@ static size_t bta_gattc_get_db_size(list_t *services,
|
||||
} else {
|
||||
db_size++;
|
||||
}
|
||||
|
||||
if (!p_cur_srvc->characteristics || list_is_empty(p_cur_srvc->characteristics))
|
||||
|
||||
if (!p_cur_srvc->characteristics || list_is_empty(p_cur_srvc->characteristics)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (list_node_t *cn = list_begin(p_cur_srvc->characteristics);
|
||||
cn != list_end(p_cur_srvc->characteristics); cn = list_next(cn)) {
|
||||
@ -1657,7 +1674,7 @@ void bta_gattc_get_db_size_handle(UINT16 conn_id, UINT16 start_handle, UINT16 en
|
||||
*count = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
tBTA_GATTC_SERV *p_srcb = p_clcb->p_srcb;
|
||||
if (!p_srcb->p_srvc_cache || list_is_empty(p_srcb->p_srvc_cache)) {
|
||||
*count = 0;
|
||||
@ -1676,7 +1693,7 @@ void bta_gattc_get_db_size_with_type_handle(UINT16 conn_id, bt_gatt_db_attribute
|
||||
*count = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
tBTA_GATTC_SERV *p_srcb = p_clcb->p_srcb;
|
||||
if (!p_srcb->p_srvc_cache || list_is_empty(p_srcb->p_srvc_cache)) {
|
||||
*count = 0;
|
||||
@ -1694,7 +1711,7 @@ void bta_gattc_get_db_size_with_type_handle(UINT16 conn_id, bt_gatt_db_attribute
|
||||
}
|
||||
}
|
||||
*count = bta_gattc_get_db_size_with_type(p_srcb->p_srvc_cache, type, NULL, start_handle, end_handle);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -1786,8 +1803,9 @@ static void bta_gattc_get_gatt_db_impl(tBTA_GATTC_SERV *p_srvc_cb,
|
||||
p_char->properties);
|
||||
curr_db_attr++;
|
||||
|
||||
if (!p_char->descriptors || list_is_empty(p_char->descriptors))
|
||||
if (!p_char->descriptors || list_is_empty(p_char->descriptors)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (list_node_t *dn = list_begin(p_char->descriptors);
|
||||
dn != list_end(p_char->descriptors); dn = list_next(dn)) {
|
||||
@ -1815,8 +1833,9 @@ static void bta_gattc_get_gatt_db_impl(tBTA_GATTC_SERV *p_srvc_cb,
|
||||
}
|
||||
}
|
||||
|
||||
if (!p_cur_srvc->included_svc || list_is_empty(p_cur_srvc->included_svc))
|
||||
if (!p_cur_srvc->included_svc || list_is_empty(p_cur_srvc->included_svc)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (list_node_t *isn = list_begin(p_cur_srvc->included_svc);
|
||||
isn != list_end(p_cur_srvc->included_svc); isn = list_next(isn)) {
|
||||
@ -1983,8 +2002,9 @@ void bta_gattc_fill_nv_attr(tBTA_GATTC_NV_ATTR *p_attr, UINT8 type, UINT16 s_han
|
||||
*******************************************************************************/
|
||||
void bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id)
|
||||
{
|
||||
if (!p_srvc_cb->p_srvc_cache || list_is_empty(p_srvc_cb->p_srvc_cache))
|
||||
if (!p_srvc_cb->p_srvc_cache || list_is_empty(p_srvc_cb->p_srvc_cache)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
size_t db_size = bta_gattc_get_db_size(p_srvc_cb->p_srvc_cache, 0x0000, 0xFFFF);
|
||||
@ -2017,8 +2037,9 @@ void bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id)
|
||||
sn != list_end(p_srvc_cb->p_srvc_cache); sn = list_next(sn)) {
|
||||
tBTA_GATTC_SERVICE *p_cur_srvc = list_node(sn);
|
||||
|
||||
if (!p_cur_srvc->characteristics || list_is_empty(p_cur_srvc->characteristics))
|
||||
if (!p_cur_srvc->characteristics || list_is_empty(p_cur_srvc->characteristics)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (list_node_t *cn = list_begin(p_cur_srvc->characteristics);
|
||||
cn != list_end(p_cur_srvc->characteristics); cn = list_next(cn)) {
|
||||
@ -2034,8 +2055,9 @@ void bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id)
|
||||
0 /* incl_srvc_e_handle */,
|
||||
FALSE);
|
||||
|
||||
if (!p_char->descriptors || list_is_empty(p_char->descriptors))
|
||||
if (!p_char->descriptors || list_is_empty(p_char->descriptors)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (list_node_t *dn = list_begin(p_char->descriptors);
|
||||
dn != list_end(p_char->descriptors); dn = list_next(dn)) {
|
||||
@ -2053,8 +2075,9 @@ void bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id)
|
||||
}
|
||||
}
|
||||
|
||||
if (!p_cur_srvc->included_svc || list_is_empty(p_cur_srvc->included_svc))
|
||||
if (!p_cur_srvc->included_svc || list_is_empty(p_cur_srvc->included_svc)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (list_node_t *an = list_begin(p_cur_srvc->included_svc);
|
||||
an != list_end(p_cur_srvc->included_svc); an = list_next(an)) {
|
||||
|
@ -261,14 +261,18 @@ tBTA_GATT_STATUS bta_gattc_co_cache_open(BD_ADDR server_bda, BOOLEAN to_save, UI
|
||||
*******************************************************************************/
|
||||
tBTA_GATT_STATUS bta_gattc_co_cache_load(tBTA_GATTC_NV_ATTR *attr, UINT8 index)
|
||||
{
|
||||
#if (!CONFIG_BT_STACK_NO_LOG)
|
||||
UINT16 num_attr = 0;
|
||||
#endif
|
||||
tBTA_GATT_STATUS status = BTA_GATT_ERROR;
|
||||
size_t length = 0;
|
||||
// Read the size of memory space required for blob
|
||||
nvs_get_blob(cache_env.cache_addr[index].cache_fp, cache_key, NULL, &length);
|
||||
// Read previously saved blob if available
|
||||
esp_err_t err_code = nvs_get_blob(cache_env.cache_addr[index].cache_fp, cache_key, attr, &length);
|
||||
#if (!CONFIG_BT_STACK_NO_LOG)
|
||||
num_attr = length / sizeof(tBTA_GATTC_NV_ATTR);
|
||||
#endif
|
||||
status = (err_code == ESP_OK && length != 0) ? BTA_GATT_OK : BTA_GATT_ERROR;
|
||||
APPL_TRACE_DEBUG("%s() - read=%d, status=%d, err_code = %d",
|
||||
__func__, num_attr, status, err_code);
|
||||
@ -323,6 +327,9 @@ void bta_gattc_co_cache_save (BD_ADDR server_bda, UINT16 num_attr,
|
||||
status = BTA_GATT_ERROR;
|
||||
}
|
||||
|
||||
#if CONFIG_BT_STACK_NO_LOG
|
||||
(void) status;
|
||||
#endif
|
||||
APPL_TRACE_DEBUG("%s() wrote hash_key = %x%x%x%x, num_attr = %d, status = %d.", __func__, hash_key[0], hash_key[1], hash_key[2], hash_key[3], num_attr, status);
|
||||
}
|
||||
|
||||
|
@ -416,8 +416,9 @@ tBTA_GATTC_SERV *bta_gattc_srcb_alloc(BD_ADDR bda)
|
||||
|
||||
if (p_tcb != NULL)
|
||||
{
|
||||
if (p_tcb->p_srvc_cache != NULL)
|
||||
if (p_tcb->p_srvc_cache != NULL) {
|
||||
list_free(p_tcb->p_srvc_cache);
|
||||
}
|
||||
osi_free(p_tcb->p_srvc_list);
|
||||
p_tcb->p_srvc_list = NULL;
|
||||
//osi_free_and_reset((void **)&p_tcb->p_srvc_list);
|
||||
@ -583,8 +584,9 @@ void bta_gattc_clear_notif_registration(tBTA_GATTC_SERV *p_srcb, UINT16 conn_id,
|
||||
* clear boundaries are always around service.
|
||||
*/
|
||||
handle = p_clrcb->notif_reg[i].handle;
|
||||
if (handle >= start_handle && handle <= end_handle)
|
||||
if (handle >= start_handle && handle <= end_handle) {
|
||||
memset(&p_clrcb->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -637,8 +639,9 @@ BOOLEAN bta_gattc_mark_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR_PTR remote_bda
|
||||
}
|
||||
if (!add) {
|
||||
if (remote_bda_ptr) {
|
||||
// bdstr_t bdstr = {0};
|
||||
#if (!CONFIG_BT_STACK_NO_LOG)
|
||||
char bdstr[18] = {0};
|
||||
#endif
|
||||
APPL_TRACE_ERROR("%s unable to find the bg connection mask for: %s", __func__,
|
||||
bdaddr_to_string((bt_bdaddr_t *)remote_bda_ptr, bdstr, sizeof(bdstr)));
|
||||
}
|
||||
@ -936,8 +939,9 @@ void bta_to_btif_uuid(bt_uuid_t *p_dest, tBT_UUID *p_src)
|
||||
|
||||
if (p_src->len == LEN_UUID_16 || p_src->len == LEN_UUID_32)
|
||||
{
|
||||
for(i=0; i != 16; ++i)
|
||||
for(i=0; i != 16; ++i) {
|
||||
p_dest->uu[i] = base_uuid[i];
|
||||
}
|
||||
}
|
||||
|
||||
switch (p_src->len)
|
||||
|
@ -403,7 +403,7 @@ void bta_gatts_add_char(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg)
|
||||
UINT16 attr_id = 0;
|
||||
tBTA_GATTS cb_data;
|
||||
|
||||
tGATT_ATTR_VAL *p_attr_val = NULL;
|
||||
tGATT_ATTR_VAL *p_attr_val = NULL;
|
||||
tGATTS_ATTR_CONTROL *p_control = NULL;
|
||||
|
||||
if(p_msg->api_add_char.attr_val.attr_max_len != 0){
|
||||
@ -665,17 +665,18 @@ void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
&gatt_if, remote_bda, &transport)) {
|
||||
p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
|
||||
|
||||
if (p_msg->api_indicate.need_confirm)
|
||||
if (p_msg->api_indicate.need_confirm) {
|
||||
|
||||
status = GATTS_HandleValueIndication (p_msg->api_indicate.hdr.layer_specific,
|
||||
p_msg->api_indicate.attr_id,
|
||||
p_msg->api_indicate.len,
|
||||
p_msg->api_indicate.value);
|
||||
else
|
||||
} else {
|
||||
status = GATTS_HandleValueNotification (p_msg->api_indicate.hdr.layer_specific,
|
||||
p_msg->api_indicate.attr_id,
|
||||
p_msg->api_indicate.len,
|
||||
p_msg->api_indicate.value);
|
||||
}
|
||||
|
||||
/* if over BR_EDR, inform PM for mode change */
|
||||
if (transport == BTA_TRANSPORT_BR_EDR) {
|
||||
@ -858,13 +859,13 @@ void bta_gatts_send_service_change_indication (tBTA_GATTS_DATA *p_msg)
|
||||
memcpy(bd_addr, p_msg->api_send_service_change.remote_bda, BD_ADDR_LEN);
|
||||
status = GATT_SendServiceChangeIndication(bd_addr);
|
||||
} else {
|
||||
status = GATT_SendServiceChangeIndication(NULL);
|
||||
status = GATT_SendServiceChangeIndication(NULL);
|
||||
}
|
||||
if (p_rcb && p_rcb->p_cback) {
|
||||
service_change.status = status;
|
||||
service_change.server_if = p_msg->api_send_service_change.server_if;
|
||||
(*p_rcb->p_cback)(BTA_GATTS_SEND_SERVICE_CHANGE_EVT, (tBTA_GATTS *)&service_change);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -940,7 +941,7 @@ static void bta_gatts_send_request_cback (UINT16 conn_id,
|
||||
cb_data.req_data.p_data = (tBTA_GATTS_REQ_DATA *)p_data;
|
||||
|
||||
if(req_type == BTA_GATTS_CONF_EVT) {
|
||||
cb_data.req_data.handle = p_data->handle;
|
||||
cb_data.req_data.handle = p_data->handle;
|
||||
}
|
||||
(*p_rcb->p_cback)(req_type, &cb_data);
|
||||
} else {
|
||||
|
@ -1159,6 +1159,7 @@ static char *bta_hf_client_skip_unknown(char *buffer)
|
||||
buffer = tmp + 2;
|
||||
|
||||
APPL_TRACE_DEBUG("%s %.*s", __FUNCTION__, buffer - start - 2, start);
|
||||
UNUSED(start);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
@ -232,6 +232,8 @@ const tBTA_HF_CLIENT_ST_TBL bta_hf_client_st_tbl[] = {
|
||||
bta_hf_client_st_closing
|
||||
};
|
||||
|
||||
const char *bta_hf_client_version = "1.6";
|
||||
|
||||
/* HF Client control block */
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
tBTA_HF_CLIENT_CB bta_hf_client_cb;
|
||||
@ -385,15 +387,11 @@ static void bta_hf_client_api_enable(tBTA_HF_CLIENT_DATA *p_data)
|
||||
bta_hf_client_cb.p_cback = p_data->api_enable.p_cback;
|
||||
|
||||
/* check if mSBC support enabled */
|
||||
#if 0 // todo
|
||||
char value[PROPERTY_VALUE_MAX];
|
||||
property_get("ro.bluetooth.hfp.ver", value, "0");
|
||||
if (strcmp(value, "1.6") == 0) {
|
||||
if (strcmp(bta_hf_client_version, "1.6") == 0) {
|
||||
bta_hf_client_cb.msbc_enabled = TRUE;
|
||||
} else{
|
||||
bta_hf_client_cb.msbc_enabled = FALSE;
|
||||
}
|
||||
#else
|
||||
bta_hf_client_cb.msbc_enabled = FALSE;
|
||||
#endif
|
||||
|
||||
bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
|
||||
|
||||
|
@ -308,6 +308,7 @@ static void bta_hf_client_sco_disc_cback(UINT16 sco_idx)
|
||||
#if (BTM_SCO_HCI_INCLUDED == TRUE )
|
||||
tBTM_STATUS status = BTM_ConfigScoPath(BTM_SCO_ROUTE_PCM, NULL, NULL, TRUE);
|
||||
APPL_TRACE_DEBUG("%s close config status = %d", __FUNCTION__, status);
|
||||
UNUSED(status);
|
||||
/* SCO clean up here */
|
||||
bta_hf_client_sco_co_close();
|
||||
#endif
|
||||
@ -427,21 +428,21 @@ static void bta_hf_client_sco_event(UINT8 event)
|
||||
|
||||
#if (BTM_SCO_HCI_INCLUDED == TRUE )
|
||||
if (event == BTA_HF_CLIENT_SCO_CI_DATA_E) {
|
||||
uint16_t pkt_offset = 1 + HCI_SCO_PREAMBLE_SIZE;
|
||||
uint16_t len_to_send = 0;
|
||||
UINT16 pkt_offset = 1 + HCI_SCO_PREAMBLE_SIZE;
|
||||
UINT16 len_to_send = 0;
|
||||
while (true)
|
||||
{
|
||||
p_buf = osi_malloc(sizeof(BT_HDR) + pkt_offset + BTM_SCO_DATA_SIZE_MAX);
|
||||
p_buf = osi_calloc(sizeof(BT_HDR) + pkt_offset + BTM_SCO_DATA_SIZE_MAX);
|
||||
if (!p_buf) {
|
||||
APPL_TRACE_WARNING("%s, no mem", __FUNCTION__);
|
||||
break;
|
||||
}
|
||||
|
||||
p_buf->offset = pkt_offset;
|
||||
p_buf->len = BTM_SCO_DATA_SIZE_MAX;
|
||||
len_to_send = bta_hf_client_sco_co_out_data(p_buf->data + pkt_offset, BTM_SCO_DATA_SIZE_MAX);
|
||||
if (len_to_send == BTM_SCO_DATA_SIZE_MAX) {
|
||||
len_to_send = bta_hf_client_sco_co_out_data(p_scb->sco_idx, p_buf->data + pkt_offset, BTM_SCO_DATA_SIZE_MAX);
|
||||
if (len_to_send == BTM_SCO_DATA_SIZE_MAX || len_to_send == BTM_ESCO_DATA_SIZE_MAX) {
|
||||
// expect to get the exact size of data from upper layer
|
||||
p_buf->len = len_to_send;
|
||||
if (bta_hf_client_cb.scb.sco_state == BTA_HF_CLIENT_SCO_OPEN_ST) {
|
||||
tBTM_STATUS write_stat = BTM_WriteScoData(p_scb->sco_idx, p_buf);
|
||||
if (write_stat != BTM_SUCCESS) {
|
||||
|
@ -101,8 +101,10 @@ void bta_hh_api_enable(tBTA_HH_DATA *p_data)
|
||||
bta_hh_le_enable();
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/* signal BTA call back event */
|
||||
(* bta_hh_cb.p_cback)(BTA_HH_ENABLE_EVT, (tBTA_HH *)&status);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
@ -901,7 +903,9 @@ void bta_hh_get_dscp_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
bta_hh_le_get_dscp_act(p_cb);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
(*bta_hh_cb.p_cback)(BTA_HH_GET_DSCP_EVT, (tBTA_HH *)&p_cb->dscp_info);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -934,11 +938,10 @@ void bta_hh_maint_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
dev_info.status = BTA_HH_OK;
|
||||
} else
|
||||
#endif
|
||||
|
||||
{
|
||||
if (HID_HostAddDev(p_dev_info->bda, p_dev_info->attr_mask, &dev_handle)\
|
||||
== HID_SUCCESS) {
|
||||
dev_info.handle = dev_handle;
|
||||
dev_info.status = BTA_HH_OK;
|
||||
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
/* update DI information */
|
||||
@ -966,6 +969,7 @@ void bta_hh_maint_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
|
||||
/* update cb_index[] map */
|
||||
bta_hh_cb.cb_index[dev_handle] = p_cb->index;
|
||||
}
|
||||
}
|
||||
} else { /* device already been added */
|
||||
dev_info.handle = p_cb->hid_handle;
|
||||
dev_info.status = BTA_HH_OK;
|
||||
|
@ -2183,9 +2183,10 @@ void bta_hh_le_write_char_descr_cmpl(tBTA_HH_DEV_CB *p_dev_cb, tBTA_HH_DATA *p_b
|
||||
case GATT_UUID_HID_BT_KB_INPUT:
|
||||
case GATT_UUID_HID_BT_MOUSE_INPUT:
|
||||
case GATT_UUID_HID_REPORT:
|
||||
if (p_data->status == BTA_GATT_OK)
|
||||
if (p_data->status == BTA_GATT_OK) {
|
||||
p_dev_cb->hid_srvc[hid_inst_id].report[p_dev_cb->clt_cfg_idx].client_cfg_value =
|
||||
BTA_GATT_CLT_CONFIG_NOTIFICATION;
|
||||
}
|
||||
p_dev_cb->clt_cfg_idx ++;
|
||||
bta_hh_le_write_rpt_clt_cfg(p_dev_cb, hid_inst_id);
|
||||
|
||||
|
@ -75,11 +75,12 @@ UINT8 bta_hh_find_cb(BD_ADDR bda)
|
||||
return xx;
|
||||
}
|
||||
#if BTA_HH_DEBUG
|
||||
else
|
||||
else {
|
||||
APPL_TRACE_DEBUG("in_use ? [%d] kdev[%d].hid_handle = %d state = [%d]",
|
||||
bta_hh_cb.kdev[xx].in_use, xx,
|
||||
bta_hh_cb.kdev[xx].hid_handle,
|
||||
bta_hh_cb.kdev[xx].state);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -123,7 +124,9 @@ void bta_hh_clean_up_kdev(tBTA_HH_DEV_CB *p_cb)
|
||||
bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = BTA_HH_IDX_INVALID;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
bta_hh_cb.cb_index[p_cb->hid_handle] = BTA_HH_IDX_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
/* reset device control block */
|
||||
@ -486,11 +489,12 @@ UINT8 bta_hh_dev_handle_to_cb_idx(UINT8 dev_handle)
|
||||
#endif
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/* regular HID device checking */
|
||||
if (dev_handle < BTA_HH_MAX_KNOWN ) {
|
||||
index = bta_hh_cb.cb_index[dev_handle];
|
||||
}
|
||||
|
||||
}
|
||||
return index;
|
||||
|
||||
}
|
||||
|
@ -1024,6 +1024,7 @@ typedef struct {
|
||||
#define BTA_DM_DISC_CMPL_EVT 4 /* Discovery complete. */
|
||||
#define BTA_DM_DI_DISC_CMPL_EVT 5 /* Discovery complete. */
|
||||
#define BTA_DM_SEARCH_CANCEL_CMPL_EVT 6 /* Search cancelled */
|
||||
#define BTA_DM_INQ_DISCARD_NUM_EVT 7 /* The number of inquiry discarded packets */
|
||||
|
||||
typedef UINT8 tBTA_DM_SEARCH_EVT;
|
||||
|
||||
@ -1055,6 +1056,11 @@ typedef struct {
|
||||
UINT8 num_resps; /* Number of inquiry responses. */
|
||||
} tBTA_DM_INQ_CMPL;
|
||||
|
||||
/* Structure associated with BTA_DM_INQ_DISCARD_NUM_EVT */
|
||||
typedef struct {
|
||||
UINT32 num_dis; /* The number of inquiry discarded packets. */
|
||||
} tBTA_DM_INQ_DISCARD;
|
||||
|
||||
/* Structure associated with BTA_DM_DI_DISC_CMPL_EVT */
|
||||
typedef struct {
|
||||
BD_ADDR bd_addr; /* BD address peer device. */
|
||||
@ -1092,6 +1098,7 @@ typedef union {
|
||||
tBTA_DM_DISC_RES disc_res; /* Discovery result for a peer device. */
|
||||
tBTA_DM_DISC_BLE_RES disc_ble_res; /* Discovery result for GATT based service */
|
||||
tBTA_DM_DI_DISC_CMPL di_disc; /* DI discovery result for a peer device */
|
||||
tBTA_DM_INQ_DISCARD inq_dis; /* the discarded packets information of inquiry */
|
||||
} tBTA_DM_SEARCH;
|
||||
|
||||
/* Structure of search callback event and structures */
|
||||
@ -1368,6 +1375,7 @@ typedef UINT8 tBTA_DM_LINK_TYPE;
|
||||
#define ALLOW_ALL_FILTER 0x00
|
||||
#define LOWEST_RSSI_VALUE 129
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** External Function Declarations
|
||||
*****************************************************************************/
|
||||
@ -2594,6 +2602,21 @@ extern void BTA_VendorInit (void);
|
||||
*******************************************************************************/
|
||||
extern void BTA_VendorCleanup (void);
|
||||
|
||||
enum {
|
||||
BTA_COEX_EVT_SCAN_STARTED = 1,
|
||||
BTA_COEX_EVT_SCAN_STOPPED,
|
||||
BTA_COEX_EVT_ACL_CONNECTED,
|
||||
BTA_COEX_EVT_ACL_DISCONNECTED,
|
||||
BTA_COEX_EVT_STREAMING_STARTED,
|
||||
BTA_COEX_EVT_STREAMING_STOPPED,
|
||||
BTA_COEX_EVT_SNIFF_ENTER,
|
||||
BTA_COEX_EVT_SNIFF_EXIT,
|
||||
BTA_COEX_EVT_A2DP_PAUSED_ENTER,
|
||||
BTA_COEX_EVT_A2DP_PAUSED_EXIT,
|
||||
};
|
||||
|
||||
extern void BTA_DmCoexEventTrigger(uint32_t event);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -102,8 +102,8 @@ typedef UINT8 tBTA_AV_HNDL;
|
||||
#endif
|
||||
|
||||
#ifndef BTA_AV_MAX_A2DP_MTU
|
||||
/*#define BTA_AV_MAX_A2DP_MTU 668 //224 (DM5) * 3 - 4(L2CAP header) */
|
||||
#define BTA_AV_MAX_A2DP_MTU 1008
|
||||
#define BTA_AV_MAX_A2DP_MTU 668 //224 (DM5) * 3 - 4(L2CAP header) // changt to this for mi6
|
||||
// #define BTA_AV_MAX_A2DP_MTU 1008
|
||||
#endif
|
||||
|
||||
#ifndef BTA_AV_MAX_VDP_MTU
|
||||
@ -279,20 +279,35 @@ typedef void *(*tBTA_AV_CO_DATAPATH) (tBTA_AV_CODEC codec_type,
|
||||
UINT32 *p_len, UINT32 *p_timestamp);
|
||||
typedef void (*tBTA_AV_CO_DELAY) (tBTA_AV_HNDL hndl, UINT16 delay);
|
||||
|
||||
/// AVRCP call-out function
|
||||
// check whether PASSTHROUGH command is supported
|
||||
typedef BOOLEAN (*tBTA_AVRC_CO_CMD_ALLOWED) (tBTA_AV_RC rc_id);
|
||||
// get the event notification capabilities
|
||||
typedef UINT8 (*tBTA_AVRC_CO_RN_EVT_CAP) (UINT8 *event_ids);
|
||||
// check whether the event_id is supported
|
||||
typedef BOOLEAN (*tBTA_AVRC_CO_RN_EVT_SUPPORTED) (UINT8 event_id);
|
||||
|
||||
/* the call-out functions for one stream */
|
||||
typedef struct {
|
||||
tBTA_AV_CO_INIT init;
|
||||
tBTA_AV_CO_DISC_RES disc_res;
|
||||
tBTA_AV_CO_GETCFG getcfg;
|
||||
tBTA_AV_CO_SETCFG setcfg;
|
||||
tBTA_AV_CO_OPEN open;
|
||||
tBTA_AV_CO_CLOSE close;
|
||||
tBTA_AV_CO_START start;
|
||||
tBTA_AV_CO_STOP stop;
|
||||
tBTA_AV_CO_DATAPATH data;
|
||||
tBTA_AV_CO_DELAY delay;
|
||||
tBTA_AV_CO_INIT init;
|
||||
tBTA_AV_CO_DISC_RES disc_res;
|
||||
tBTA_AV_CO_GETCFG getcfg;
|
||||
tBTA_AV_CO_SETCFG setcfg;
|
||||
tBTA_AV_CO_OPEN open;
|
||||
tBTA_AV_CO_CLOSE close;
|
||||
tBTA_AV_CO_START start;
|
||||
tBTA_AV_CO_STOP stop;
|
||||
tBTA_AV_CO_DATAPATH data;
|
||||
tBTA_AV_CO_DELAY delay;
|
||||
} tBTA_AV_CO_FUNCTS;
|
||||
|
||||
/* the call-out functions for AVRCP */
|
||||
typedef struct {
|
||||
tBTA_AVRC_CO_CMD_ALLOWED rc_cmd;
|
||||
tBTA_AVRC_CO_RN_EVT_CAP rn_evt_cap;
|
||||
tBTA_AVRC_CO_RN_EVT_SUPPORTED rn_evt_supported;
|
||||
} tBTA_AVRC_CO_FUNCTS;
|
||||
|
||||
typedef UINT8 tBTA_AV_EVT;
|
||||
|
||||
/* Event associated with BTA_AV_ENABLE_EVT */
|
||||
@ -307,6 +322,7 @@ typedef struct {
|
||||
UINT8 app_id; /* ID associated with call to BTA_AvRegister() */
|
||||
tBTA_AV_STATUS status;
|
||||
tBTA_AV_CO_FUNCTS *p_bta_av_cos;
|
||||
tBTA_AVRC_CO_FUNCTS *p_bta_avrc_cos;
|
||||
} tBTA_AV_REGISTER;
|
||||
|
||||
/* data associated with BTA_AV_OPEN_EVT */
|
||||
@ -377,6 +393,8 @@ typedef struct {
|
||||
UINT8 rc_handle;
|
||||
BOOLEAN sdp_disc_done;
|
||||
tBTA_AV_FEAT peer_features;
|
||||
UINT16 peer_ct_features;
|
||||
UINT16 peer_tg_features;
|
||||
BD_ADDR peer_addr;
|
||||
tBTA_AV_STATUS status;
|
||||
} tBTA_AV_RC_OPEN;
|
||||
@ -391,6 +409,8 @@ typedef struct {
|
||||
typedef struct {
|
||||
UINT8 rc_handle;
|
||||
tBTA_AV_FEAT peer_features;
|
||||
UINT16 peer_ct_features;
|
||||
UINT16 peer_tg_features;
|
||||
} tBTA_AV_RC_FEAT;
|
||||
|
||||
/* data associated with BTA_AV_REMOTE_CMD_EVT */
|
||||
@ -519,10 +539,8 @@ typedef struct {
|
||||
UINT16 video_flush_to; /* AVDTP video transport channel flush timeout */
|
||||
BOOLEAN avrc_group; /* TRUE, to accept AVRC 1.3 group nevigation command */
|
||||
UINT8 num_co_ids; /* company id count in p_meta_co_ids */
|
||||
UINT8 num_evt_ids; /* event id count in p_meta_evt_ids */
|
||||
tBTA_AV_CODE rc_pass_rsp; /* the default response code for pass through commands */
|
||||
const UINT32 *p_meta_co_ids;/* the metadata Get Capabilities response for company id */
|
||||
const UINT8 *p_meta_evt_ids;/* the the metadata Get Capabilities response for event id */
|
||||
const tBTA_AV_ACT *p_act_tbl;/* the action function table for VDP stream */
|
||||
tBTA_AV_REG *p_reg; /* action function to register VDP */
|
||||
char avrc_controller_name[BTA_SERVICE_NAME_LEN]; /* Default AVRCP controller name */
|
||||
@ -580,7 +598,9 @@ void BTA_AvDisable(void);
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name,
|
||||
UINT8 app_id, tBTA_AV_DATA_CBACK *p_data_cback, tBTA_AV_CO_FUNCTS *bta_av_cos, UINT8 tsep);
|
||||
UINT8 app_id, tBTA_AV_DATA_CBACK *p_data_cback,
|
||||
tBTA_AV_CO_FUNCTS *bta_av_cos, tBTA_AVRC_CO_FUNCTS *bta_avrc_cos,
|
||||
UINT8 tsep);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
|
@ -205,6 +205,8 @@ extern void bta_dm_co_ble_set_rsp_key_req(UINT8 rsp_key);
|
||||
|
||||
extern void bta_dm_co_ble_set_max_key_size(UINT8 ble_key_size);
|
||||
|
||||
extern void bta_dm_co_ble_set_min_key_size(UINT8 ble_key_size);
|
||||
|
||||
extern void bta_dm_co_ble_set_accept_auth_enable(UINT8 enable);
|
||||
|
||||
extern UINT8 bta_dm_co_ble_get_accept_auth_enable(void);
|
||||
|
@ -96,7 +96,7 @@ void bta_hf_client_sco_co_close(void);
|
||||
** Returns number of bytes got from application
|
||||
**
|
||||
*******************************************************************************/
|
||||
uint32_t bta_hf_client_sco_co_out_data(uint8_t *p_buf, uint32_t sz);
|
||||
uint32_t bta_hf_client_sco_co_out_data(UINT16 sco_index, UINT8 *p_buf, UINT32 sz);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "osi/allocator.h"
|
||||
#include "osi/osi.h"
|
||||
#include "stack/bt_types.h"
|
||||
#include "bta/utl.h"
|
||||
#include "bta/bta_sys.h"
|
||||
@ -137,7 +138,7 @@ UINT8 bta_jv_alloc_sec_id(void)
|
||||
return ret;
|
||||
|
||||
}
|
||||
static int get_sec_id_used(void)
|
||||
UNUSED_ATTR static int get_sec_id_used(void)
|
||||
{
|
||||
int i;
|
||||
int used = 0;
|
||||
@ -146,12 +147,13 @@ static int get_sec_id_used(void)
|
||||
used++;
|
||||
}
|
||||
}
|
||||
if (used == BTA_JV_NUM_SERVICE_ID)
|
||||
if (used == BTA_JV_NUM_SERVICE_ID) {
|
||||
APPL_TRACE_ERROR("get_sec_id_used, sec id exceeds the limit:%d",
|
||||
BTA_JV_NUM_SERVICE_ID);
|
||||
}
|
||||
return used;
|
||||
}
|
||||
static int get_rfc_cb_used(void)
|
||||
UNUSED_ATTR static int get_rfc_cb_used(void)
|
||||
{
|
||||
int i;
|
||||
int used = 0;
|
||||
@ -160,9 +162,10 @@ static int get_rfc_cb_used(void)
|
||||
used++;
|
||||
}
|
||||
}
|
||||
if (used == BTA_JV_MAX_RFC_CONN)
|
||||
if (used == BTA_JV_MAX_RFC_CONN) {
|
||||
APPL_TRACE_ERROR("get_sec_id_used, rfc ctrl block exceeds the limit:%d",
|
||||
BTA_JV_MAX_RFC_CONN);
|
||||
}
|
||||
return used;
|
||||
}
|
||||
|
||||
@ -474,19 +477,21 @@ static tBTA_JV_STATUS bta_jv_free_set_pm_profile_cb(UINT32 jv_handle)
|
||||
< BTA_JV_MAX_RFC_SR_SESSION && bta_jv_cb.rfc_cb[hi].rfc_hdl[si]) {
|
||||
tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(bta_jv_cb.rfc_cb[hi].rfc_hdl[si]);
|
||||
if (p_pcb) {
|
||||
if (NULL == p_pcb->p_pm_cb)
|
||||
if (NULL == p_pcb->p_pm_cb) {
|
||||
APPL_TRACE_WARNING("%s(jv_handle:"
|
||||
" 0x%x):port_handle: 0x%x, p_pm_cb: %d: no link to "
|
||||
"pm_cb?", __func__, jv_handle, p_pcb->port_handle, i);
|
||||
}
|
||||
p_cb = &p_pcb->p_pm_cb;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (jv_handle < BTA_JV_MAX_L2C_CONN) {
|
||||
tBTA_JV_L2C_CB *p_l2c_cb = &bta_jv_cb.l2c_cb[jv_handle];
|
||||
if (NULL == p_l2c_cb->p_pm_cb)
|
||||
if (NULL == p_l2c_cb->p_pm_cb) {
|
||||
APPL_TRACE_WARNING("%s(jv_handle: "
|
||||
"0x%x): p_pm_cb: %d: no link to pm_cb?", __func__, jv_handle, i);
|
||||
}
|
||||
p_cb = &p_l2c_cb->p_pm_cb;
|
||||
}
|
||||
}
|
||||
@ -742,9 +747,10 @@ void bta_jv_get_channel_id(tBTA_JV_MSG *p_data)
|
||||
bta_jv_cb.scn[channel - 1] = TRUE;
|
||||
scn = (UINT8) channel;
|
||||
}
|
||||
if (bta_jv_cb.p_dm_cback)
|
||||
if (bta_jv_cb.p_dm_cback) {
|
||||
bta_jv_cb.p_dm_cback(BTA_JV_GET_SCN_EVT, (tBTA_JV *)&scn,
|
||||
p_data->alloc_channel.user_data);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case BTA_JV_CONN_TYPE_L2CAP:
|
||||
@ -998,6 +1004,9 @@ static bool create_base_record(const uint32_t sdp_handle, const char *name, cons
|
||||
APPL_TRACE_DEBUG("create_base_record: successfully created base service "
|
||||
"record, handle: 0x%08x, scn: %d, name: %s, with_obex: %d",
|
||||
sdp_handle, channel, name, with_obex);
|
||||
|
||||
UNUSED(stage);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1031,6 +1040,8 @@ static int add_spp_sdp(const char *name, const int channel) {
|
||||
|
||||
APPL_TRACE_DEBUG("add_spp_sdp: service registered successfully, "
|
||||
"service_name: %s, handle 0x%08x)", name, handle);
|
||||
UNUSED(stage);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
@ -1523,6 +1534,7 @@ static int bta_jv_port_data_co_cback(UINT16 port_handle, UINT8 *buf, UINT16 len,
|
||||
tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(port_handle);
|
||||
int ret = 0;
|
||||
APPL_TRACE_DEBUG("%s, p_cb:%p, p_pcb:%p, len:%d, type:%d", __func__, p_cb, p_pcb, len, type);
|
||||
UNUSED(p_cb);
|
||||
if (p_pcb != NULL) {
|
||||
switch (type) {
|
||||
case DATA_CO_CALLBACK_TYPE_INCOMING:
|
||||
|
@ -571,7 +571,12 @@ void bta_sys_sendmsg(void *p_msg)
|
||||
// there is a procedure in progress that can schedule a task via this
|
||||
// message queue. This causes |btu_bta_msg_queue| to get cleaned up before
|
||||
// it gets used here; hence we check for NULL before using it.
|
||||
#ifdef TASK_MONITOR_MODE
|
||||
if (btu_task_post(SIG_BTU_BTA_MSG, p_msg, TASK_POST_BLOCKING_WITH_TO) != TASK_POST_SUCCESS) {
|
||||
#else
|
||||
if (btu_task_post(SIG_BTU_BTA_MSG, p_msg, TASK_POST_BLOCKING) != TASK_POST_SUCCESS) {
|
||||
#endif
|
||||
|
||||
osi_free(p_msg);
|
||||
}
|
||||
}
|
||||
@ -590,8 +595,11 @@ void bta_alarm_cb(void *data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data;
|
||||
|
||||
#ifdef TASK_MONITOR_MODE
|
||||
btu_task_post(SIG_BTU_BTA_ALARM, p_tle, TASK_POST_BLOCKING_WITH_TO);
|
||||
#else
|
||||
btu_task_post(SIG_BTU_BTA_ALARM, p_tle, TASK_POST_BLOCKING);
|
||||
#endif
|
||||
}
|
||||
|
||||
void bta_sys_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout_ms)
|
||||
|
@ -750,7 +750,9 @@ static void _btc_read_le_key(const uint8_t key_type, const size_t key_len, bt_bd
|
||||
*device_added = true;
|
||||
}
|
||||
|
||||
#if (!CONFIG_BT_STACK_NO_LOG)
|
||||
char bd_str[20] = {0};
|
||||
#endif
|
||||
BTC_TRACE_DEBUG("%s() Adding key type %d for %s", __func__,
|
||||
key_type, bdaddr_to_string(&bd_addr, bd_str, sizeof(bd_str)));
|
||||
BTA_DmAddBleKey(bta_bd_addr, (tBTA_LE_KEY_VALUE *)buffer, key_type);
|
||||
|
@ -290,6 +290,9 @@ static void btc_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
|
||||
|
||||
}
|
||||
|
||||
#if (CONFIG_BT_STACK_NO_LOG)
|
||||
(void) status;
|
||||
#endif
|
||||
BTC_TRACE_DEBUG("%s, authentication status = %x", __func__, status);
|
||||
return;
|
||||
|
||||
|
@ -47,10 +47,22 @@
|
||||
#endif /* #if BTC_HF_CLIENT_INCLUDED */
|
||||
#endif /* #if CONFIG_CLASSIC_BT_ENABLED */
|
||||
|
||||
#if CONFIG_BLE_MESH
|
||||
#include "btc_ble_mesh_ble.h"
|
||||
#include "btc_ble_mesh_prov.h"
|
||||
#include "btc_ble_mesh_health_model.h"
|
||||
#include "btc_ble_mesh_config_model.h"
|
||||
#include "btc_ble_mesh_generic_model.h"
|
||||
#include "btc_ble_mesh_lighting_model.h"
|
||||
#include "btc_ble_mesh_sensor_model.h"
|
||||
#include "btc_ble_mesh_time_scene_model.h"
|
||||
#endif /* #if CONFIG_BLE_MESH */
|
||||
|
||||
static xTaskHandle xBtcTaskHandle = NULL;
|
||||
static xQueueHandle xBtcQueue = 0;
|
||||
|
||||
void bt_abort_with_coredump_log(uint16_t error);
|
||||
|
||||
static btc_func_t profile_tab[BTC_PID_NUM] = {
|
||||
[BTC_PID_MAIN_INIT] = {btc_main_call_handler, NULL },
|
||||
[BTC_PID_DEV] = {btc_dev_call_handler, NULL },
|
||||
@ -78,7 +90,8 @@ static btc_func_t profile_tab[BTC_PID_NUM] = {
|
||||
[BTC_PID_PRF_QUE] = {btc_profile_queue_handler, NULL },
|
||||
#if BTC_AV_INCLUDED
|
||||
[BTC_PID_A2DP] = {btc_a2dp_call_handler, btc_a2dp_cb_handler },
|
||||
[BTC_PID_AVRC] = {btc_avrc_call_handler, NULL },
|
||||
[BTC_PID_AVRC_CT] = {btc_avrc_ct_call_handler, NULL },
|
||||
[BTC_PID_AVRC_TG] = {btc_avrc_tg_call_handler, NULL },
|
||||
#endif /* #if BTC_AV_INCLUDED */
|
||||
#if CONFIG_BT_SPP_ENABLED
|
||||
[BTC_PID_SPP] = {btc_spp_call_handler, btc_spp_cb_handler },
|
||||
@ -87,6 +100,25 @@ static btc_func_t profile_tab[BTC_PID_NUM] = {
|
||||
[BTC_PID_HF_CLIENT] = {btc_hf_client_call_handler, btc_hf_client_cb_handler},
|
||||
#endif /* #if BTC_HF_CLIENT_INCLUDED */
|
||||
#endif /* #if CONFIG_CLASSIC_BT_ENABLED */
|
||||
#if CONFIG_BLE_MESH
|
||||
[BTC_PID_PROV] = {btc_ble_mesh_prov_call_handler, btc_ble_mesh_prov_cb_handler },
|
||||
[BTC_PID_MODEL] = {btc_ble_mesh_model_call_handler, btc_ble_mesh_model_cb_handler },
|
||||
[BTC_PID_HEALTH_CLIENT] = {btc_ble_mesh_health_client_call_handler, btc_ble_mesh_health_client_cb_handler },
|
||||
[BTC_PID_HEALTH_SERVER] = {btc_ble_mesh_health_server_call_handler, btc_ble_mesh_health_server_cb_handler },
|
||||
[BTC_PID_CONFIG_CLIENT] = {btc_ble_mesh_config_client_call_handler, btc_ble_mesh_config_client_cb_handler },
|
||||
[BTC_PID_CONFIG_SERVER] = {NULL, btc_ble_mesh_config_server_cb_handler },
|
||||
[BTC_PID_GENERIC_CLIENT] = {btc_ble_mesh_generic_client_call_handler, btc_ble_mesh_generic_client_cb_handler },
|
||||
[BTC_PID_LIGHTING_CLIENT] = {btc_ble_mesh_lighting_client_call_handler, btc_ble_mesh_lighting_client_cb_handler },
|
||||
[BTC_PID_SENSOR_CLIENT] = {btc_ble_mesh_sensor_client_call_handler, btc_ble_mesh_sensor_client_cb_handler },
|
||||
[BTC_PID_TIME_SCENE_CLIENT] = {btc_ble_mesh_time_scene_client_call_handler, btc_ble_mesh_time_scene_client_cb_handler},
|
||||
[BTC_PID_GENERIC_SERVER] = {NULL, btc_ble_mesh_generic_server_cb_handler },
|
||||
[BTC_PID_LIGHTING_SERVER] = {NULL, btc_ble_mesh_lighting_server_cb_handler },
|
||||
[BTC_PID_SENSOR_SERVER] = {NULL, btc_ble_mesh_sensor_server_cb_handler },
|
||||
[BTC_PID_TIME_SCENE_SERVER] = {NULL, btc_ble_mesh_time_scene_server_cb_handler},
|
||||
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
|
||||
[BTC_PID_BLE_MESH_BLE_COEX] = {btc_ble_mesh_ble_call_handler, btc_ble_mesh_ble_cb_handler },
|
||||
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
|
||||
#endif /* #if CONFIG_BLE_MESH */
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
@ -127,6 +159,10 @@ static bt_status_t btc_task_post(btc_msg_t *msg, task_post_t timeout)
|
||||
|
||||
if (xQueueSend(xBtcQueue, msg, timeout) != pdTRUE) {
|
||||
BTC_TRACE_ERROR("Btc Post failed\n");
|
||||
#ifdef TASK_MONITOR_MODE
|
||||
ets_printf("!! Btc Post failed.Timeout Abort !!");
|
||||
bt_abort_with_coredump_log(0);
|
||||
#endif
|
||||
return BT_STATUS_BUSY;
|
||||
}
|
||||
|
||||
@ -157,14 +193,41 @@ bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg
|
||||
} else {
|
||||
lmsg.arg = NULL;
|
||||
}
|
||||
|
||||
#ifdef TASK_MONITOR_MODE
|
||||
return btc_task_post(&lmsg, TASK_POST_BLOCKING_WITH_TO);
|
||||
#else
|
||||
return btc_task_post(&lmsg, TASK_POST_BLOCKING);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if (CONFIG_SPIRAM_USE_MALLOC && CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST)
|
||||
StaticQueue_t *btc_queue_buffer = NULL;
|
||||
uint8_t *btc_queue_storage = NULL;
|
||||
#endif
|
||||
|
||||
int btc_init(void)
|
||||
{
|
||||
#if (CONFIG_SPIRAM_USE_MALLOC && CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST)
|
||||
|
||||
btc_queue_buffer = heap_caps_malloc(sizeof(StaticQueue_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
if (!btc_queue_buffer) {
|
||||
BTC_TRACE_ERROR("Btc Queue malloc fail in PSRAM.\n");
|
||||
return BT_STATUS_NOMEM;
|
||||
}
|
||||
|
||||
btc_queue_storage = heap_caps_malloc((BTC_TASK_QUEUE_LEN*sizeof(btc_msg_t)), MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT);
|
||||
if (!btc_queue_storage ) {
|
||||
BTC_TRACE_ERROR("Btc Queue malloc fail in PSRAM.\n");
|
||||
return BT_STATUS_NOMEM;
|
||||
}
|
||||
|
||||
xBtcQueue = xQueueCreateStatic(BTC_TASK_QUEUE_LEN, sizeof(btc_msg_t), btc_queue_storage, btc_queue_buffer);
|
||||
BTC_TRACE_API("Btc Queue malloc in PSRAM Success.\n");
|
||||
#else
|
||||
BTC_TRACE_API("xBtcQueue in internal RAM.");
|
||||
xBtcQueue = xQueueCreate(BTC_TASK_QUEUE_LEN, sizeof(btc_msg_t));
|
||||
#endif
|
||||
xTaskCreatePinnedToCore(btc_task, "Btc_task", BTC_TASK_STACK_SIZE, NULL, BTC_TASK_PRIO, &xBtcTaskHandle, BTC_TASK_PINNED_TO_CORE);
|
||||
if (xBtcTaskHandle == NULL || xBtcQueue == 0){
|
||||
return BT_STATUS_NOMEM;
|
||||
@ -184,6 +247,17 @@ void btc_deinit(void)
|
||||
#if SCAN_QUEUE_CONGEST_CHECK
|
||||
btc_adv_list_deinit();
|
||||
#endif
|
||||
|
||||
#if (CONFIG_SPIRAM_USE_MALLOC && CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST)
|
||||
if(btc_queue_buffer){
|
||||
heap_caps_free(btc_queue_buffer);
|
||||
btc_queue_buffer = NULL;
|
||||
}
|
||||
if(btc_queue_storage){
|
||||
heap_caps_free(btc_queue_storage);
|
||||
btc_queue_storage = NULL;
|
||||
}
|
||||
#endif
|
||||
xBtcTaskHandle = NULL;
|
||||
xBtcQueue = 0;
|
||||
}
|
||||
|
@ -57,12 +57,30 @@ typedef enum {
|
||||
BTC_PID_GAP_BT,
|
||||
BTC_PID_PRF_QUE,
|
||||
BTC_PID_A2DP,
|
||||
BTC_PID_AVRC,
|
||||
BTC_PID_AVRC_CT,
|
||||
BTC_PID_AVRC_TG,
|
||||
BTC_PID_SPP,
|
||||
#if BTC_HF_CLIENT_INCLUDED
|
||||
BTC_PID_HF_CLIENT,
|
||||
#endif /* BTC_HF_CLIENT_INCLUDED */
|
||||
#endif /* CONFIG_CLASSIC_BT_ENABLED */
|
||||
#if CONFIG_BLE_MESH
|
||||
BTC_PID_PROV,
|
||||
BTC_PID_MODEL,
|
||||
BTC_PID_HEALTH_CLIENT,
|
||||
BTC_PID_HEALTH_SERVER,
|
||||
BTC_PID_CONFIG_CLIENT,
|
||||
BTC_PID_CONFIG_SERVER,
|
||||
BTC_PID_GENERIC_CLIENT,
|
||||
BTC_PID_LIGHTING_CLIENT,
|
||||
BTC_PID_SENSOR_CLIENT,
|
||||
BTC_PID_TIME_SCENE_CLIENT,
|
||||
BTC_PID_GENERIC_SERVER,
|
||||
BTC_PID_LIGHTING_SERVER,
|
||||
BTC_PID_SENSOR_SERVER,
|
||||
BTC_PID_TIME_SCENE_SERVER,
|
||||
BTC_PID_BLE_MESH_BLE_COEX,
|
||||
#endif /* CONFIG_BLE_MESH */
|
||||
BTC_PID_NUM,
|
||||
} btc_pid_t; //btc profile id
|
||||
|
||||
|
@ -170,6 +170,14 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
|
||||
BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id,
|
||||
status, &rsp);
|
||||
|
||||
if(status != GATT_SUCCESS) {
|
||||
if (blufi_env.prepare_buf) {
|
||||
osi_free(blufi_env.prepare_buf);
|
||||
blufi_env.prepare_buf = NULL;
|
||||
}
|
||||
BLUFI_TRACE_ERROR("write data error , error code 0x%x\n", status);
|
||||
return;
|
||||
}
|
||||
memcpy(blufi_env.prepare_buf + p_data->req_data.p_data->write_req.offset,
|
||||
p_data->req_data.p_data->write_req.value,
|
||||
p_data->req_data.p_data->write_req.len);
|
||||
@ -194,7 +202,7 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
|
||||
BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id,
|
||||
GATT_SUCCESS, NULL);
|
||||
|
||||
if (p_data->req_data.p_data->exec_write == GATT_PREP_WRITE_EXEC) {
|
||||
if (blufi_env.prepare_buf && p_data->req_data.p_data->exec_write == GATT_PREP_WRITE_EXEC) {
|
||||
btc_blufi_recv_handler(blufi_env.prepare_buf, blufi_env.prepare_len);
|
||||
}
|
||||
|
||||
|
@ -117,7 +117,7 @@ void btc_a2dp_control_media_ctrl(esp_a2d_media_ctrl_t ctrl)
|
||||
APPL_TRACE_DEBUG("BTC MEDIA (A2DP-DATA) EVENT %u", ctrl);
|
||||
|
||||
if (btc_aa_ctrl_cb.a2dp_cmd_pending != ESP_A2D_MEDIA_CTRL_NONE) {
|
||||
APPL_TRACE_DEBUG("un-acked a2dp cmd: %u", btc_aa_ctrl_cb.a2dp_cmd_pending);
|
||||
APPL_TRACE_WARNING("un-acked a2dp cmd: %u", btc_aa_ctrl_cb.a2dp_cmd_pending);
|
||||
a2dp_cmd_acknowledge(ctrl, ESP_A2D_MEDIA_CTRL_ACK_BUSY);
|
||||
return;
|
||||
}
|
||||
@ -179,6 +179,11 @@ void btc_a2dp_control_media_ctrl(esp_a2d_media_ctrl_t ctrl)
|
||||
/* local suspend */
|
||||
if (btc_av_stream_started_ready()) {
|
||||
btc_dispatch_sm_event(BTC_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0);
|
||||
#if (BTC_AV_SINK_INCLUDED == TRUE)
|
||||
if (btc_av_get_peer_sep() == AVDT_TSEP_SRC && btc_av_get_service_id() == BTA_A2DP_SINK_SERVICE_ID) {
|
||||
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_SUCCESS);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
/* we are not in started state; just ack back ok. This can happen if we are
|
||||
remotely suspended; clear REMOTE SUSPEND Flag */
|
||||
|
@ -88,7 +88,8 @@ enum {
|
||||
layers we might need to temporarily buffer up data */
|
||||
|
||||
/* 18 frames is equivalent to 6.89*18*2.9 ~= 360 ms @ 44.1 khz, 20 ms mediatick */
|
||||
#define MAX_OUTPUT_A2DP_SNK_FRAME_QUEUE_SZ (18)
|
||||
#define JITTER_BUFFER_WATER_LEVEL (15)
|
||||
#define MAX_OUTPUT_A2DP_SNK_FRAME_QUEUE_SZ (18 + JITTER_BUFFER_WATER_LEVEL)
|
||||
|
||||
typedef struct {
|
||||
UINT16 num_frames_to_be_processed;
|
||||
@ -104,6 +105,18 @@ typedef struct {
|
||||
UINT32 sample_rate;
|
||||
} tBTC_A2DP_SINK_CB;
|
||||
|
||||
typedef struct {
|
||||
xTaskHandle btc_aa_snk_task_hdl;
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
StaticTask_t *task;
|
||||
StackType_t *stack;
|
||||
#endif
|
||||
} a2dp_sink_task_t;
|
||||
|
||||
#define A2DP_MEM_CHECK(a, action) if (!a) {\
|
||||
APPL_TRACE_ERROR("%s ,failed to allocate ", __func__); action;\
|
||||
}
|
||||
|
||||
static void btc_a2dp_sink_thread_init(UNUSED_ATTR void *context);
|
||||
static void btc_a2dp_sink_thread_cleanup(UNUSED_ATTR void *context);
|
||||
static void btc_a2dp_sink_flush_q(fixed_queue_t *p_q);
|
||||
@ -122,12 +135,12 @@ static void btc_a2dp_sink_data_ready(UNUSED_ATTR void *context);
|
||||
static tBTC_A2DP_SINK_CB btc_aa_snk_cb;
|
||||
static int btc_a2dp_sink_state = BTC_A2DP_SINK_STATE_OFF;
|
||||
static future_t *btc_a2dp_sink_future = NULL;
|
||||
static xTaskHandle btc_aa_snk_task_hdl = NULL;
|
||||
static QueueHandle_t btc_aa_snk_data_queue = NULL;
|
||||
static QueueHandle_t btc_aa_snk_ctrl_queue = NULL;
|
||||
static QueueSetHandle_t btc_aa_snk_queue_set;
|
||||
|
||||
static esp_a2d_sink_data_cb_t bt_aa_snk_data_cb = NULL;
|
||||
static a2dp_sink_task_t a2dp_sink_task;
|
||||
|
||||
void btc_a2dp_sink_reg_data_cb(esp_a2d_sink_data_cb_t callback)
|
||||
{
|
||||
@ -270,26 +283,40 @@ bool btc_a2dp_sink_startup(void)
|
||||
if (!btc_aa_snk_data_queue || !btc_aa_snk_ctrl_queue || !btc_aa_snk_queue_set ) {
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
xTaskCreatePinnedToCore(btc_a2dp_sink_task_handler, BTC_A2DP_SINK_TASK_NAME, BTC_A2DP_SINK_TASK_STACK_SIZE, NULL, BTC_A2DP_SINK_TASK_PRIO, &btc_aa_snk_task_hdl, BTC_A2DP_SINK_TASK_PINNED_TO_CORE);
|
||||
if (btc_aa_snk_task_hdl == NULL) {
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
#if !CONFIG_SPIRAM_USE_MALLOC
|
||||
xTaskCreatePinnedToCore(btc_a2dp_sink_task_handler, BTC_A2DP_SINK_TASK_NAME, BTC_A2DP_SINK_TASK_STACK_SIZE, NULL, BTC_A2DP_SINK_TASK_PRIO, &a2dp_sink_task.btc_aa_snk_task_hdl, BTC_A2DP_SINK_TASK_PINNED_TO_CORE);
|
||||
A2DP_MEM_CHECK(a2dp_sink_task.btc_aa_snk_task_hdl, goto error_exit);
|
||||
#else
|
||||
a2dp_sink_task.stack = heap_caps_malloc(BTC_A2DP_SINK_TASK_STACK_SIZE, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT);
|
||||
a2dp_sink_task.task = heap_caps_calloc(1, sizeof(StaticTask_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
A2DP_MEM_CHECK(a2dp_sink_task.stack, goto error_exit);
|
||||
A2DP_MEM_CHECK(a2dp_sink_task.task, goto error_exit);
|
||||
a2dp_sink_task.btc_aa_snk_task_hdl = xTaskCreateStaticPinnedToCore(btc_a2dp_sink_task_handler, BTC_A2DP_SINK_TASK_NAME, BTC_A2DP_SINK_TASK_STACK_SIZE, NULL, BTC_A2DP_SINK_TASK_PRIO, a2dp_sink_task.stack, a2dp_sink_task.task, BTC_A2DP_SINK_TASK_PINNED_TO_CORE);
|
||||
A2DP_MEM_CHECK(a2dp_sink_task.btc_aa_snk_task_hdl, goto error_exit);
|
||||
#endif
|
||||
btc_a2dp_sink_ctrl_post(BTC_MEDIA_TASK_SINK_INIT, NULL);
|
||||
|
||||
APPL_TRACE_EVENT("## A2DP SINK MEDIA THREAD STARTED ##\n");
|
||||
|
||||
return true;
|
||||
|
||||
error_exit:;
|
||||
error_exit:
|
||||
APPL_TRACE_ERROR("%s unable to start up media thread\n", __func__);
|
||||
|
||||
if (btc_aa_snk_task_hdl != NULL) {
|
||||
vTaskDelete(btc_aa_snk_task_hdl);
|
||||
btc_aa_snk_task_hdl = NULL;
|
||||
if (a2dp_sink_task.btc_aa_snk_task_hdl != NULL) {
|
||||
vTaskDelete(a2dp_sink_task.btc_aa_snk_task_hdl);
|
||||
a2dp_sink_task.btc_aa_snk_task_hdl = NULL;
|
||||
}
|
||||
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
if (a2dp_sink_task.task) {
|
||||
free(a2dp_sink_task.task);
|
||||
a2dp_sink_task.task = NULL;
|
||||
}
|
||||
if (a2dp_sink_task.stack) {
|
||||
free(a2dp_sink_task.stack);
|
||||
a2dp_sink_task.stack = NULL;
|
||||
}
|
||||
#endif
|
||||
if (btc_aa_snk_data_queue) {
|
||||
vQueueDelete(btc_aa_snk_data_queue);
|
||||
btc_aa_snk_data_queue = NULL;
|
||||
@ -332,9 +359,15 @@ void btc_a2dp_sink_shutdown(void)
|
||||
future_await(btc_a2dp_sink_future);
|
||||
btc_a2dp_sink_future = NULL;
|
||||
|
||||
vTaskDelete(btc_aa_snk_task_hdl);
|
||||
btc_aa_snk_task_hdl = NULL;
|
||||
vTaskDelete(a2dp_sink_task.btc_aa_snk_task_hdl);
|
||||
a2dp_sink_task.btc_aa_snk_task_hdl = NULL;
|
||||
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
free(a2dp_sink_task.stack);
|
||||
free(a2dp_sink_task.task);
|
||||
a2dp_sink_task.task = NULL;
|
||||
a2dp_sink_task.stack = NULL;
|
||||
#endif
|
||||
vQueueDelete(btc_aa_snk_data_queue);
|
||||
btc_aa_snk_data_queue = NULL;
|
||||
|
||||
@ -458,7 +491,7 @@ static void btc_a2dp_sink_data_ready(UNUSED_ATTR void *context)
|
||||
tBT_SBC_HDR *p_msg;
|
||||
|
||||
if (fixed_queue_is_empty(btc_aa_snk_cb.RxSbcQ)) {
|
||||
APPL_TRACE_DEBUG(" QUE EMPTY ");
|
||||
APPL_TRACE_ERROR(" QUE EMPTY ");
|
||||
} else {
|
||||
if (btc_aa_snk_cb.rx_flush == TRUE) {
|
||||
btc_a2dp_sink_flush_q(btc_aa_snk_cb.RxSbcQ);
|
||||
@ -615,6 +648,7 @@ static void btc_a2dp_sink_handle_decoder_reset(tBTC_MEDIA_SINK_CFG_UPDATE *p_msg
|
||||
|
||||
int frames_to_process = ((freq_multiple) / (num_blocks * num_subbands)) + 1;
|
||||
APPL_TRACE_EVENT(" Frames to be processed in 20 ms %d\n", frames_to_process);
|
||||
UNUSED(frames_to_process);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -774,8 +808,13 @@ UINT8 btc_a2dp_sink_enque_buf(BT_HDR *p_pkt)
|
||||
p_pkt->offset + p_pkt->len)) != NULL) {
|
||||
memcpy(p_msg, p_pkt, (sizeof(BT_HDR) + p_pkt->offset + p_pkt->len));
|
||||
p_msg->num_frames_to_be_processed = (*((UINT8 *)(p_msg + 1) + p_msg->offset)) & 0x0f;
|
||||
APPL_TRACE_VERBOSE("btc_a2dp_sink_enque_buf %d + \n", p_msg->num_frames_to_be_processed);
|
||||
APPL_TRACE_DEBUG("btc_a2dp_sink_enque_buf %d + \n", p_msg->num_frames_to_be_processed);
|
||||
fixed_queue_enqueue(btc_aa_snk_cb.RxSbcQ, p_msg);
|
||||
|
||||
if (fixed_queue_length(btc_aa_snk_cb.RxSbcQ) < JITTER_BUFFER_WATER_LEVEL) {
|
||||
return fixed_queue_length(btc_aa_snk_cb.RxSbcQ);
|
||||
}
|
||||
|
||||
btc_a2dp_sink_data_post(BTC_A2DP_SINK_DATA_EVT);
|
||||
} else {
|
||||
/* let caller deal with a failed allocation */
|
||||
@ -827,6 +866,8 @@ static void btc_a2dp_sink_thread_cleanup(UNUSED_ATTR void *context)
|
||||
|
||||
fixed_queue_free(btc_aa_snk_cb.RxSbcQ, osi_free_func);
|
||||
|
||||
btc_aa_snk_cb.RxSbcQ = NULL;
|
||||
|
||||
future_ready(btc_a2dp_sink_future, NULL);
|
||||
}
|
||||
|
||||
|
@ -495,10 +495,11 @@ static UINT64 time_now_us()
|
||||
static void log_tstamps_us(char *comment)
|
||||
{
|
||||
static UINT64 prev_us = 0;
|
||||
const UINT64 now_us = time_now_us();
|
||||
UINT64 now_us = time_now_us();
|
||||
APPL_TRACE_DEBUG("[%s] ts %08llu, diff : %08llu, queue sz %d", comment, now_us, now_us - prev_us,
|
||||
fixed_queue_length(btc_aa_src_cb.TxAaQ));
|
||||
prev_us = now_us;
|
||||
UNUSED(prev_us);
|
||||
}
|
||||
|
||||
/* when true media task discards any tx frames */
|
||||
@ -819,7 +820,7 @@ static void btc_a2dp_source_enc_init(BT_HDR *p_msg)
|
||||
btc_aa_src_cb.timestamp = 0;
|
||||
|
||||
/* SBC encoder config (enforced even if not used) */
|
||||
|
||||
btc_sbc_encoder.sbc_mode = SBC_MODE_STD;
|
||||
btc_sbc_encoder.s16ChannelMode = pInitAudio->ChannelMode;
|
||||
btc_sbc_encoder.s16NumOfSubBands = pInitAudio->NumOfSubBands;
|
||||
btc_sbc_encoder.s16NumOfBlocks = pInitAudio->NumOfBlocks;
|
||||
@ -878,7 +879,6 @@ static void btc_a2dp_source_enc_update(BT_HDR *p_msg)
|
||||
BTC_MEDIA_AA_SBC_OFFSET - sizeof(BT_HDR))
|
||||
< pUpdateAudio->MinMtuSize) ? (BTC_MEDIA_AA_BUF_SIZE - BTC_MEDIA_AA_SBC_OFFSET
|
||||
- sizeof(BT_HDR)) : pUpdateAudio->MinMtuSize;
|
||||
|
||||
/* Set the initial target bit rate */
|
||||
pstrEncParams->u16BitRate = btc_a2dp_source_get_sbc_rate();
|
||||
|
||||
@ -1155,10 +1155,16 @@ static UINT8 btc_get_num_aa_frame(void)
|
||||
|
||||
/* calculate nbr of frames pending for this media tick */
|
||||
result = btc_aa_src_cb.media_feeding_state.pcm.counter / pcm_bytes_per_frame;
|
||||
if (result > MAX_PCM_FRAME_NUM_PER_TICK) {
|
||||
APPL_TRACE_WARNING("%s() - Limiting frames to be sent from %d to %d"
|
||||
, __FUNCTION__, result, MAX_PCM_FRAME_NUM_PER_TICK);
|
||||
result = MAX_PCM_FRAME_NUM_PER_TICK;
|
||||
|
||||
/* limit the frames to be sent */
|
||||
UINT32 frm_nb_threshold = MAX_OUTPUT_A2DP_SRC_FRAME_QUEUE_SZ - fixed_queue_length(btc_aa_src_cb.TxAaQ);
|
||||
if (frm_nb_threshold > MAX_PCM_FRAME_NUM_PER_TICK) {
|
||||
frm_nb_threshold = MAX_PCM_FRAME_NUM_PER_TICK;
|
||||
}
|
||||
|
||||
if (result > frm_nb_threshold) {
|
||||
APPL_TRACE_EVENT("Limit frms to send from %d to %d", result, frm_nb_threshold);
|
||||
result = frm_nb_threshold;
|
||||
}
|
||||
btc_aa_src_cb.media_feeding_state.pcm.counter -= result * pcm_bytes_per_frame;
|
||||
|
||||
@ -1374,8 +1380,7 @@ static void btc_media_aa_prep_sbc_2_send(UINT8 nb_frame)
|
||||
if (btc_media_aa_read_feeding()) {
|
||||
/* SBC encode and descramble frame */
|
||||
SBC_Encoder(&(btc_sbc_encoder));
|
||||
A2D_SbcChkFrInit(btc_sbc_encoder.pu8Packet);
|
||||
A2D_SbcDescramble(btc_sbc_encoder.pu8Packet, btc_sbc_encoder.u16PacketLength);
|
||||
|
||||
/* Update SBC frame length */
|
||||
p_buf->len += btc_sbc_encoder.u16PacketLength;
|
||||
nb_frame--;
|
||||
@ -1657,6 +1662,8 @@ static void btc_a2dp_source_thread_cleanup(UNUSED_ATTR void *context)
|
||||
|
||||
fixed_queue_free(btc_aa_src_cb.TxAaQ, osi_free_func);
|
||||
|
||||
btc_aa_src_cb.TxAaQ = NULL;
|
||||
|
||||
future_ready(btc_a2dp_source_future, NULL);
|
||||
}
|
||||
|
||||
|
@ -148,6 +148,7 @@ static void btc_av_event_free_data(btc_sm_event_t event, void *p_data);
|
||||
*************************************************************************/
|
||||
|
||||
extern tBTA_AV_CO_FUNCTS bta_av_a2d_cos;
|
||||
extern tBTA_AVRC_CO_FUNCTS bta_avrc_cos;
|
||||
/*****************************************************************************
|
||||
** Local helper functions
|
||||
******************************************************************************/
|
||||
@ -988,7 +989,10 @@ static bt_status_t btc_av_init(int service_id)
|
||||
}
|
||||
|
||||
btc_a2dp_on_init();
|
||||
|
||||
esp_a2d_cb_param_t param;
|
||||
memset(¶m, 0, sizeof(esp_a2d_cb_param_t));
|
||||
param.a2d_prof_stat.init_state = 1;
|
||||
btc_a2d_cb_to_app(ESP_A2D_PROF_STATE_EVT, ¶m);
|
||||
return BT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1038,23 +1042,28 @@ static void clean_up(int service_id)
|
||||
tle_av_open_on_rc = NULL;
|
||||
}
|
||||
#endif /* BTC_AV_SRC_INCLUDED */
|
||||
btc_dm_disable_service(BTA_A2DP_SOURCE_SERVICE_ID);
|
||||
}
|
||||
|
||||
btc_dm_disable_service(BTA_A2DP_SOURCE_SERVICE_ID);
|
||||
|
||||
if (service_id == BTA_A2DP_SINK_SERVICE_ID) {
|
||||
btc_dm_disable_service(BTA_A2DP_SINK_SERVICE_ID);
|
||||
}
|
||||
|
||||
/* Also shut down the AV state machine */
|
||||
btc_sm_shutdown(btc_av_cb.sm_handle);
|
||||
btc_av_cb.sm_handle = NULL;
|
||||
|
||||
if (service_id == BTA_A2DP_SINK_SERVICE_ID) {
|
||||
#if BTC_AV_SINK_INCLUDED
|
||||
btc_a2dp_sink_shutdown();
|
||||
#endif /* BTC_AV_SINK_INCLUDED */
|
||||
btc_dm_disable_service(BTA_A2DP_SINK_SERVICE_ID);
|
||||
}
|
||||
|
||||
if (btc_av_cb.sm_handle) {
|
||||
/* Also shut down the AV state machine */
|
||||
btc_sm_shutdown(btc_av_cb.sm_handle);
|
||||
btc_av_cb.sm_handle = NULL;
|
||||
} else {
|
||||
BTC_TRACE_WARNING("AV sm handle already free\n");
|
||||
}
|
||||
|
||||
esp_a2d_cb_param_t param;
|
||||
memset(¶m, 0, sizeof(esp_a2d_cb_param_t));
|
||||
param.a2d_prof_stat.init_state = 0;
|
||||
btc_a2d_cb_to_app(ESP_A2D_PROF_STATE_EVT, ¶m);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -1199,10 +1208,13 @@ static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
|
||||
BTC_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d\n", a2d_status);
|
||||
}
|
||||
}
|
||||
UNUSED(que_len);
|
||||
}
|
||||
#else
|
||||
static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
|
||||
{
|
||||
UNUSED(event);
|
||||
UNUSED(p_data);
|
||||
BTC_TRACE_WARNING("%s : event %u\n", __func__, event);
|
||||
}
|
||||
#endif
|
||||
@ -1230,7 +1242,7 @@ bt_status_t btc_av_execute_service(BOOLEAN b_enable, UINT8 tsep)
|
||||
| BTA_AV_FEAT_RCTG | BTA_AV_FEAT_METADATA | BTA_AV_FEAT_VENDOR
|
||||
| BTA_AV_FEAT_RCCT | BTA_AV_FEAT_ADV_CTRL,
|
||||
bte_av_callback);
|
||||
BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTC_AV_SERVICE_NAME, 0, bte_av_media_callback, &bta_av_a2d_cos, tsep);
|
||||
BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTC_AV_SERVICE_NAME, 0, bte_av_media_callback, &bta_av_a2d_cos, &bta_avrc_cos, tsep);
|
||||
} else {
|
||||
BTA_AvDeregister(btc_av_cb.bta_handle);
|
||||
BTA_AvDisable();
|
||||
|
106
components/bt/bluedroid/btc/profile/std/avrc/bta_avrc_co.c
Normal file
106
components/bt/bluedroid/btc/profile/std/avrc/bta_avrc_co.c
Normal file
@ -0,0 +1,106 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the AVRC call-out function implementation for BTC.
|
||||
*
|
||||
******************************************************************************/
|
||||
// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Filename: bta_avrc_co.c
|
||||
*
|
||||
* Description: Bluetooth AVRC implementation
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "common/bt_target.h"
|
||||
#include "bta/bta_sys.h"
|
||||
#include "bta/bta_av_api.h"
|
||||
#include "btc_avrc.h"
|
||||
|
||||
#if BTC_AV_INCLUDED
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_avrc_co_cmd_allowed
|
||||
**
|
||||
** Description Check if local AVRCP TG configuration supports a specific
|
||||
** PASSTHROUGH command with the given operation_id
|
||||
**
|
||||
** Returns TRUE if operation_id is supported, FALSE otherwise
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_avrc_co_cmd_allowed(tBTA_AV_RC rc_id)
|
||||
{
|
||||
if (rc_id >= BTA_AV_VENDOR) {
|
||||
return FALSE;
|
||||
}
|
||||
const uint16_t *rc_cmd = btc_avrc_tg_get_supported_command();
|
||||
if (rc_cmd[rc_id >> 4] & ((uint16_t)1 << (rc_id & 0x0F))) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_avrc_co_rn_evt_cap
|
||||
**
|
||||
** Description get the event notifcation capabilities on AVRCP target
|
||||
**
|
||||
** Returns number of event_ids supported
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT8 bta_avrc_co_rn_evt_cap(UINT8 *event_ids)
|
||||
{
|
||||
if (event_ids == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT16 event_bits = btc_avrc_tg_get_rn_supported_evt();
|
||||
UINT8 count = 0;
|
||||
for (UINT8 i = 0; i < 16; ++i, event_bits >>= 1) {
|
||||
if (event_bits & 0x01) {
|
||||
event_ids[count++] = i;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_avrc_co_evt_supported
|
||||
**
|
||||
** Description Check if local AVRCP TG configuration supports the given
|
||||
** event_id
|
||||
**
|
||||
** Returns TRUE if operation_id is supported, FALSE otherwise
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_avrc_co_rn_evt_supported(UINT8 event_id)
|
||||
{
|
||||
return btc_avrc_tg_rn_evt_supported(event_id) ?
|
||||
TRUE : FALSE;
|
||||
}
|
||||
|
||||
/* the call out functions for AVRC */
|
||||
tBTA_AVRC_CO_FUNCTS bta_avrc_cos = {
|
||||
bta_avrc_co_cmd_allowed,
|
||||
bta_avrc_co_rn_evt_cap,
|
||||
bta_avrc_co_rn_evt_supported,
|
||||
};
|
||||
|
||||
#endif /* #if BTC_AV_INCLUDED */
|
File diff suppressed because it is too large
Load Diff
@ -604,6 +604,9 @@ static void btc_search_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data
|
||||
case BTA_DM_SEARCH_CANCEL_CMPL_EVT:
|
||||
BTC_TRACE_DEBUG("BTA_DM_SEARCH_CANCEL_CMPL_EVT\n");
|
||||
break;
|
||||
case BTA_DM_INQ_DISCARD_NUM_EVT:
|
||||
param.scan_rst.num_dis = p_data->inq_dis.num_dis;
|
||||
break;
|
||||
default:
|
||||
BTC_TRACE_ERROR("%s : Unknown event 0x%x\n", __FUNCTION__, event);
|
||||
return;
|
||||
@ -1186,6 +1189,12 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
|
||||
bta_dm_co_ble_set_max_key_size(key_size);
|
||||
break;
|
||||
}
|
||||
case ESP_BLE_SM_MIN_KEY_SIZE: {
|
||||
uint8_t key_size = 0;
|
||||
STREAM_TO_UINT8(key_size, value);
|
||||
bta_dm_co_ble_set_min_key_size(key_size);
|
||||
break;
|
||||
}
|
||||
case ESP_BLE_SM_SET_STATIC_PASSKEY: {
|
||||
uint32_t passkey = 0;
|
||||
for(uint8_t i = 0; i < arg->set_security_param.len; i++)
|
||||
|
@ -715,10 +715,13 @@ void btc_gatts_call_handler(btc_msg_t *msg)
|
||||
#else
|
||||
//BTA_DmAddBleDevice(p_cb->bd_addr.address, addr_type, device_type);
|
||||
#endif
|
||||
/*
|
||||
not support background connection
|
||||
// Mark background connections
|
||||
if (!arg->open.is_direct) {
|
||||
BTA_DmBleSetBgConnType(BTM_BLE_CONN_AUTO, NULL);
|
||||
}
|
||||
*/
|
||||
|
||||
transport = BTA_GATT_TRANSPORT_LE;
|
||||
|
||||
|
@ -15,9 +15,58 @@
|
||||
#include "bta/bta_hf_client_co.h"
|
||||
#include "hci/hci_audio.h"
|
||||
#include "btc_hf_client.h"
|
||||
#include "osi/allocator.h"
|
||||
#include <string.h>
|
||||
|
||||
#if (BTA_HF_INCLUDED == TRUE)
|
||||
|
||||
#if (BTM_SCO_HCI_INCLUDED == TRUE)
|
||||
|
||||
#include "btm_int.h"
|
||||
#include "stack/btm_api.h"
|
||||
#include "oi_codec_sbc.h"
|
||||
#include "oi_status.h"
|
||||
#include "sbc_encoder.h"
|
||||
|
||||
#if (PLC_INCLUDED == TRUE)
|
||||
#include "sbc_plc.h"
|
||||
|
||||
typedef struct {
|
||||
bool first_good_frame_found;
|
||||
sbc_plc_state_t plc_state;
|
||||
int16_t sbc_plc_out[SBC_FS];
|
||||
} bta_hf_ct_plc_t;
|
||||
|
||||
#if HFP_DYNAMIC_MEMORY == FALSE
|
||||
static bta_hf_ct_plc_t bta_hf_ct_plc;
|
||||
#else
|
||||
static bta_hf_ct_plc_t *bta_hf_ct_plc_ptr;
|
||||
#define bta_hf_ct_plc (*bta_hf_ct_plc_ptr)
|
||||
#endif
|
||||
|
||||
#endif ///(PLC_INCLUDED == TRUE)
|
||||
|
||||
|
||||
#define HF_SBC_DEC_CONTEXT_DATA_LEN (CODEC_DATA_WORDS(1, SBC_CODEC_FAST_FILTER_BUFFERS))
|
||||
#define HF_SBC_DEC_PCM_DATA_LEN 240
|
||||
#define HF_SBC_ENC_PCM_DATA_LEN 240
|
||||
|
||||
#if HFP_DYNAMIC_MEMORY == FALSE
|
||||
static OI_CODEC_SBC_DECODER_CONTEXT hf_sbc_decoder_context;
|
||||
static OI_UINT32 hf_sbc_decoder_context_data[HF_SBC_DEC_CONTEXT_DATA_LEN];
|
||||
static OI_INT16 hf_sbc_decode_pcm_data[HF_SBC_DEC_PCM_DATA_LEN];
|
||||
|
||||
static SBC_ENC_PARAMS hf_sbc_encoder;
|
||||
#else
|
||||
static OI_CODEC_SBC_DECODER_CONTEXT *hf_sbc_decoder_context_ptr;
|
||||
static OI_UINT32 *hf_sbc_decoder_context_data;
|
||||
static OI_INT16 *hf_sbc_decode_pcm_data;
|
||||
#define hf_sbc_decoder_context (*hf_sbc_decoder_context_ptr)
|
||||
|
||||
static SBC_ENC_PARAMS *hf_sbc_encoder_ptr;
|
||||
#define hf_sbc_encoder (*hf_sbc_encoder_ptr)
|
||||
#endif /* HFP_DYNAMIC_MEMORY == FALSE */
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hf_client_co_audio_state
|
||||
@ -63,11 +112,55 @@ void bta_hf_client_co_audio_state(UINT16 handle, UINT8 state, tBTA_HFP_PEER_CODE
|
||||
tBTA_HFP_SCO_ROUTE_TYPE bta_hf_client_sco_co_init(UINT32 rx_bw, UINT32 tx_bw,
|
||||
tBTA_HFP_CODEC_INFO *p_codec_info, UINT8 app_id)
|
||||
{
|
||||
APPL_TRACE_EVENT("%s rx_bw %d, tx_bw %d, codec %d", __FUNCTION__, rx_bw, tx_bw,
|
||||
APPL_TRACE_EVENT("%s rx_bw %d, tx_bw %dhandle, codec %d", __FUNCTION__, rx_bw, tx_bw,
|
||||
p_codec_info->codec_type);
|
||||
return BTA_HFP_SCO_ROUTE_HCI;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hf_dec_init
|
||||
**
|
||||
** Description Initialize decoding task
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_hf_dec_init(void) {
|
||||
#if (PLC_INCLUDED == TRUE)
|
||||
sbc_plc_init(&(bta_hf_ct_plc.plc_state));
|
||||
#endif ///(PLC_INCLUDED == TRUE)
|
||||
|
||||
OI_STATUS status;
|
||||
status = OI_CODEC_SBC_DecoderReset(&hf_sbc_decoder_context, hf_sbc_decoder_context_data,
|
||||
HF_SBC_DEC_CONTEXT_DATA_LEN * sizeof(OI_UINT32), 1, 1, FALSE);
|
||||
if (!OI_SUCCESS(status)) {
|
||||
APPL_TRACE_ERROR("OI_CODEC_SBC_DecoderReset failed with error code %d\n", status);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hf_enc_init
|
||||
**
|
||||
** Description Initialize encoding task
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_hf_enc_init(void) {
|
||||
hf_sbc_encoder.sbc_mode = SBC_MODE_MSBC;
|
||||
hf_sbc_encoder.s16NumOfBlocks = 15;
|
||||
hf_sbc_encoder.s16NumOfSubBands = 8;
|
||||
hf_sbc_encoder.s16AllocationMethod = SBC_LOUDNESS;
|
||||
hf_sbc_encoder.s16BitPool = 26;
|
||||
hf_sbc_encoder.s16ChannelMode = SBC_MONO;
|
||||
hf_sbc_encoder.s16NumOfChannels = 1;
|
||||
hf_sbc_encoder.s16SamplingFreq = SBC_sf16000;
|
||||
|
||||
SBC_Encoder_Init(&(hf_sbc_encoder));
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hf_client_sco_co_open
|
||||
@ -82,6 +175,64 @@ void bta_hf_client_sco_co_open(UINT16 handle, UINT8 pkt_size, UINT16 event)
|
||||
{
|
||||
APPL_TRACE_EVENT("%s hdl %x, pkt_sz %u, event %u", __FUNCTION__, handle,
|
||||
pkt_size, event);
|
||||
|
||||
#if (HFP_DYNAMIC_MEMORY == TRUE)
|
||||
hf_sbc_decoder_context_ptr = osi_calloc(sizeof(OI_CODEC_SBC_DECODER_CONTEXT));
|
||||
hf_sbc_decoder_context_data = osi_calloc(HF_SBC_DEC_CONTEXT_DATA_LEN * sizeof(OI_UINT32));
|
||||
hf_sbc_decode_pcm_data = osi_calloc(HF_SBC_DEC_PCM_DATA_LEN * sizeof(OI_INT16));
|
||||
if (!hf_sbc_decoder_context_ptr || !hf_sbc_decoder_context_data || !hf_sbc_decode_pcm_data) {
|
||||
APPL_TRACE_ERROR("%s failed to allocate SBC decoder", __FUNCTION__);
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
hf_sbc_encoder_ptr = osi_calloc(sizeof(SBC_ENC_PARAMS));
|
||||
|
||||
if (!hf_sbc_encoder_ptr) {
|
||||
APPL_TRACE_ERROR("%s failed to allocate SBC encoder", __FUNCTION__);
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
#if (PLC_INCLUDED == TRUE)
|
||||
bta_hf_ct_plc_ptr = (bta_hf_ct_plc_t *)osi_calloc(sizeof(bta_hf_ct_plc_t));
|
||||
if (!bta_hf_ct_plc_ptr) {
|
||||
APPL_TRACE_ERROR("%s malloc fail.", __FUNCTION__);
|
||||
goto error_exit;
|
||||
}
|
||||
#endif ///(PLC_INCLUDED == TRUE)
|
||||
#endif /// (HFP_DYNAMIC_MEMORY == TRUE)
|
||||
|
||||
bta_hf_dec_init();
|
||||
bta_hf_enc_init();
|
||||
|
||||
return;
|
||||
|
||||
#if (HFP_DYNAMIC_MEMORY == TRUE)
|
||||
error_exit:;
|
||||
if (hf_sbc_decoder_context_ptr) {
|
||||
osi_free(hf_sbc_decoder_context_ptr);
|
||||
hf_sbc_decoder_context_ptr = NULL;
|
||||
}
|
||||
if (hf_sbc_decoder_context_data) {
|
||||
osi_free(hf_sbc_decoder_context_data);
|
||||
hf_sbc_decoder_context_data = NULL;
|
||||
}
|
||||
if (hf_sbc_decode_pcm_data) {
|
||||
osi_free(hf_sbc_decode_pcm_data);
|
||||
hf_sbc_decode_pcm_data = NULL;
|
||||
}
|
||||
if (hf_sbc_encoder_ptr) {
|
||||
osi_free(hf_sbc_encoder_ptr);
|
||||
hf_sbc_encoder_ptr = NULL;
|
||||
}
|
||||
|
||||
#if (PLC_INCLUDED == TRUE)
|
||||
if (bta_hf_ct_plc_ptr) {
|
||||
osi_free(bta_hf_ct_plc_ptr);
|
||||
bta_hf_ct_plc_ptr = NULL;
|
||||
}
|
||||
#endif ///(PLC_INCLUDED == TRUE)
|
||||
#endif /// (HFP_DYNAMIC_MEMORY == TRUE)
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -97,6 +248,30 @@ void bta_hf_client_sco_co_open(UINT16 handle, UINT8 pkt_size, UINT16 event)
|
||||
void bta_hf_client_sco_co_close(void)
|
||||
{
|
||||
APPL_TRACE_EVENT("%s", __FUNCTION__);
|
||||
|
||||
#if (PLC_INCLUDED == TRUE)
|
||||
sbc_plc_deinit(&(bta_hf_ct_plc.plc_state));
|
||||
bta_hf_ct_plc.first_good_frame_found = FALSE;
|
||||
|
||||
#if (HFP_DYNAMIC_MEMORY == TRUE)
|
||||
osi_free(bta_hf_ct_plc_ptr);
|
||||
#endif /// (HFP_DYNAMIC_MEMORY == TRUE)
|
||||
|
||||
#endif ///(PLC_INCLUDED == TRUE)
|
||||
|
||||
#if (HFP_DYNAMIC_MEMORY == TRUE)
|
||||
osi_free(hf_sbc_decoder_context_ptr);
|
||||
hf_sbc_decoder_context_ptr = NULL;
|
||||
|
||||
osi_free(hf_sbc_decoder_context_data);
|
||||
hf_sbc_decoder_context_data = NULL;
|
||||
|
||||
osi_free(hf_sbc_decode_pcm_data);
|
||||
hf_sbc_decode_pcm_data = NULL;
|
||||
|
||||
osi_free(hf_sbc_encoder_ptr);
|
||||
hf_sbc_encoder_ptr = NULL;
|
||||
#endif /* HFP_DYNAMIC_MEMORY == TRUE */
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -108,9 +283,104 @@ void bta_hf_client_sco_co_close(void)
|
||||
** Returns number of bytes got from application
|
||||
**
|
||||
*******************************************************************************/
|
||||
uint32_t bta_hf_client_sco_co_out_data(uint8_t *p_buf, uint32_t sz)
|
||||
UINT8 hf_sequence_number = 0;
|
||||
uint32_t bta_hf_client_sco_co_out_data(UINT16 sco_index, UINT8 *p_buf, UINT32 sz)
|
||||
{
|
||||
return btc_hf_client_outgoing_data_cb_to_app(p_buf, sz);
|
||||
tSCO_CONN *sco_p = &btm_cb.sco_cb.sco_db[sco_index];
|
||||
if (sco_p->esco.data.air_mode == BTM_SCO_AIR_MODE_CVSD) {
|
||||
// CVSD
|
||||
return btc_hf_client_outgoing_data_cb_to_app(p_buf, sz);
|
||||
} else if (sco_p->esco.data.air_mode == BTM_SCO_AIR_MODE_TRANSPNT) {
|
||||
// mSBC
|
||||
hf_sequence_number ++;
|
||||
UINT32 size = btc_hf_client_outgoing_data_cb_to_app((UINT8 *)hf_sbc_encoder.as16PcmBuffer, HF_SBC_ENC_PCM_DATA_LEN);
|
||||
if (size != HF_SBC_ENC_PCM_DATA_LEN){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// H2: Header with synchronization word and sequence number
|
||||
p_buf[0] = 0x01;
|
||||
p_buf[1] = 0x08 | (hf_sequence_number & 0x02) << 5 | (hf_sequence_number & 0x02) << 6
|
||||
| (hf_sequence_number & 0x01) << 4 | (hf_sequence_number & 0x01) << 5;
|
||||
hf_sbc_encoder.pu8Packet = p_buf + 2;
|
||||
|
||||
SBC_Encoder(&hf_sbc_encoder);
|
||||
return BTM_ESCO_DATA_SIZE_MAX;
|
||||
|
||||
} else {
|
||||
APPL_TRACE_ERROR("%s invaild air mode: %d", __FUNCTION__, sco_p->esco.data.air_mode);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hf_client_decode_msbc_frame
|
||||
**
|
||||
** Description This function is called decode a mSBC frame
|
||||
**
|
||||
** Returns number of bytes got from application
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_hf_client_decode_msbc_frame(UINT8 **data, UINT8 *length, BOOLEAN is_bad_frame){
|
||||
OI_STATUS status;
|
||||
const OI_BYTE *zero_signal_frame_data;
|
||||
UINT8 zero_signal_frame_len = BTM_ESCO_DATA_SIZE;
|
||||
UINT32 sbc_frame_len = HF_SBC_DEC_PCM_DATA_LEN;
|
||||
|
||||
if (is_bad_frame){
|
||||
status = OI_CODEC_SBC_CHECKSUM_MISMATCH;
|
||||
} else {
|
||||
status = OI_CODEC_SBC_DecodeFrame(&hf_sbc_decoder_context, (const OI_BYTE **)data,
|
||||
(OI_UINT32 *)length,
|
||||
(OI_INT16 *)hf_sbc_decode_pcm_data,
|
||||
(OI_UINT32 *)&sbc_frame_len);
|
||||
}
|
||||
|
||||
// PLC_INCLUDED will be set to TRUE when enabling Wide Band Speech
|
||||
#if (PLC_INCLUDED == TRUE)
|
||||
switch(status){
|
||||
case OI_OK:
|
||||
bta_hf_ct_plc.first_good_frame_found = TRUE;
|
||||
sbc_plc_good_frame(&(bta_hf_ct_plc.plc_state), (int16_t *)hf_sbc_decode_pcm_data, bta_hf_ct_plc.sbc_plc_out);
|
||||
case OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA:
|
||||
case OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA:
|
||||
case OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA:
|
||||
break;
|
||||
case OI_CODEC_SBC_NO_SYNCWORD:
|
||||
case OI_CODEC_SBC_CHECKSUM_MISMATCH:
|
||||
if (!bta_hf_ct_plc.first_good_frame_found) {
|
||||
break;
|
||||
}
|
||||
zero_signal_frame_data = sbc_plc_zero_signal_frame();
|
||||
sbc_frame_len = HF_SBC_DEC_PCM_DATA_LEN;
|
||||
status = OI_CODEC_SBC_DecodeFrame(&hf_sbc_decoder_context, &zero_signal_frame_data,
|
||||
(OI_UINT32 *)&zero_signal_frame_len,
|
||||
(OI_INT16 *)hf_sbc_decode_pcm_data,
|
||||
(OI_UINT32 *)&sbc_frame_len);
|
||||
|
||||
sbc_plc_bad_frame(&(bta_hf_ct_plc.plc_state), hf_sbc_decode_pcm_data, bta_hf_ct_plc.sbc_plc_out);
|
||||
break;
|
||||
case OI_STATUS_INVALID_PARAMETERS:
|
||||
// This caused by corrupt frames.
|
||||
// The codec apparently does not recover from this.
|
||||
// Re-initialize the codec.
|
||||
APPL_TRACE_ERROR("Frame decode error: OI_STATUS_INVALID_PARAMETERS");
|
||||
|
||||
if (!OI_SUCCESS(OI_CODEC_SBC_DecoderReset(&hf_sbc_decoder_context, hf_sbc_decoder_context_data,
|
||||
HF_SBC_DEC_CONTEXT_DATA_LEN * sizeof(OI_UINT32), 1, 1, FALSE))) {
|
||||
APPL_TRACE_ERROR("OI_CODEC_SBC_DecoderReset failed with error code %d\n", status);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
APPL_TRACE_ERROR("Frame decode error: %d", status);
|
||||
break;
|
||||
}
|
||||
#endif ///(PLC_INCLUDED == TRUE)
|
||||
|
||||
if (OI_SUCCESS(status)){
|
||||
btc_hf_client_incoming_data_cb_to_app((const uint8_t *)(bta_hf_ct_plc.sbc_plc_out), sbc_frame_len);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -124,14 +394,40 @@ uint32_t bta_hf_client_sco_co_out_data(uint8_t *p_buf, uint32_t sz)
|
||||
*******************************************************************************/
|
||||
void bta_hf_client_sco_co_in_data(BT_HDR *p_buf, tBTM_SCO_DATA_FLAG status)
|
||||
{
|
||||
UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
|
||||
UINT8 pkt_size = 0;
|
||||
UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
|
||||
UINT8 pkt_size = 0;
|
||||
UINT16 handle, sco_index;
|
||||
|
||||
STREAM_SKIP_UINT16(p);
|
||||
STREAM_TO_UINT16 (handle, p);
|
||||
STREAM_TO_UINT8 (pkt_size, p);
|
||||
btc_hf_client_incoming_data_cb_to_app(p, pkt_size);
|
||||
|
||||
handle = BTMD_GET_HANDLE (handle);
|
||||
sco_index = btm_find_scb_by_handle(handle);
|
||||
tSCO_CONN *sco_p = &btm_cb.sco_cb.sco_db[sco_index];
|
||||
|
||||
if (sco_p->esco.data.air_mode == BTM_SCO_AIR_MODE_CVSD) {
|
||||
// CVSD
|
||||
if(status != BTM_SCO_DATA_CORRECT){
|
||||
APPL_TRACE_DEBUG("%s: not a correct frame(%d).", __func__, status);
|
||||
}
|
||||
btc_hf_client_incoming_data_cb_to_app(p, pkt_size);
|
||||
} else if (sco_p->esco.data.air_mode == BTM_SCO_AIR_MODE_TRANSPNT) {
|
||||
// mSBC
|
||||
BOOLEAN is_bad_frame = false;
|
||||
UINT8 msbc_frame_size = BTM_ESCO_DATA_SIZE;
|
||||
if (pkt_size < msbc_frame_size) {
|
||||
is_bad_frame = true;
|
||||
}
|
||||
if (status != BTM_SCO_DATA_CORRECT) {
|
||||
is_bad_frame = true;
|
||||
}
|
||||
UINT8 *data = p;
|
||||
bta_hf_client_decode_msbc_frame(&data, &pkt_size, is_bad_frame);
|
||||
} else {
|
||||
APPL_TRACE_ERROR("%s invaild air mode: %d", __FUNCTION__, sco_p->esco.data.air_mode);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE) */
|
||||
|
||||
#endif /* #if (BTA_HF_INCLUDED == TRUE) */
|
||||
#endif /* #if (BTA_HF_INCLUDED == TRUE) */
|
@ -195,8 +195,9 @@ bt_status_t btc_hf_client_init(void)
|
||||
*******************************************************************************/
|
||||
static bt_status_t connect_int( bt_bdaddr_t *bd_addr, uint16_t uuid )
|
||||
{
|
||||
if (is_connected(bd_addr))
|
||||
if (is_connected(bd_addr)) {
|
||||
return BT_STATUS_BUSY;
|
||||
}
|
||||
|
||||
btc_hf_client_cb.state = ESP_HF_CLIENT_CONNECTION_STATE_CONNECTING;
|
||||
bdcpy(btc_hf_client_cb.connected_bda.address, bd_addr->address);
|
||||
@ -713,14 +714,14 @@ static void process_ind_evt(tBTA_HF_CLIENT_IND *ind)
|
||||
{
|
||||
esp_hf_client_cb_param_t param;
|
||||
memset(¶m, 0, sizeof(esp_hf_client_cb_param_t));
|
||||
|
||||
|
||||
switch (ind->type)
|
||||
{
|
||||
case BTA_HF_CLIENT_IND_CALL:
|
||||
param.call.status = ind->value;
|
||||
btc_hf_client_cb_to_app(ESP_HF_CLIENT_CIND_CALL_EVT, ¶m);
|
||||
break;
|
||||
|
||||
|
||||
case BTA_HF_CLIENT_IND_CALLSETUP:
|
||||
param.call_setup.status = ind->value;
|
||||
btc_hf_client_cb_to_app(ESP_HF_CLIENT_CIND_CALL_SETUP_EVT, ¶m);
|
||||
@ -787,6 +788,7 @@ void btc_hf_client_cb_handler(btc_msg_t *msg)
|
||||
{
|
||||
BTC_TRACE_WARNING("%s: HF CLient open failed, but another device connected. status=%d state=%d connected device=%s",
|
||||
__FUNCTION__, p_data->open.status, btc_hf_client_cb.state, bdaddr_to_string(&btc_hf_client_cb.connected_bda, bdstr, sizeof(bdstr)));
|
||||
UNUSED(bdstr);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -795,18 +797,20 @@ void btc_hf_client_cb_handler(btc_msg_t *msg)
|
||||
param.conn_stat.state = btc_hf_client_cb.state;
|
||||
param.conn_stat.peer_feat = 0;
|
||||
param.conn_stat.chld_feat = 0;
|
||||
|
||||
|
||||
memcpy(param.conn_stat.remote_bda, &btc_hf_client_cb.connected_bda,
|
||||
sizeof(esp_bd_addr_t));
|
||||
|
||||
btc_hf_client_cb_to_app(ESP_HF_CLIENT_CONNECTION_STATE_EVT, ¶m);
|
||||
} while (0);
|
||||
|
||||
if (btc_hf_client_cb.state == ESP_HF_CLIENT_CONNECTION_STATE_DISCONNECTED)
|
||||
bdsetany(btc_hf_client_cb.connected_bda.address);
|
||||
|
||||
if (p_data->open.status != BTA_HF_CLIENT_SUCCESS)
|
||||
if (btc_hf_client_cb.state == ESP_HF_CLIENT_CONNECTION_STATE_DISCONNECTED) {
|
||||
bdsetany(btc_hf_client_cb.connected_bda.address);
|
||||
}
|
||||
|
||||
if (p_data->open.status != BTA_HF_CLIENT_SUCCESS) {
|
||||
btc_queue_advance();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@ -820,13 +824,13 @@ void btc_hf_client_cb_handler(btc_msg_t *msg)
|
||||
param.conn_stat.state = btc_hf_client_cb.state;
|
||||
param.conn_stat.peer_feat = btc_hf_client_cb.peer_feat;
|
||||
param.conn_stat.chld_feat = btc_hf_client_cb.chld_feat;
|
||||
|
||||
|
||||
memcpy(param.conn_stat.remote_bda, &btc_hf_client_cb.connected_bda,
|
||||
sizeof(esp_bd_addr_t));
|
||||
|
||||
btc_hf_client_cb_to_app(ESP_HF_CLIENT_CONNECTION_STATE_EVT, ¶m);
|
||||
} while (0);
|
||||
|
||||
|
||||
/* Inform the application about in-band ringtone */
|
||||
if (btc_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_INBAND)
|
||||
{
|
||||
@ -839,7 +843,7 @@ void btc_hf_client_cb_handler(btc_msg_t *msg)
|
||||
|
||||
btc_queue_advance();
|
||||
break;
|
||||
|
||||
|
||||
case BTA_HF_CLIENT_CLOSE_EVT:
|
||||
btc_hf_client_cb.state = ESP_HF_CLIENT_CONNECTION_STATE_DISCONNECTED;
|
||||
do {
|
||||
@ -847,7 +851,7 @@ void btc_hf_client_cb_handler(btc_msg_t *msg)
|
||||
param.conn_stat.state = ESP_HF_CLIENT_CONNECTION_STATE_DISCONNECTED;
|
||||
param.conn_stat.peer_feat = 0;
|
||||
param.conn_stat.chld_feat = 0;
|
||||
|
||||
|
||||
memcpy(param.conn_stat.remote_bda, &btc_hf_client_cb.connected_bda,
|
||||
sizeof(esp_bd_addr_t));
|
||||
|
||||
@ -980,7 +984,7 @@ void btc_hf_client_cb_handler(btc_msg_t *msg)
|
||||
memset(¶m, 0, sizeof(esp_hf_client_cb_param_t));
|
||||
param.audio_stat.state = ESP_HF_CLIENT_AUDIO_STATE_CONNECTED;
|
||||
memcpy(param.audio_stat.remote_bda, &btc_hf_client_cb.connected_bda,
|
||||
sizeof(esp_bd_addr_t));
|
||||
sizeof(esp_bd_addr_t));
|
||||
btc_hf_client_cb_to_app(ESP_HF_CLIENT_AUDIO_STATE_EVT, ¶m);
|
||||
} while (0);
|
||||
break;
|
||||
@ -989,7 +993,7 @@ void btc_hf_client_cb_handler(btc_msg_t *msg)
|
||||
memset(¶m, 0, sizeof(esp_hf_client_cb_param_t));
|
||||
param.audio_stat.state = ESP_HF_CLIENT_AUDIO_STATE_CONNECTED_MSBC;
|
||||
memcpy(param.audio_stat.remote_bda, &btc_hf_client_cb.connected_bda,
|
||||
sizeof(esp_bd_addr_t));
|
||||
sizeof(esp_bd_addr_t));
|
||||
btc_hf_client_cb_to_app(ESP_HF_CLIENT_AUDIO_STATE_EVT, ¶m);
|
||||
} while (0);
|
||||
break;
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "common/bt_defs.h"
|
||||
#include "stack/bt_types.h"
|
||||
#include "bta/bta_av_api.h"
|
||||
#include "btc/btc_task.h"
|
||||
#include "esp_avrc_api.h"
|
||||
|
||||
#if (BTC_AV_INCLUDED == TRUE)
|
||||
#ifndef BTC_AVRC_TGT_INCLUDED
|
||||
@ -29,13 +31,14 @@
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
BTC_AVRC_CTRL_API_INIT_EVT = 0,
|
||||
BTC_AVRC_CTRL_API_DEINIT_EVT,
|
||||
BTC_AVRC_CT_API_INIT_EVT = 0,
|
||||
BTC_AVRC_CT_API_DEINIT_EVT,
|
||||
BTC_AVRC_CTRL_API_SND_PTCMD_EVT,
|
||||
BTC_AVRC_STATUS_API_SND_META_EVT,
|
||||
BTC_AVRC_STATUS_API_SND_PLAY_STATUS_EVT,
|
||||
BTC_AVRC_STATUS_API_SND_GET_RN_CAPS_EVT,
|
||||
BTC_AVRC_NOTIFY_API_SND_REG_NOTIFY_EVT,
|
||||
BTC_AVRC_CTRL_API_SET_PLAYER_SETTING_EVT
|
||||
BTC_AVRC_CTRL_API_SND_SET_PLAYER_SETTING_EVT
|
||||
} btc_avrc_act_t;
|
||||
|
||||
typedef struct {
|
||||
@ -61,18 +64,40 @@ typedef struct {
|
||||
uint8_t value_id;
|
||||
} ps_cmd_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t tl;
|
||||
} get_caps_cmd_t;
|
||||
|
||||
/* btc_avrc_args_t */
|
||||
typedef union {
|
||||
pt_cmd_t pt_cmd;
|
||||
md_cmd_t md_cmd;
|
||||
rn_cmd_t rn_cmd;
|
||||
ps_cmd_t ps_cmd;
|
||||
get_caps_cmd_t get_caps_cmd;
|
||||
} btc_avrc_args_t;
|
||||
|
||||
/** BT-RC Controller callback structure. */
|
||||
typedef void (* btrc_passthrough_rsp_callback) (int id, int key_state);
|
||||
/* btc_avrc_tg_act_t */
|
||||
typedef enum {
|
||||
BTC_AVRC_TG_API_INIT_EVT = 0,
|
||||
BTC_AVRC_TG_API_DEINIT_EVT,
|
||||
BTC_AVRC_TG_API_SET_RN_SUPPORTED_EVT,
|
||||
BTC_AVRC_TG_API_SET_PSTH_SUPPORTED_CMD_EVT,
|
||||
BTC_AVRC_TG_API_SEND_RN_RSP_EVT,
|
||||
} btc_avrc_tg_act_t;
|
||||
|
||||
typedef void (* btrc_connection_state_callback) (bool state, bt_bdaddr_t *bd_addr);
|
||||
typedef struct {
|
||||
esp_avrc_rn_event_ids_t event_id;
|
||||
esp_avrc_rn_rsp_t rsp;
|
||||
esp_avrc_rn_param_t param;
|
||||
} rn_rsp_t;
|
||||
|
||||
/* btc_avrc_tg_args_t */
|
||||
typedef union {
|
||||
rn_rsp_t rn_rsp; /* BTC_AVRC_TG_API_SEND_RN_RSP_EVT */
|
||||
uint16_t set_rn_evt; /* BTC_AVRC_TG_API_SET_RN_SUPPORTED_EVT */
|
||||
uint16_t *set_psth_cmd; /* BTC_AVRC_TG_API_SET_PSTH_SUPPORTED_CMD_EVT */
|
||||
} btc_avrc_tg_args_t;
|
||||
|
||||
void btc_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data);
|
||||
|
||||
@ -81,7 +106,24 @@ BOOLEAN btc_rc_get_connected_peer(BD_ADDR peer_addr);
|
||||
/*******************************************************************************
|
||||
** BTC AVRC API
|
||||
********************************************************************************/
|
||||
void btc_avrc_call_handler(btc_msg_t *msg);
|
||||
void btc_avrc_ct_call_handler(btc_msg_t *msg);
|
||||
void btc_avrc_tg_call_handler(btc_msg_t *msg);
|
||||
void btc_avrc_tg_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
|
||||
|
||||
bool btc_avrc_tg_init_p(void);
|
||||
bool btc_avrc_ct_init_p(void);
|
||||
bool btc_avrc_tg_connected_p(void);
|
||||
bool btc_avrc_ct_connected_p(void);
|
||||
|
||||
const uint16_t *btc_avrc_tg_get_supported_command(void);
|
||||
const uint16_t *btc_avrc_tg_get_allowed_command(void);
|
||||
bool btc_avrc_tg_check_supported_command(const uint16_t *cmd_set);
|
||||
|
||||
uint16_t btc_avrc_tg_get_rn_allowed_evt(void);
|
||||
uint16_t btc_avrc_tg_get_rn_supported_evt(void);
|
||||
bool btc_avrc_tg_check_rn_supported_evt(uint16_t evt_set);
|
||||
bool btc_avrc_tg_rn_evt_supported(uint8_t event_id);
|
||||
bool btc_avrc_ct_rn_evt_supported(uint8_t event_id);
|
||||
|
||||
#endif ///BTC_AV_INCLUDED == TRUE
|
||||
|
||||
|
@ -315,6 +315,7 @@ static void btc_spp_init(btc_spp_args_t *arg)
|
||||
{
|
||||
if (osi_mutex_new(&spp_local_param.spp_slot_mutex) != 0) {
|
||||
BTC_TRACE_ERROR("%s osi_mutex_new failed\n", __func__);
|
||||
return;
|
||||
}
|
||||
spp_local_param.spp_mode = arg->init.mode;
|
||||
spp_local_param.spp_slot_id = 0;
|
||||
@ -323,6 +324,10 @@ static void btc_spp_init(btc_spp_args_t *arg)
|
||||
|
||||
static void btc_spp_uninit(void)
|
||||
{
|
||||
if (!spp_local_param.spp_slot_mutex) {
|
||||
BTC_TRACE_ERROR("%s SPP have not been init\n", __func__);
|
||||
return;
|
||||
}
|
||||
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
|
||||
for (size_t i = 1; i <= BTA_JV_MAX_RFC_SR_SESSION; i++) {
|
||||
if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->connected) {
|
||||
|
@ -77,6 +77,7 @@
|
||||
#if CONFIG_HFP_CLIENT_ENABLE
|
||||
#define BTC_HF_CLIENT_INCLUDED TRUE
|
||||
#define BTA_HF_INCLUDED TRUE
|
||||
#define PLC_INCLUDED TRUE
|
||||
#ifndef RFCOMM_INCLUDED
|
||||
#define RFCOMM_INCLUDED TRUE
|
||||
#endif
|
||||
@ -86,6 +87,12 @@
|
||||
#ifndef BTM_MAX_SCO_LINKS
|
||||
#define BTM_MAX_SCO_LINKS (1)
|
||||
#endif
|
||||
#ifndef SBC_DEC_INCLUDED
|
||||
#define SBC_DEC_INCLUDED TRUE
|
||||
#endif
|
||||
#ifndef SBC_ENC_INCLUDED
|
||||
#define SBC_ENC_INCLUDED TRUE
|
||||
#endif
|
||||
#endif /* CONFIG_HFP_HF_ENABLE */
|
||||
|
||||
#if CONFIG_BT_SSP_ENABLED
|
||||
@ -98,6 +105,10 @@
|
||||
#define CLASSIC_BT_INCLUDED FALSE
|
||||
#endif /* CLASSIC_BT_INCLUDED */
|
||||
|
||||
#ifndef CLASSIC_BT_GATT_INCLUDED
|
||||
#define CLASSIC_BT_GATT_INCLUDED FALSE
|
||||
#endif /* CLASSIC_BT_GATT_INCLUDED */
|
||||
|
||||
#ifndef CONFIG_GATTC_CACHE_NVS_FLASH
|
||||
#define CONFIG_GATTC_CACHE_NVS_FLASH FALSE
|
||||
#endif /* CONFIG_GATTC_CACHE_NVS_FLASH */
|
||||
@ -143,11 +154,35 @@
|
||||
#define SMP_SLAVE_CON_PARAMS_UPD_ENABLE FALSE
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED
|
||||
#define BLE_ADV_REPORT_FLOW_CONTROL FALSE
|
||||
#else
|
||||
#define BLE_ADV_REPORT_FLOW_CONTROL CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED
|
||||
#endif /* CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED */
|
||||
|
||||
#ifndef CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_NUM
|
||||
#define BLE_ADV_REPORT_FLOW_CONTROL_NUM 100
|
||||
#else
|
||||
#define BLE_ADV_REPORT_FLOW_CONTROL_NUM CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_NUM
|
||||
#endif /* CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_NUM */
|
||||
|
||||
#ifndef CONFIG_BLE_ADV_REPORT_DISCARD_THRSHOLD
|
||||
#define BLE_ADV_REPORT_DISCARD_THRSHOLD 20
|
||||
#else
|
||||
#define BLE_ADV_REPORT_DISCARD_THRSHOLD CONFIG_BLE_ADV_REPORT_DISCARD_THRSHOLD
|
||||
#endif /* CONFIG_BLE_ADV_REPORT_DISCARD_THRSHOLD */
|
||||
|
||||
#if (CONFIG_BT_ACL_CONNECTIONS)
|
||||
#define MAX_ACL_CONNECTIONS CONFIG_BT_ACL_CONNECTIONS
|
||||
#define GATT_MAX_PHY_CHANNEL CONFIG_BT_ACL_CONNECTIONS
|
||||
#endif /* CONFIG_BT_ACL_CONNECTIONS */
|
||||
|
||||
#if(CONFIG_BLE_ESTABLISH_LINK_CONNECTION_TIMEOUT)
|
||||
#define BLE_ESTABLISH_LINK_CONNECTION_TIMEOUT CONFIG_BLE_ESTABLISH_LINK_CONNECTION_TIMEOUT
|
||||
#else
|
||||
#define BLE_ESTABLISH_LINK_CONNECTION_TIMEOUT 30
|
||||
#endif
|
||||
|
||||
//------------------Added from bdroid_buildcfg.h---------------------
|
||||
#ifndef L2CAP_EXTFEA_SUPPORTED_MASK
|
||||
#define L2CAP_EXTFEA_SUPPORTED_MASK (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE | L2CAP_EXTFEA_NO_CRC | L2CAP_EXTFEA_FIXED_CHNLS)
|
||||
@ -585,6 +620,16 @@
|
||||
#define BTM_SCO_DATA_SIZE_MAX 120 //240
|
||||
#endif
|
||||
|
||||
/* max TX eSCO data packet size */
|
||||
#ifndef BTM_ESCO_DATA_SIZE_MAX
|
||||
#define BTM_ESCO_DATA_SIZE_MAX 60
|
||||
#endif
|
||||
|
||||
/* TX eSCO data packet size */
|
||||
#ifndef BTM_ESCO_DATA_SIZE
|
||||
#define BTM_ESCO_DATA_SIZE 57
|
||||
#endif
|
||||
|
||||
/* The size in bytes of the BTM inquiry database. 5 As Default */
|
||||
#ifndef BTM_INQ_DB_SIZE
|
||||
#define BTM_INQ_DB_SIZE 5
|
||||
@ -887,7 +932,7 @@
|
||||
|
||||
/* This is set to enable L2CAP to take the ACL link out of park mode when ACL data is to be sent. */
|
||||
#ifndef L2CAP_WAKE_PARKED_LINK
|
||||
#define L2CAP_WAKE_PARKED_LINK TRUE
|
||||
#define L2CAP_WAKE_PARKED_LINK FALSE
|
||||
#endif
|
||||
|
||||
/* Whether link wants to be the master or the slave. */
|
||||
|
@ -31,6 +31,7 @@ typedef struct {
|
||||
UINT8 ble_init_key;
|
||||
UINT8 ble_resp_key;
|
||||
UINT8 ble_max_key_size;
|
||||
UINT8 ble_min_key_size;
|
||||
UINT8 ble_accept_auth_enable;
|
||||
UINT8 oob_support;
|
||||
#endif
|
||||
@ -48,4 +49,4 @@ typedef struct {
|
||||
#endif
|
||||
} tBTE_BT_APPL_CFG;
|
||||
|
||||
extern tBTE_BT_APPL_CFG bte_bt_appl_cfg;
|
||||
extern tBTE_BT_APPL_CFG bte_bt_appl_cfg;
|
||||
|
@ -100,7 +100,11 @@ static void start_up(void)
|
||||
response = AWAIT_COMMAND(packet_factory->make_set_c2h_flow_control(HCI_HOST_FLOW_CTRL_ACL_ON));
|
||||
packet_parser->parse_generic_command_complete(response);
|
||||
#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
|
||||
|
||||
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
|
||||
// Enable adv flow control
|
||||
response = AWAIT_COMMAND(packet_factory->make_set_adv_report_flow_control(HCI_HOST_FLOW_CTRL_ADV_REPORT_ON, (uint16_t)BLE_ADV_REPORT_FLOW_CONTROL_NUM, (uint16_t)BLE_ADV_REPORT_DISCARD_THRSHOLD));
|
||||
packet_parser->parse_generic_command_complete(response);
|
||||
#endif
|
||||
// Tell the controller about our buffer sizes and buffer counts next
|
||||
// TODO(zachoverflow): factor this out. eww l2cap contamination. And why just a hardcoded 10?
|
||||
response = AWAIT_COMMAND(
|
||||
|
@ -27,6 +27,7 @@
|
||||
#define CASE_RETURN_STR(const) case const: return #const;
|
||||
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
#if (!CONFIG_BT_STACK_NO_LOG)
|
||||
static const char *interop_feature_string(const interop_feature_t feature)
|
||||
{
|
||||
switch (feature) {
|
||||
@ -36,7 +37,7 @@ static const char *interop_feature_string(const interop_feature_t feature)
|
||||
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
#endif // (!CONFIG_BT_STACK_NO_LOG)
|
||||
// Interface functions
|
||||
bool interop_match(const interop_feature_t feature, const bt_bdaddr_t *addr)
|
||||
{
|
||||
@ -47,7 +48,9 @@ bool interop_match(const interop_feature_t feature, const bt_bdaddr_t *addr)
|
||||
for (size_t i = 0; i != db_size; ++i) {
|
||||
if (feature == interop_database[i].feature &&
|
||||
memcmp(addr, &interop_database[i].addr, interop_database[i].len) == 0) {
|
||||
#if (!CONFIG_BT_STACK_NO_LOG)
|
||||
char bdstr[20] = {0};
|
||||
#endif
|
||||
LOG_WARN("%s() Device %s is a match for interop workaround %s", __func__,
|
||||
bdaddr_to_string(addr, bdstr, sizeof(bdstr)), interop_feature_string(feature));
|
||||
return true;
|
||||
|
@ -76,6 +76,7 @@ Declarations of codec functions, data types, and macros.
|
||||
|
||||
#define OI_SBC_SYNCWORD 0x9c
|
||||
#define OI_SBC_ENHANCED_SYNCWORD 0x9d
|
||||
#define OI_mSBC_SYNCWORD 0xad
|
||||
|
||||
/**@name Sampling frequencies */
|
||||
/**@{*/
|
||||
|
@ -81,9 +81,6 @@ INLINE OI_STATUS internal_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
|
||||
return OI_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Read the SBC header up to but not including the joint stereo mask. The syncword has already been
|
||||
* examined, and the enhanced mode flag set, by FindSyncword.
|
||||
@ -94,7 +91,33 @@ INLINE void OI_SBC_ReadHeader(OI_CODEC_SBC_COMMON_CONTEXT *common, const OI_BYTE
|
||||
OI_UINT8 d1;
|
||||
|
||||
|
||||
OI_ASSERT(data[0] == OI_SBC_SYNCWORD || data[0] == OI_SBC_ENHANCED_SYNCWORD);
|
||||
OI_ASSERT(data[0] == OI_SBC_SYNCWORD || data[0] == OI_SBC_ENHANCED_SYNCWORD
|
||||
|| data[0] == OI_mSBC_SYNCWORD);
|
||||
|
||||
/**
|
||||
* For mSBC, just set those parameters
|
||||
*/
|
||||
if (data[0] == OI_mSBC_SYNCWORD){
|
||||
frame->freqIndex = 0;
|
||||
frame->frequency = 16000;
|
||||
|
||||
frame->blocks = 4;
|
||||
frame->nrof_blocks = 15;
|
||||
|
||||
frame->mode = 0;
|
||||
frame->nrof_channels = 1;
|
||||
|
||||
frame->alloc = SBC_LOUDNESS;
|
||||
|
||||
frame->subbands = 1;
|
||||
frame->nrof_subbands = 8;
|
||||
|
||||
frame->cachedInfo = 0;
|
||||
|
||||
frame->bitpool = 26;
|
||||
frame->crc = data[3];
|
||||
return;
|
||||
}
|
||||
|
||||
/* Avoid filling out all these strucutures if we already remember the values
|
||||
* from last time. Just in case we get a stream corresponding to data[1] ==
|
||||
|
@ -79,7 +79,9 @@ PRIVATE OI_STATUS FindSyncword(OI_CODEC_SBC_DECODER_CONTEXT *context,
|
||||
return OI_CODEC_SBC_NO_SYNCWORD;
|
||||
}
|
||||
#else // SBC_ENHANCED
|
||||
while (*frameBytes && (**frameData != OI_SBC_SYNCWORD)) {
|
||||
|
||||
while (*frameBytes && (**frameData != OI_SBC_SYNCWORD)
|
||||
&& (**frameData != OI_mSBC_SYNCWORD)) {
|
||||
(*frameBytes)--;
|
||||
(*frameData)++;
|
||||
}
|
||||
|
@ -67,6 +67,12 @@
|
||||
|
||||
#define SBC_NULL 0
|
||||
|
||||
#define SBC_MODE_STD 0
|
||||
#define SBC_MODE_MSBC 1
|
||||
|
||||
#define SBC_SYNC_WORD_STD (0x9C)
|
||||
#define SBC_SYNC_WORD_MSBC (0xAD)
|
||||
|
||||
#ifndef SBC_MAX_NUM_FRAME
|
||||
#define SBC_MAX_NUM_FRAME 1
|
||||
#endif
|
||||
@ -161,6 +167,7 @@ typedef struct SBC_ENC_PARAMS_TAG {
|
||||
SINT16 s16BitPool; /* 16*numOfSb for mono & dual;
|
||||
32*numOfSb for stereo & joint stereo */
|
||||
UINT16 u16BitRate;
|
||||
UINT8 sbc_mode; /* SBC_MODE_STD or SBC_MODE_MSBC */
|
||||
UINT8 u8NumPacketToEncode; /* number of sbc frame to encode. Default is 1 */
|
||||
#if (SBC_JOINT_STE_INCLUDED == TRUE)
|
||||
SINT16 as16Join[SBC_MAX_NUM_OF_SUBBANDS]; /*1 if JS, 0 otherwise*/
|
||||
|
@ -145,9 +145,10 @@ void sbc_enc_bit_alloc_mono(SBC_ENC_PARAMS *pstrCodecParams)
|
||||
for (s32Sb = 0; s32Sb < s32NumOfSubBands; s32Sb++) {
|
||||
if (*(ps16GenBufPtr) < s32BitSlice + 2) {
|
||||
*(ps16GenArrPtr) = 0;
|
||||
} else
|
||||
} else {
|
||||
*(ps16GenArrPtr) = ((*(ps16GenBufPtr) - s32BitSlice) < 16) ?
|
||||
(SINT16)(*(ps16GenBufPtr) - s32BitSlice) : 16;
|
||||
}
|
||||
|
||||
ps16GenBufPtr++;
|
||||
ps16GenArrPtr++;
|
||||
|
@ -132,9 +132,10 @@ void sbc_enc_bit_alloc_ste(SBC_ENC_PARAMS *pstrCodecParams)
|
||||
for (s32Sb = 0; s32Sb < s32NumOfSubBands; s32Sb++) {
|
||||
if (*ps16GenBufPtr < s32BitSlice + 2) {
|
||||
*ps16GenArrPtr = 0;
|
||||
} else
|
||||
} else {
|
||||
*ps16GenArrPtr = ((*(ps16GenBufPtr) - s32BitSlice) < 16) ?
|
||||
(SINT16)(*(ps16GenBufPtr) - s32BitSlice) : 16;
|
||||
}
|
||||
ps16GenBufPtr++;
|
||||
ps16GenArrPtr++;
|
||||
}
|
||||
|
@ -31,84 +31,6 @@
|
||||
|
||||
SINT16 EncMaxShiftCounter;
|
||||
|
||||
/*************************************************************************************************
|
||||
* SBC encoder scramble code
|
||||
* Purpose: to tie the SBC code with BTE/mobile stack code,
|
||||
* especially for the case when the SBC is ported into a third-party Multimedia chip
|
||||
*
|
||||
* Algorithm:
|
||||
* init process: all counters reset to 0,
|
||||
* calculate base_index: (6 + s16NumOfChannels*s16NumOfSubBands/2)
|
||||
* scramble side: the init process happens every time SBC_Encoder_Init() is called.
|
||||
* descramble side: it would be nice to know if he "init" process has happened.
|
||||
* alter the SBC SYNC word 0x9C (1001 1100) to 0x8C (1000 1100).
|
||||
*
|
||||
* scramble process:
|
||||
* The CRC byte:
|
||||
* Every SBC frame has a frame header.
|
||||
* The 1st byte is the sync word and the following 2 bytes are about the stream format.
|
||||
* They are supposed to be "constant" within a "song"
|
||||
* The 4th byte is the CRC byte. The CRC byte is bound to be random.
|
||||
* Derive 2 items from the CRC byte; one is the "use" bit, the other is the "index".
|
||||
*
|
||||
* SBC keeps 2 sets of "use" & "index"; derived the current and the previous frame.
|
||||
*
|
||||
* The "use" bit is any bit in SBC_PRTC_USE_MASK is set.
|
||||
* If set, SBC uses the "index" from the current frame.
|
||||
* If not set, SBC uses the "index" from the previous frame or 0.
|
||||
*
|
||||
* index = (CRC & 0x3) + ((CRC & 0x30) >> 2) // 8 is the max index
|
||||
*
|
||||
* if(index > 0)
|
||||
* {
|
||||
* p = &u8frame[base_index];
|
||||
* if((index&1)&&(u16PacketLength > (base_index+index*2)))
|
||||
* {
|
||||
* // odd index: swap 2 bytes
|
||||
* tmp = p[index];
|
||||
* p[index] = p[index*2];
|
||||
* p[index*2] = tmp;
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* // even index: shift by 3
|
||||
* tmp = (p[index] >> 5) + (p[index] << 3);
|
||||
* p[index] = tmp;
|
||||
* }
|
||||
* }
|
||||
* //else index is 0. The frame stays unaltered
|
||||
*
|
||||
*/
|
||||
|
||||
#define SBC_PRTC_CRC_IDX 3
|
||||
#define SBC_PRTC_USE_MASK 0x64
|
||||
#define SBC_PRTC_SYNC_MASK 0x10
|
||||
#define SBC_PRTC_CIDX 0
|
||||
#define SBC_PRTC_LIDX 1
|
||||
typedef struct {
|
||||
UINT8 use;
|
||||
UINT8 idx;
|
||||
} tSBC_FR_CB;
|
||||
|
||||
typedef struct {
|
||||
tSBC_FR_CB fr[2];
|
||||
UINT8 init;
|
||||
UINT8 index;
|
||||
UINT8 base;
|
||||
} tSBC_PRTC_CB;
|
||||
tSBC_PRTC_CB sbc_prtc_cb;
|
||||
|
||||
#define SBC_PRTC_IDX(sc) (((sc) & 0x3) + (((sc) & 0x30) >> 2))
|
||||
#define SBC_PRTC_CHK_INIT(ar) {if(sbc_prtc_cb.init == 0){sbc_prtc_cb.init=1; ar[0] &= ~SBC_PRTC_SYNC_MASK;}}
|
||||
#define SBC_PRTC_C2L() {p_last=&sbc_prtc_cb.fr[SBC_PRTC_LIDX]; p_cur=&sbc_prtc_cb.fr[SBC_PRTC_CIDX]; \
|
||||
p_last->idx = p_cur->idx; p_last->use = p_cur->use;}
|
||||
#define SBC_PRTC_GETC(ar) {p_cur->use = ar[SBC_PRTC_CRC_IDX] & SBC_PRTC_USE_MASK; \
|
||||
p_cur->idx = SBC_PRTC_IDX(ar[SBC_PRTC_CRC_IDX]);}
|
||||
#define SBC_PRTC_CHK_CRC(ar) {SBC_PRTC_C2L();SBC_PRTC_GETC(ar);sbc_prtc_cb.index = (p_cur->use)?SBC_PRTC_CIDX:SBC_PRTC_LIDX;}
|
||||
#define SBC_PRTC_SCRMB(ar) {idx = sbc_prtc_cb.fr[sbc_prtc_cb.index].idx; \
|
||||
if(idx > 0){if((idx&1)&&(pstrEncParams->u16PacketLength > (sbc_prtc_cb.base+(idx<<1)))) {tmp2=idx<<1; tmp=ar[idx];ar[idx]=ar[tmp2];ar[tmp2]=tmp;} \
|
||||
else{tmp2=ar[idx]; tmp=(tmp2>>5)+(tmp2<<3);ar[idx]=(UINT8)tmp;}}}
|
||||
|
||||
#if (SBC_JOINT_STE_INCLUDED == TRUE)
|
||||
SINT32 s32LRDiff[SBC_MAX_NUM_OF_BLOCKS] = {0};
|
||||
SINT32 s32LRSum[SBC_MAX_NUM_OF_BLOCKS] = {0};
|
||||
@ -130,9 +52,6 @@ void SBC_Encoder(SBC_ENC_PARAMS *pstrEncParams)
|
||||
UINT32 u32CountSum, u32CountDiff;
|
||||
SINT32 *pSum, *pDiff;
|
||||
#endif
|
||||
UINT8 *pu8;
|
||||
tSBC_FR_CB *p_cur, *p_last;
|
||||
UINT32 idx, tmp, tmp2;
|
||||
register SINT32 s32NumOfSubBands = pstrEncParams->s16NumOfSubBands;
|
||||
|
||||
pstrEncParams->pu8NextPacket = pstrEncParams->pu8Packet;
|
||||
@ -263,22 +182,8 @@ void SBC_Encoder(SBC_ENC_PARAMS *pstrEncParams)
|
||||
sbc_enc_bit_alloc_mono(pstrEncParams);
|
||||
}
|
||||
|
||||
/* save the beginning of the frame. pu8NextPacket is modified in EncPacking() */
|
||||
pu8 = pstrEncParams->pu8NextPacket;
|
||||
/* Quantize the encoded audio */
|
||||
EncPacking(pstrEncParams);
|
||||
|
||||
/* scramble the code */
|
||||
SBC_PRTC_CHK_INIT(pu8);
|
||||
SBC_PRTC_CHK_CRC(pu8);
|
||||
#if 0
|
||||
if (pstrEncParams->u16PacketLength > ((sbc_prtc_cb.fr[sbc_prtc_cb.index].idx * 2) + sbc_prtc_cb.base)) {
|
||||
printf("len: %d, idx: %d\n", pstrEncParams->u16PacketLength, sbc_prtc_cb.fr[sbc_prtc_cb.index].idx);
|
||||
} else {
|
||||
printf("len: %d, idx: %d!!!!\n", pstrEncParams->u16PacketLength, sbc_prtc_cb.fr[sbc_prtc_cb.index].idx);
|
||||
}
|
||||
#endif
|
||||
SBC_PRTC_SCRMB((&pu8[sbc_prtc_cb.base]));
|
||||
} while (--(pstrEncParams->u8NumPacketToEncode));
|
||||
|
||||
pstrEncParams->u8NumPacketToEncode = 1; /* default is one for retrocompatibility purpose */
|
||||
@ -300,83 +205,111 @@ void SBC_Encoder_Init(SBC_ENC_PARAMS *pstrEncParams)
|
||||
|
||||
pstrEncParams->u8NumPacketToEncode = 1; /* default is one for retrocompatibility purpose */
|
||||
|
||||
/* Required number of channels */
|
||||
if (pstrEncParams->s16ChannelMode == SBC_MONO) {
|
||||
pstrEncParams->s16NumOfChannels = 1;
|
||||
} else {
|
||||
pstrEncParams->s16NumOfChannels = 2;
|
||||
}
|
||||
|
||||
/* Bit pool calculation */
|
||||
if (pstrEncParams->s16SamplingFreq == SBC_sf16000) {
|
||||
s16SamplingFreq = 16000;
|
||||
} else if (pstrEncParams->s16SamplingFreq == SBC_sf32000) {
|
||||
s16SamplingFreq = 32000;
|
||||
} else if (pstrEncParams->s16SamplingFreq == SBC_sf44100) {
|
||||
s16SamplingFreq = 44100;
|
||||
} else {
|
||||
s16SamplingFreq = 48000;
|
||||
}
|
||||
|
||||
if ( (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO)
|
||||
|| (pstrEncParams->s16ChannelMode == SBC_STEREO) ) {
|
||||
s16Bitpool = (SINT16)( (pstrEncParams->u16BitRate *
|
||||
pstrEncParams->s16NumOfSubBands * 1000 / s16SamplingFreq)
|
||||
- ( (32 + (4 * pstrEncParams->s16NumOfSubBands *
|
||||
pstrEncParams->s16NumOfChannels)
|
||||
+ ( (pstrEncParams->s16ChannelMode - 2) *
|
||||
pstrEncParams->s16NumOfSubBands ) )
|
||||
/ pstrEncParams->s16NumOfBlocks) );
|
||||
|
||||
s16FrameLen = 4 + (4 * pstrEncParams->s16NumOfSubBands *
|
||||
pstrEncParams->s16NumOfChannels) / 8
|
||||
+ ( ((pstrEncParams->s16ChannelMode - 2) *
|
||||
pstrEncParams->s16NumOfSubBands)
|
||||
+ (pstrEncParams->s16NumOfBlocks * s16Bitpool) ) / 8;
|
||||
|
||||
s16BitRate = (8 * s16FrameLen * s16SamplingFreq)
|
||||
/ (pstrEncParams->s16NumOfSubBands *
|
||||
pstrEncParams->s16NumOfBlocks * 1000);
|
||||
|
||||
if (s16BitRate > pstrEncParams->u16BitRate) {
|
||||
s16Bitpool--;
|
||||
}
|
||||
|
||||
if (pstrEncParams->s16NumOfSubBands == 8) {
|
||||
pstrEncParams->s16BitPool = (s16Bitpool > 255) ? 255 : s16Bitpool;
|
||||
if (pstrEncParams->sbc_mode != SBC_MODE_MSBC) {
|
||||
/* Required number of channels */
|
||||
if (pstrEncParams->s16ChannelMode == SBC_MONO) {
|
||||
pstrEncParams->s16NumOfChannels = 1;
|
||||
} else {
|
||||
pstrEncParams->s16BitPool = (s16Bitpool > 128) ? 128 : s16Bitpool;
|
||||
pstrEncParams->s16NumOfChannels = 2;
|
||||
}
|
||||
|
||||
/* Bit pool calculation */
|
||||
if (pstrEncParams->s16SamplingFreq == SBC_sf16000) {
|
||||
s16SamplingFreq = 16000;
|
||||
} else if (pstrEncParams->s16SamplingFreq == SBC_sf32000) {
|
||||
s16SamplingFreq = 32000;
|
||||
} else if (pstrEncParams->s16SamplingFreq == SBC_sf44100) {
|
||||
s16SamplingFreq = 44100;
|
||||
} else {
|
||||
s16SamplingFreq = 48000;
|
||||
}
|
||||
|
||||
if ( (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO)
|
||||
|| (pstrEncParams->s16ChannelMode == SBC_STEREO) ) {
|
||||
s16Bitpool = (SINT16)( (pstrEncParams->u16BitRate *
|
||||
pstrEncParams->s16NumOfSubBands * 1000 / s16SamplingFreq)
|
||||
- ( (32 + (4 * pstrEncParams->s16NumOfSubBands *
|
||||
pstrEncParams->s16NumOfChannels)
|
||||
+ ( (pstrEncParams->s16ChannelMode - 2) *
|
||||
pstrEncParams->s16NumOfSubBands ) )
|
||||
/ pstrEncParams->s16NumOfBlocks) );
|
||||
|
||||
s16FrameLen = 4 + (4 * pstrEncParams->s16NumOfSubBands *
|
||||
pstrEncParams->s16NumOfChannels) / 8
|
||||
+ ( ((pstrEncParams->s16ChannelMode - 2) *
|
||||
pstrEncParams->s16NumOfSubBands)
|
||||
+ (pstrEncParams->s16NumOfBlocks * s16Bitpool) ) / 8;
|
||||
|
||||
s16BitRate = (8 * s16FrameLen * s16SamplingFreq)
|
||||
/ (pstrEncParams->s16NumOfSubBands *
|
||||
pstrEncParams->s16NumOfBlocks * 1000);
|
||||
|
||||
if (s16BitRate > pstrEncParams->u16BitRate) {
|
||||
s16Bitpool--;
|
||||
}
|
||||
|
||||
if (pstrEncParams->s16NumOfSubBands == 8) {
|
||||
pstrEncParams->s16BitPool = (s16Bitpool > 255) ? 255 : s16Bitpool;
|
||||
} else {
|
||||
pstrEncParams->s16BitPool = (s16Bitpool > 128) ? 128 : s16Bitpool;
|
||||
}
|
||||
} else {
|
||||
s16Bitpool = (SINT16)( ((pstrEncParams->s16NumOfSubBands *
|
||||
pstrEncParams->u16BitRate * 1000)
|
||||
/ (s16SamplingFreq * pstrEncParams->s16NumOfChannels))
|
||||
- ( ( (32 / pstrEncParams->s16NumOfChannels) +
|
||||
(4 * pstrEncParams->s16NumOfSubBands) )
|
||||
/ pstrEncParams->s16NumOfBlocks ) );
|
||||
|
||||
pstrEncParams->s16BitPool = (s16Bitpool >
|
||||
(16 * pstrEncParams->s16NumOfSubBands))
|
||||
? (16 * pstrEncParams->s16NumOfSubBands) : s16Bitpool;
|
||||
}
|
||||
|
||||
if (pstrEncParams->s16BitPool < 0) {
|
||||
pstrEncParams->s16BitPool = 0;
|
||||
}
|
||||
/* sampling freq */
|
||||
HeaderParams = ((pstrEncParams->s16SamplingFreq & 3) << 6);
|
||||
|
||||
/* number of blocks*/
|
||||
HeaderParams |= (((pstrEncParams->s16NumOfBlocks - 4) & 12) << 2);
|
||||
|
||||
/* channel mode: mono, dual...*/
|
||||
HeaderParams |= ((pstrEncParams->s16ChannelMode & 3) << 2);
|
||||
|
||||
/* Loudness or SNR */
|
||||
HeaderParams |= ((pstrEncParams->s16AllocationMethod & 1) << 1);
|
||||
HeaderParams |= ((pstrEncParams->s16NumOfSubBands >> 3) & 1); /*4 or 8*/
|
||||
|
||||
pstrEncParams->FrameHeader = HeaderParams;
|
||||
} else {
|
||||
s16Bitpool = (SINT16)( ((pstrEncParams->s16NumOfSubBands *
|
||||
pstrEncParams->u16BitRate * 1000)
|
||||
/ (s16SamplingFreq * pstrEncParams->s16NumOfChannels))
|
||||
- ( ( (32 / pstrEncParams->s16NumOfChannels) +
|
||||
(4 * pstrEncParams->s16NumOfSubBands) )
|
||||
/ pstrEncParams->s16NumOfBlocks ) );
|
||||
// mSBC
|
||||
|
||||
pstrEncParams->s16BitPool = (s16Bitpool >
|
||||
(16 * pstrEncParams->s16NumOfSubBands))
|
||||
? (16 * pstrEncParams->s16NumOfSubBands) : s16Bitpool;
|
||||
// Use mSBC encoding parameters to reset the control field
|
||||
/* Required number of channels: 1 */
|
||||
pstrEncParams->s16ChannelMode = SBC_MONO;
|
||||
pstrEncParams->s16NumOfChannels = 1;
|
||||
|
||||
/* Required Sampling frequency : 16KHz */
|
||||
pstrEncParams->s16SamplingFreq = SBC_sf16000;
|
||||
|
||||
/* Bit pool value: 26 */
|
||||
pstrEncParams->s16BitPool = 26;
|
||||
|
||||
/* number of subbands: 8 */
|
||||
pstrEncParams->s16NumOfSubBands = 8;
|
||||
|
||||
/* number of blocks: 15 */
|
||||
pstrEncParams->s16NumOfBlocks = 15;
|
||||
|
||||
/* allocation method: loudness */
|
||||
pstrEncParams->s16AllocationMethod = SBC_LOUDNESS;
|
||||
|
||||
/* set the header paramers, unused for mSBC */
|
||||
pstrEncParams->FrameHeader = 0;
|
||||
}
|
||||
|
||||
if (pstrEncParams->s16BitPool < 0) {
|
||||
pstrEncParams->s16BitPool = 0;
|
||||
}
|
||||
/* sampling freq */
|
||||
HeaderParams = ((pstrEncParams->s16SamplingFreq & 3) << 6);
|
||||
|
||||
/* number of blocks*/
|
||||
HeaderParams |= (((pstrEncParams->s16NumOfBlocks - 4) & 12) << 2);
|
||||
|
||||
/* channel mode: mono, dual...*/
|
||||
HeaderParams |= ((pstrEncParams->s16ChannelMode & 3) << 2);
|
||||
|
||||
/* Loudness or SNR */
|
||||
HeaderParams |= ((pstrEncParams->s16AllocationMethod & 1) << 1);
|
||||
HeaderParams |= ((pstrEncParams->s16NumOfSubBands >> 3) & 1); /*4 or 8*/
|
||||
pstrEncParams->FrameHeader = HeaderParams;
|
||||
|
||||
if (pstrEncParams->s16NumOfSubBands == 4) {
|
||||
if (pstrEncParams->s16NumOfChannels == 1) {
|
||||
EncMaxShiftCounter = ((ENC_VX_BUFFER_SIZE - 4 * 10) >> 2) << 2;
|
||||
@ -395,9 +328,6 @@ void SBC_Encoder_Init(SBC_ENC_PARAMS *pstrEncParams)
|
||||
pstrEncParams->u16BitRate, pstrEncParams->s16BitPool);
|
||||
|
||||
SbcAnalysisInit();
|
||||
|
||||
memset(&sbc_prtc_cb, 0, sizeof(tSBC_PRTC_CB));
|
||||
sbc_prtc_cb.base = 6 + pstrEncParams->s16NumOfChannels * pstrEncParams->s16NumOfSubBands / 2;
|
||||
}
|
||||
|
||||
#endif /* #if (defined(SBC_ENC_INCLUDED) && SBC_ENC_INCLUDED == TRUE) */
|
||||
|
@ -84,10 +84,17 @@ void EncPacking(SBC_ENC_PARAMS *pstrEncParams)
|
||||
#endif
|
||||
|
||||
pu8PacketPtr = pstrEncParams->pu8NextPacket; /*Initialize the ptr*/
|
||||
*pu8PacketPtr++ = (UINT8)0x9C; /*Sync word*/
|
||||
*pu8PacketPtr++ = (UINT8)(pstrEncParams->FrameHeader);
|
||||
if (pstrEncParams->sbc_mode != SBC_MODE_MSBC) {
|
||||
*pu8PacketPtr++ = (UINT8)SBC_SYNC_WORD_STD; /*Sync word*/
|
||||
*pu8PacketPtr++ = (UINT8)(pstrEncParams->FrameHeader);
|
||||
|
||||
*pu8PacketPtr = (UINT8)(pstrEncParams->s16BitPool & 0x00FF);
|
||||
*pu8PacketPtr = (UINT8)(pstrEncParams->s16BitPool & 0x00FF);
|
||||
} else {
|
||||
*pu8PacketPtr++ = (UINT8)SBC_SYNC_WORD_MSBC; /*Sync word*/
|
||||
// two reserved bytes
|
||||
*pu8PacketPtr++ = 0;
|
||||
*pu8PacketPtr = 0;
|
||||
}
|
||||
pu8PacketPtr += 2; /*skip for CRC*/
|
||||
|
||||
/*here it indicate if it is byte boundary or nibble boundary*/
|
||||
|
91
components/bt/bluedroid/external/sbc/plc/include/sbc_plc.h
vendored
Normal file
91
components/bt/bluedroid/external/sbc/plc/include/sbc_plc.h
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _SBC_PLC_H
|
||||
#define _SBC_PLC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Paramter for PLC (16 kHZ)*/
|
||||
#define SBC_FS 120 /* SBC Frame Size */
|
||||
#define SBC_N 256 /* 16ms - Window Length for pattern matching */
|
||||
#define SBC_M 64 /* 4ms - Template for matching */
|
||||
#define SBC_LHIST (SBC_N + SBC_FS - 1) /* Length of history buffer required */
|
||||
#define SBC_RT 36 /* SBC Reconvergence Time (samples) */
|
||||
#define SBC_OLAL 16 /* OverLap-Add Length (samples) */
|
||||
|
||||
/* PLC State Information */
|
||||
typedef struct sbc_plc_state {
|
||||
int16_t hist[SBC_LHIST + SBC_FS + SBC_RT + SBC_OLAL];
|
||||
int16_t bestlag;
|
||||
int nbf;
|
||||
} sbc_plc_state_t;
|
||||
|
||||
/* Prototypes */
|
||||
/**
|
||||
* Perform PLC initialization of memory vectors.
|
||||
*
|
||||
* @param plc_state pointer to PLC state memory
|
||||
*/
|
||||
void sbc_plc_init(sbc_plc_state_t *plc_state);
|
||||
|
||||
/**
|
||||
* Perform PLC deinitialization of memory vectors.
|
||||
*
|
||||
* @param plc_state pointer to PLC state memory
|
||||
*/
|
||||
void sbc_plc_deinit(sbc_plc_state_t *plc_state);
|
||||
|
||||
/**
|
||||
* Perform bad frame processing.
|
||||
*
|
||||
* @param plc_state pointer to PLC state memory
|
||||
* @param ZIRbuf pointer to the ZIR response of the SBC decoder
|
||||
* @param out pointer to the output samples
|
||||
*/
|
||||
void sbc_plc_bad_frame(sbc_plc_state_t *plc_state, int16_t *ZIRbuf, int16_t *out);
|
||||
|
||||
/**
|
||||
* Perform good frame processing. Most of the time, this function
|
||||
* just updates history buffers and passes the input to the output,
|
||||
* but in the first good frame after frame loss, it must conceal the
|
||||
* received signal as it reconverges with the true output.
|
||||
*
|
||||
* @param plc_state pointer to PLC state memory
|
||||
* @param in pointer to the input vector
|
||||
* @param out pointer to the output samples
|
||||
*/
|
||||
void sbc_plc_good_frame(sbc_plc_state_t *plc_state, int16_t *in, int16_t *out);
|
||||
|
||||
/**
|
||||
* Get a zero signal eSCO frame
|
||||
* @return pointer to data buffer
|
||||
*/
|
||||
uint8_t * sbc_plc_zero_signal_frame(void);
|
||||
|
||||
/**
|
||||
* Get a zero signal eSCO pcm frame
|
||||
* @return pointer to data buffer
|
||||
*/
|
||||
int16_t * sbc_plc_zero_signal_frame_pcm(void);
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /// _SBC_PLC_H
|
307
components/bt/bluedroid/external/sbc/plc/sbc_plc.c
vendored
Normal file
307
components/bt/bluedroid/external/sbc/plc/sbc_plc.c
vendored
Normal file
@ -0,0 +1,307 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "common/bt_target.h"
|
||||
#include "sbc_plc.h"
|
||||
|
||||
#if (PLC_INCLUDED == TRUE)
|
||||
/* msbc */
|
||||
static const uint8_t indices0[] = { 0xad, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x00, 0x77, 0x6d,
|
||||
0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6d, 0xdd, 0xb6, 0xdb, 0x77, 0x6d,
|
||||
0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6d, 0xdd, 0xb6, 0xdb, 0x77, 0x6d,
|
||||
0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6d, 0xdd, 0xb6, 0xdb, 0x77, 0x6d,
|
||||
0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6c};
|
||||
|
||||
|
||||
/* 8 kHZ */
|
||||
static const int16_t indices0_pcm[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
/* Raised COSine table for OLA */
|
||||
/* 16 kHZ */
|
||||
static float rcos[SBC_OLAL] = {
|
||||
0.99148655f,0.96623611f,0.92510857f,0.86950446f,
|
||||
0.80131732f,0.72286918f,0.63683150f,0.54613418f,
|
||||
0.45386582f,0.36316850f,0.27713082f,0.19868268f,
|
||||
0.13049554f,0.07489143f,0.03376389f,0.00851345f};
|
||||
|
||||
// /* 8 kHZ */
|
||||
// static float rcos[SBC_OLAL] = {
|
||||
// 0.96984631f,0.88302222f, 0.75f,0.58682409f,
|
||||
// 0.41317591f, 0.25f,0.11697778f,0.09015369f};
|
||||
|
||||
|
||||
static float SqrtByCarmack(const float x){
|
||||
union {
|
||||
int i;
|
||||
float y;
|
||||
} float_int;
|
||||
|
||||
float x2;
|
||||
const float threehalfs = 1.5f;
|
||||
|
||||
x2 = x * 0.5f;
|
||||
float_int.y = x;
|
||||
|
||||
float_int.i = 0x5f375a86 - (float_int.i >> 1);
|
||||
float_int.y = float_int.y * (threehalfs - (x2 * float_int.y * float_int.y));
|
||||
// float_int.y = float_int.y * (threehalfs - (x2 * float_int.y * float_int.y));
|
||||
// float_int.y = float_int.y * (threehalfs - (x2 * float_int.y * float_int.y));
|
||||
|
||||
return (x * float_int.y);
|
||||
}
|
||||
|
||||
static float absolute(float x){
|
||||
if (x < 0) {
|
||||
x = -x;
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the cross correlation according to Eq. (4) of Goodman
|
||||
* paper, except that the true correlation is used. His formula
|
||||
* seems to be incorrect.
|
||||
*
|
||||
* @param x pointer to x input vector
|
||||
* @param y pointer to y input vector
|
||||
*
|
||||
* @return value containing the cross-correlation of x and y
|
||||
*/
|
||||
static float CrossCorrelation(int16_t *x, int16_t *y){
|
||||
int m;
|
||||
float num = 0;
|
||||
float den = 0;
|
||||
float x2 = 0;
|
||||
float y2 = 0;
|
||||
|
||||
for (m = 0; m < SBC_M; m++) {
|
||||
num += ((float)x[m]) * y[m];
|
||||
x2 += ((float)x[m]) * x[m];
|
||||
y2 += ((float)y[m]) * y[m];
|
||||
}
|
||||
den = (float)SqrtByCarmack(x2 * y2);
|
||||
return num / den;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform pattern matching to find the match of template with the
|
||||
* history buffer according to Section B of Goodman paper.
|
||||
*
|
||||
* @param y pointer to history buffer
|
||||
*
|
||||
* @return the lag corresponding to the best match. The lag is
|
||||
* with respect to the beginning of the history buffer.
|
||||
*
|
||||
*/
|
||||
static int PatternMatch(int16_t *y){
|
||||
int n;
|
||||
float maxCn = -999999.0; // large negative number
|
||||
float Cn;
|
||||
int bestmatch = 0;
|
||||
|
||||
for (n = 0; n < SBC_N; n++){
|
||||
Cn = CrossCorrelation(&y[SBC_LHIST-SBC_M], &y[n]);
|
||||
if (Cn > maxCn){
|
||||
bestmatch = n;
|
||||
maxCn = Cn;
|
||||
}
|
||||
}
|
||||
return bestmatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform amplitude matching using mean-absolute-value according
|
||||
* to Goodman paper.
|
||||
*
|
||||
* @param y pointer to history buffer
|
||||
* @param bestmatch value of the lag to the best match
|
||||
*
|
||||
* @return scale factor
|
||||
*/
|
||||
static float AmplitudeMatch(int16_t *y, int16_t bestmatch) {
|
||||
int i;
|
||||
float sumx = 0;
|
||||
float sumy = 0.000001f;
|
||||
float sf;
|
||||
|
||||
for (i = 0; i < SBC_FS; i++){
|
||||
sumx += absolute(y[SBC_LHIST - SBC_FS + i]);
|
||||
sumy += absolute(y[bestmatch + i]);
|
||||
}
|
||||
sf = sumx / sumy;
|
||||
// This is not in the paper, but limit the scaling factor to something reasonable to avoid creating artifacts
|
||||
if (sf < 0.75f) {
|
||||
sf = 0.75f;
|
||||
}
|
||||
if (sf > 1.2f) {
|
||||
sf = 1.2f;
|
||||
}
|
||||
return sf;
|
||||
}
|
||||
|
||||
static int16_t crop_sample(float val){
|
||||
float croped_val = val;
|
||||
if (croped_val > 32767.0) croped_val= 32767.0;
|
||||
if (croped_val < -32768.0) croped_val=-32768.0;
|
||||
return (int16_t) croped_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a zero signal eSCO frame
|
||||
* @return pointer to data buffer
|
||||
*/
|
||||
uint8_t * sbc_plc_zero_signal_frame(void){
|
||||
return (uint8_t *)&indices0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a zero signal eSCO pcm frame
|
||||
* @return pointer to data buffer
|
||||
*/
|
||||
int16_t * sbc_plc_zero_signal_frame_pcm(void){
|
||||
return (int16_t *)&indices0_pcm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform PLC initialization of memory vectors.
|
||||
*
|
||||
* @param plc_state pointer to PLC state memory
|
||||
*/
|
||||
void sbc_plc_init(sbc_plc_state_t *plc_state){
|
||||
plc_state->nbf=0;
|
||||
plc_state->bestlag=0;
|
||||
memset(plc_state->hist, 0, sizeof(plc_state->hist));
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform PLC deinitialization of memory vectors.
|
||||
*
|
||||
* @param plc_state pointer to PLC state memory
|
||||
*/
|
||||
void sbc_plc_deinit(sbc_plc_state_t *plc_state){
|
||||
plc_state->nbf=0;
|
||||
plc_state->bestlag=0;
|
||||
memset(plc_state->hist, 0, sizeof(plc_state->hist));
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform bad frame processing.
|
||||
*
|
||||
* @param plc_state pointer to PLC state memory
|
||||
* @param ZIRbuf pointer to the ZIR response of the SBC decoder
|
||||
* @param out pointer to the output samples
|
||||
*/
|
||||
void sbc_plc_bad_frame(sbc_plc_state_t *plc_state, int16_t *ZIRbuf, int16_t *out){
|
||||
int i = 0;
|
||||
float val;
|
||||
float sf = 1;
|
||||
|
||||
plc_state->nbf++;
|
||||
|
||||
if (plc_state->nbf == 1){
|
||||
// Perform pattern matching to find where to replicate
|
||||
plc_state->bestlag = PatternMatch(plc_state->hist);
|
||||
// the replication begins after the template match
|
||||
plc_state->bestlag += SBC_M;
|
||||
|
||||
// Compute Scale Factor to Match Amplitude of Substitution Packet to that of Preceding Packet
|
||||
sf = AmplitudeMatch(plc_state->hist, plc_state->bestlag);
|
||||
|
||||
for (i = 0; i < SBC_OLAL; i++){
|
||||
val = ZIRbuf[i] * rcos[i]
|
||||
+ sf * plc_state->hist[plc_state->bestlag + i] * rcos[SBC_OLAL - i - 1];
|
||||
plc_state->hist[SBC_LHIST + i] = crop_sample(val);
|
||||
}
|
||||
|
||||
for (; i < SBC_FS; i++){
|
||||
val = sf*plc_state->hist[plc_state->bestlag + i];
|
||||
plc_state->hist[SBC_LHIST + i] = crop_sample(val);
|
||||
}
|
||||
|
||||
for (; i < SBC_FS + SBC_OLAL; i++){
|
||||
val = sf * plc_state->hist[plc_state->bestlag + i] * rcos[i-SBC_FS]
|
||||
+ plc_state->hist[plc_state->bestlag + i] * rcos[SBC_OLAL - 1 - i + SBC_FS];
|
||||
plc_state->hist[SBC_LHIST + i] = crop_sample(val);
|
||||
}
|
||||
|
||||
for (; i < SBC_FS + SBC_RT + SBC_OLAL; i++){
|
||||
plc_state->hist[SBC_LHIST + i] = plc_state->hist[plc_state->bestlag + i];
|
||||
}
|
||||
} else {
|
||||
for ( ;i < SBC_FS + SBC_RT + SBC_OLAL; i++){
|
||||
plc_state->hist[SBC_LHIST + i] = plc_state->hist[plc_state->bestlag + i];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < SBC_FS; i++){
|
||||
out[i] = plc_state->hist[SBC_LHIST + i];
|
||||
}
|
||||
|
||||
// shift the history buffer
|
||||
for (i = 0; i < SBC_LHIST + SBC_RT + SBC_OLAL; i++){
|
||||
plc_state->hist[i] = plc_state->hist[i + SBC_FS];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform good frame processing. Most of the time, this function
|
||||
* just updates history buffers and passes the input to the output,
|
||||
* but in the first good frame after frame loss, it must conceal the
|
||||
* received signal as it reconverges with the true output.
|
||||
*
|
||||
* @param plc_state pointer to PLC state memory
|
||||
* @param in pointer to the input vector
|
||||
* @param out pointer to the output samples
|
||||
*/
|
||||
void sbc_plc_good_frame(sbc_plc_state_t *plc_state, int16_t *in, int16_t *out){
|
||||
int i = 0;
|
||||
|
||||
if (plc_state->nbf > 0){
|
||||
for (i = 0; i < SBC_RT; i++){
|
||||
out[i] = plc_state->hist[SBC_LHIST + i];
|
||||
}
|
||||
|
||||
for (i = SBC_RT; i < SBC_RT + SBC_OLAL; i++){
|
||||
out[i] = (int16_t)(plc_state->hist[SBC_LHIST + i] * rcos[i - SBC_RT] + in[i] * rcos[SBC_OLAL - 1 - i + SBC_RT]);
|
||||
}
|
||||
}
|
||||
|
||||
for (; i < SBC_FS; i++){
|
||||
out[i] = in[i];
|
||||
}
|
||||
// Copy the output to the history buffer
|
||||
for (i = 0; i < SBC_FS; i++){
|
||||
plc_state->hist[SBC_LHIST + i] = out[i];
|
||||
}
|
||||
// shift the history buffer
|
||||
for (i = 0; i < SBC_LHIST; i++){
|
||||
plc_state->hist[i] = plc_state->hist[i + SBC_FS];
|
||||
}
|
||||
|
||||
plc_state->nbf = 0;
|
||||
}
|
||||
|
||||
#endif ///(PLC_INCLUDED == TRUE)
|
@ -55,6 +55,7 @@ static const uint16_t outbound_event_types[] = {
|
||||
typedef struct {
|
||||
size_t buffer_size;
|
||||
fixed_queue_t *rx_q;
|
||||
uint16_t adv_free_num;
|
||||
} hci_hal_env_t;
|
||||
|
||||
|
||||
@ -81,6 +82,7 @@ static void hci_hal_env_init(
|
||||
assert(max_buffer_count > 0);
|
||||
|
||||
hci_hal_env.buffer_size = buffer_size;
|
||||
hci_hal_env.adv_free_num = 0;
|
||||
|
||||
hci_hal_env.rx_q = fixed_queue_new(max_buffer_count);
|
||||
if (hci_hal_env.rx_q) {
|
||||
@ -102,8 +104,11 @@ static bool hal_open(const hci_hal_callbacks_t *upper_callbacks)
|
||||
{
|
||||
assert(upper_callbacks != NULL);
|
||||
callbacks = upper_callbacks;
|
||||
|
||||
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
|
||||
hci_hal_env_init(HCI_HAL_SERIAL_BUFFER_SIZE, BLE_ADV_REPORT_FLOW_CONTROL_NUM + L2CAP_HOST_FC_ACL_BUFS + QUEUE_SIZE_MAX); // adv flow control num + ACL flow control num + hci cmd numeber
|
||||
#else
|
||||
hci_hal_env_init(HCI_HAL_SERIAL_BUFFER_SIZE, QUEUE_SIZE_MAX);
|
||||
#endif
|
||||
|
||||
xHciH4Queue = xQueueCreate(HCI_H4_QUEUE_LEN, sizeof(BtTaskEvt_t));
|
||||
xTaskCreatePinnedToCore(hci_hal_h4_rx_handler, HCI_H4_TASK_NAME, HCI_H4_TASK_STACK_SIZE, NULL, HCI_H4_TASK_PRIO, &xHciH4TaskHandle, HCI_H4_TASK_PINNED_TO_CORE);
|
||||
@ -184,10 +189,10 @@ task_post_status_t hci_hal_h4_task_post(task_post_t timeout)
|
||||
evt.par = 0;
|
||||
|
||||
if (xQueueSend(xHciH4Queue, &evt, timeout) != pdTRUE) {
|
||||
return TASK_POST_SUCCESS;
|
||||
return TASK_POST_FAIL;
|
||||
}
|
||||
|
||||
return TASK_POST_FAIL;
|
||||
return TASK_POST_SUCCESS;
|
||||
}
|
||||
|
||||
#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
|
||||
@ -223,12 +228,37 @@ static void hci_packet_complete(BT_HDR *packet){
|
||||
bool host_recv_adv_packet(BT_HDR *packet)
|
||||
{
|
||||
assert(packet);
|
||||
if(packet->data[0] == DATA_TYPE_EVENT && packet->data[1] == HCI_BLE_EVENT && packet->data[3] == HCI_BLE_ADV_PKT_RPT_EVT) {
|
||||
return true;
|
||||
if(packet->data[0] == DATA_TYPE_EVENT && packet->data[1] == HCI_BLE_EVENT) {
|
||||
if(packet->data[3] == HCI_BLE_ADV_PKT_RPT_EVT
|
||||
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
|
||||
|| packet->data[3] == HCI_BLE_ADV_DISCARD_REPORT_EVT
|
||||
#endif
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
|
||||
static void hci_update_adv_report_flow_control(BT_HDR *packet)
|
||||
{
|
||||
// this is adv packet
|
||||
if(host_recv_adv_packet(packet)) {
|
||||
// update adv free number
|
||||
hci_hal_env.adv_free_num ++;
|
||||
if (esp_vhci_host_check_send_available()){
|
||||
// send hci cmd
|
||||
btsnd_hcic_ble_update_adv_report_flow_control(hci_hal_env.adv_free_num);
|
||||
hci_hal_env.adv_free_num = 0;
|
||||
} else {
|
||||
//do nothing
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
|
||||
{
|
||||
uint8_t type, hdr_size;
|
||||
@ -247,8 +277,10 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
|
||||
packet->offset++;
|
||||
packet->len--;
|
||||
if (type == HCI_BLE_EVENT) {
|
||||
#if (!CONFIG_BT_STACK_NO_LOG)
|
||||
uint8_t len = 0;
|
||||
STREAM_TO_UINT8(len, stream);
|
||||
#endif
|
||||
HCI_TRACE_ERROR("Workround stream corrupted during LE SCAN: pkt_len=%d ble_event_len=%d\n",
|
||||
packet->len, len);
|
||||
osi_free(packet);
|
||||
@ -282,6 +314,11 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
|
||||
osi_free(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
|
||||
hci_update_adv_report_flow_control(packet);
|
||||
#endif
|
||||
|
||||
#if SCAN_QUEUE_CONGEST_CHECK
|
||||
if(BTU_check_queue_is_congest() && host_recv_adv_packet(packet)) {
|
||||
HCI_TRACE_ERROR("BtuQueue is congested");
|
||||
@ -289,7 +326,6 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
packet->event = outbound_event_types[PACKET_TYPE_TO_INDEX(type)];
|
||||
callbacks->packet_ready(packet);
|
||||
}
|
||||
@ -307,7 +343,11 @@ static void host_send_pkt_available_cb(void)
|
||||
{
|
||||
//Controller rx cache buffer is ready for receiving new host packet
|
||||
//Just Call Host main thread task to process pending packets.
|
||||
#ifdef TASK_MONITOR_MODE
|
||||
hci_host_task_post(TASK_POST_BLOCKING_WITH_TO);
|
||||
#else
|
||||
hci_host_task_post(TASK_POST_BLOCKING);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
|
||||
@ -325,6 +365,7 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
|
||||
//pkt = (BT_HDR *)hci_hal_env.allocator->alloc(pkt_size);
|
||||
if (!pkt) {
|
||||
HCI_TRACE_ERROR("%s couldn't aquire memory for inbound data buffer.\n", __func__);
|
||||
assert(pkt!=NULL);
|
||||
return -1;
|
||||
}
|
||||
pkt->offset = 0;
|
||||
|
@ -33,6 +33,8 @@
|
||||
#include "osi/mutex.h"
|
||||
#include "osi/fixed_queue.h"
|
||||
|
||||
void bt_abort_with_coredump_log(uint16_t error);
|
||||
|
||||
typedef struct {
|
||||
uint16_t opcode;
|
||||
future_t *complete_future;
|
||||
@ -64,7 +66,7 @@ typedef struct {
|
||||
} hci_host_env_t;
|
||||
|
||||
// Using a define here, because it can be stringified for the property lookup
|
||||
static const uint32_t COMMAND_PENDING_TIMEOUT = 8000;
|
||||
static const uint32_t COMMAND_PENDING_TIMEOUT = 35000;
|
||||
|
||||
// Our interface
|
||||
static bool interface_created;
|
||||
@ -141,6 +143,10 @@ task_post_status_t hci_host_task_post(task_post_t timeout)
|
||||
evt.par = 0;
|
||||
|
||||
if (xQueueSend(xHciHostQueue, &evt, timeout) != pdTRUE) {
|
||||
#ifdef TASK_MONITOR_MODE
|
||||
ets_printf("!! HCI send fail.Timeout Abort !!");
|
||||
bt_abort_with_coredump_log(0);
|
||||
#endif
|
||||
HCI_TRACE_ERROR("xHciHostQueue failed\n");
|
||||
return TASK_POST_FAIL;
|
||||
}
|
||||
@ -271,7 +277,12 @@ static void transmit_command(
|
||||
BTTRC_DUMP_BUFFER(NULL, command->data + command->offset, command->len);
|
||||
|
||||
fixed_queue_enqueue(hci_host_env.command_queue, wait_entry);
|
||||
|
||||
#ifdef TASK_MONITOR_MODE
|
||||
hci_host_task_post(TASK_POST_BLOCKING_WITH_TO);
|
||||
#else
|
||||
hci_host_task_post(TASK_POST_BLOCKING);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@ -292,7 +303,11 @@ static future_t *transmit_command_futured(BT_HDR *command)
|
||||
command->event = MSG_STACK_TO_HC_HCI_CMD;
|
||||
|
||||
fixed_queue_enqueue(hci_host_env.command_queue, wait_entry);
|
||||
#ifdef TASK_MONITOR_MODE
|
||||
hci_host_task_post(TASK_POST_BLOCKING_WITH_TO);
|
||||
#else
|
||||
hci_host_task_post(TASK_POST_BLOCKING);
|
||||
#endif
|
||||
return future;
|
||||
}
|
||||
|
||||
@ -305,7 +320,11 @@ static void transmit_downward(uint16_t type, void *data)
|
||||
fixed_queue_enqueue(hci_host_env.packet_queue, data);
|
||||
}
|
||||
|
||||
#ifdef TASK_MONITOR_MODE
|
||||
hci_host_task_post(TASK_POST_BLOCKING_WITH_TO);
|
||||
#else
|
||||
hci_host_task_post(TASK_POST_BLOCKING);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -317,7 +336,11 @@ static void event_command_ready(fixed_queue_t *queue)
|
||||
|
||||
wait_entry = fixed_queue_dequeue(queue);
|
||||
|
||||
if(wait_entry->opcode == HCI_HOST_NUM_PACKETS_DONE){
|
||||
if(wait_entry->opcode == HCI_HOST_NUM_PACKETS_DONE
|
||||
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
|
||||
|| wait_entry->opcode == HCI_VENDOR_BLE_ADV_REPORT_FLOW_CONTROL
|
||||
#endif
|
||||
){
|
||||
packet_fragmenter->fragment_and_dispatch(wait_entry->command);
|
||||
osi_free(wait_entry->command);
|
||||
osi_free(wait_entry);
|
||||
@ -409,6 +432,7 @@ static void command_timed_out(void *context)
|
||||
// If it's caused by a software bug, fix it. If it's a hardware bug, fix it.
|
||||
{
|
||||
HCI_TRACE_ERROR("%s hci layer timeout waiting for response to a command. opcode: 0x%x", __func__, wait_entry->opcode);
|
||||
bt_abort_with_coredump_log(wait_entry->opcode);
|
||||
}
|
||||
}
|
||||
|
||||
@ -475,7 +499,11 @@ intercepted:
|
||||
/*Tell HCI Host Task to continue TX Pending commands*/
|
||||
if (hci_host_env.command_credits &&
|
||||
!fixed_queue_is_empty(hci_host_env.command_queue)) {
|
||||
hci_host_task_post(TASK_POST_BLOCKING);
|
||||
#ifdef TASK_MONITOR_MODE
|
||||
hci_host_task_post(TASK_POST_BLOCKING_WITH_TO);
|
||||
#else
|
||||
hci_host_task_post(TASK_POST_BLOCKING);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (wait_entry) {
|
||||
@ -503,7 +531,11 @@ static void dispatch_reassembled(BT_HDR *packet)
|
||||
{
|
||||
// Events should already have been dispatched before this point
|
||||
//Tell Up-layer received packet.
|
||||
#ifdef TASK_MONITOR_MODE
|
||||
if (btu_task_post(SIG_BTU_HCI_MSG, packet, TASK_POST_BLOCKING_WITH_TO) != TASK_POST_SUCCESS) {
|
||||
#else
|
||||
if (btu_task_post(SIG_BTU_HCI_MSG, packet, TASK_POST_BLOCKING) != TASK_POST_SUCCESS) {
|
||||
#endif
|
||||
osi_free(packet);
|
||||
}
|
||||
}
|
||||
|
@ -53,6 +53,18 @@ static BT_HDR *make_set_c2h_flow_control(uint8_t enable)
|
||||
return packet;
|
||||
}
|
||||
|
||||
static BT_HDR *make_set_adv_report_flow_control(uint8_t enable, uint16_t num, uint16_t lost_threshold)
|
||||
{
|
||||
uint8_t *stream;
|
||||
const uint8_t parameter_size = 1 + 2 + 2;
|
||||
BT_HDR *packet = make_command(HCI_VENDOR_BLE_SET_ADV_FLOW_CONTROL, parameter_size, &stream);
|
||||
|
||||
UINT8_TO_STREAM(stream, enable);
|
||||
UINT16_TO_STREAM(stream, num);
|
||||
UINT16_TO_STREAM(stream, lost_threshold);
|
||||
return packet;
|
||||
}
|
||||
|
||||
static BT_HDR *make_host_buffer_size(uint16_t acl_size, uint8_t sco_size, uint16_t acl_count, uint16_t sco_count)
|
||||
{
|
||||
uint8_t *stream;
|
||||
@ -239,6 +251,7 @@ static const hci_packet_factory_t interface = {
|
||||
make_reset,
|
||||
make_read_buffer_size,
|
||||
make_set_c2h_flow_control,
|
||||
make_set_adv_report_flow_control,
|
||||
make_host_buffer_size,
|
||||
make_read_local_version_info,
|
||||
make_read_bd_addr,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user